Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 0 additions & 127 deletions BLOCKS.md

This file was deleted.

61 changes: 61 additions & 0 deletions blocks/BLOCKS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Block Editor Compatibility

This file describes steps to start developing Blocks for Edit Flow.
Currently, the following Edit Flow modules are compatible with Gutenberg Block Editor:

* Custom Statuses

### Setup

*Note:* This document assumes you have a working knowledge of modern JavaScript and its tooling. Including npm, Webpack, and React.

Prerequisites: `npm`.

From the plugin's folder run:

```
npm i
```

This should leave you with everything you need for development, including a local copy of Webpack and webpack-cli.

## Anatomy of an Edit Flow block.

There are two parts for adding Block Editor compatibility to modules.

#### PHP

On the PHP side, we mostly just need to make sure the block assets are enqueued when they are needed. There is a [Block_Editor_Compatible](common/php/trait-block-editor-compatible.php) trait that gives access to helpful methods related to the block editor when used within modules.

#### JavaScript

##### Development

To start the Webpack in watch mode:

```npm run dev```

##### Build for production

To generate optimized/minified production-ready files:

```npm run build```

##### File Structure

```
blocks/
# Source files:
src/
module-slug/
block.js # Gutenberg Block code for the module
editor.scss # Editor styles
style.scss # Front-end styles
# Build
dist/
module-slug.build.js # Built block js
module-slug.editor.build.css # Built editor CSS
module-slug.style.build.css # Built front-end CSS
```

The files from `dist/` should be enqueued in the compat class for the module.
2 changes: 0 additions & 2 deletions blocks/dist/calendar.build.js

This file was deleted.

2 changes: 0 additions & 2 deletions blocks/dist/calendar.editor.build.css

This file was deleted.

2 changes: 0 additions & 2 deletions blocks/dist/calendar.style.build.css

This file was deleted.

2 changes: 0 additions & 2 deletions blocks/src/calendar/block.js

This file was deleted.

Empty file removed blocks/src/calendar/editor.scss
Empty file.
Empty file removed blocks/src/calendar/style.scss
Empty file.
21 changes: 1 addition & 20 deletions common/php/class-module.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@ class EF_Module {
'private',
);

/**
* Associative array of hook_name => callback_name
* This is used for Gutenberg-compat initialization
* [
* 'init' => 'init_callback_on_module_instance'
* ]
* @var array
*/
protected $compat_hooks = [];

function __construct() {}

/**
Expand Down Expand Up @@ -598,15 +588,6 @@ function upgrade_074_term_descriptions( $taxonomy ) {
wp_update_term( $term->term_id, $taxonomy, array( 'description' => $new_description ) );
}
}

/**
* Return compatibility hooks for the current instance
*
* @return array
*/
function get_compat_hooks() {
return isset( $this->compat_hooks ) && is_array( $this->compat_hooks ) ? $this->compat_hooks : [];
}

}

}
117 changes: 7 additions & 110 deletions common/php/trait-block-editor-compatible.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,129 +6,26 @@
// phpcs:disable WordPressVIPMinimum.Variables.VariableAnalysis.SelfOutsideClass

trait Block_Editor_Compatible {
/**
* Holds the reference to the Module's object
*
* @var EF_Module
*/
protected $ef_module;
/**
* Holds associative array of hooks and their respective callbacks
*
* @var array
*/
protected $hooks = [];
protected static $active_plugins;

/**
* This method handles init of Module Compat
*
* @param EF_Module $module_instance
* @param array $hooks associative array of hooks and their respective callbacks
*
*
* @return void
*/
function __construct( $module_instance, $hooks = [] ) {
$this->ef_module = $module_instance;
$this->hooks = $hooks;

if ( is_admin() ) {

add_action( 'init', [ $this, 'action_init_for_admin' ], 15 );
}
}

/**
* Unhook the module's hooks and use the module's Compat hooks instead.
*
* This is currently run on init action, but only when `is_admin` is true.
*
* @since 0.9
*
* @return void
*/
function action_init_for_admin() {
if ( ! $this->ef_module->is_enabled() ) {
return;
}

$this->check_active_plugins();

if ( $this->should_apply_compat() ) {
foreach ( $this->hooks as $hook => $callback ) {
if ( is_callable( [ $this, $callback ] ) ) {
remove_action( $hook, array( $this->ef_module, $callback ) );
add_action( $hook, array( $this, $callback ) );
}
}
}
}

function check_active_plugins() {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );

self::$active_plugins = [
'classic-editor' => is_plugin_active( 'classic-editor' ),
'gutenberg' => is_plugin_active( 'gutenberg' ),
];
}

/**
* Helper function to determine whether we're running WP 5.0.
*
* @return boolean
*/
public static function is_at_least_50() {
private function is_at_least_wp_50() {
return version_compare( get_bloginfo( 'version' ), '5.0', '>=' );
}

/**
* Helper to determine whether either Gutenberg plugin or Classic Editor plugin is loaded.
* Whether or not we are in the block editor.
*
* @param string $slug
* @return boolean
*/
public static function is_plugin_active( $slug = '' ) {
return isset( self::$active_plugins[ $slug ] ) && self::$active_plugins[ $slug ];
}

/**
* Detect whether we should load compatability for the module.
* This runs very early during request lifecycle and may not be precise. It's better to use `get_current_screen()->is_block_editor()` if it's available.
*
* However, Block Editor can be enabled/disabled on a granular basis via the filters for the core and the plugin versions.
*
* use_block_editor_for_post
* use_block_editor_for_post_type
* gutenberg_can_edit_post_type
* gutenberg_can_edit_post
*
*
* This needs to be handled in the compat hook callback.
*
* If any of $conditions evaluates to TRUE, we should apply compat hooks.
*
* @return boolean
*/
protected function should_apply_compat() {
$conditions = [
/**
* 5.0:
*
* Classic editor either disabled or enabled (either via an option or with GET argument).
* It's a hairy conditional :(
*/
// phpcs:ignore WordPress.VIP.SuperGlobalInputUsage.AccessDetected, WordPress.Security.NonceVerification.NoNonceVerification
self::is_at_least_50() && ! self::is_plugin_active( 'classic-editor' ),
self::is_at_least_50() && self::is_plugin_active( 'classic-editor' ) && ( get_option( 'classic-editor-replace' ) === 'block' && ! isset( $_GET[ 'classic-editor__forget' ] ) ),
self::is_at_least_50() && self::is_plugin_active( 'classic-editor' ) && ( get_option( 'classic-editor-replace' ) === 'classic' && isset( $_GET[ 'classic-editor__forget' ] ) ),
/**
* < 5.0 but Gutenberg plugin is active.
*/
! self::is_at_least_50() && self::is_plugin_active( 'gutenberg' ),
];
public function is_block_editor() {
if ( self::is_at_least_wp_50() && function_exists( 'get_current_screen' ) ) {
return get_current_screen()->is_block_editor();
}

return count( array_filter( $conditions, function( $c ) { return (bool) $c; } ) ) > 0;
return false;
}
}
8 changes: 0 additions & 8 deletions edit_flow.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,6 @@ private function load_modules() {
if ( file_exists( EDIT_FLOW_ROOT . "/modules/{$module_dir}/$module_dir.php" ) ) {
include_once( EDIT_FLOW_ROOT . "/modules/{$module_dir}/$module_dir.php" );

// Try to load Gutenberg compat files
if ( file_exists( EDIT_FLOW_ROOT . "/modules/{$module_dir}/compat/block-editor.php" ) ) {
include_once( EDIT_FLOW_ROOT . "/modules/{$module_dir}/compat/block-editor.php" );
}
// Prepare the class name because it should be standardized
$tmp = explode( '-', $module_dir );
$class_name = '';
Expand All @@ -150,10 +146,6 @@ private function load_modules() {
foreach( $class_names as $slug => $class_name ) {
if ( class_exists( $class_name ) ) {
$this->$slug = new $class_name();
$compat_class_name = "{$class_name}_Block_Editor_Compat";
if ( class_exists( $compat_class_name ) ) {
$this->$slug->compat = new $compat_class_name( $this->$slug, $this->$slug->get_compat_hooks() );
}
}
}

Expand Down
Loading