I wrote yesterday on Gutenberg, WordPress' soon-to-be editing experience, as it was highly mentioned at WordCampUS here in Nashville over the weekend. Yesterday, I focused specifically on the outer facade of Gutenberg – movable blocks, layouts, and modular approaches to content.
Today, we're going to look at the back-end. For a WordPress developer, this is where their experience may become a little less rosy. For a modern developer, a lot of this will look familiar.
Gutenberg's Content Structure
Gutenberg's content is structured into "blocks". A block is simply a syntaxed area of code that WordPress recognizes as something it should hook into with the editor.
On the outside, as we saw yesterday, a typical text block looks like your standard paragraph. But on the backend…
…we have syntax. Commented code that Gutenberg recognizes to store its information. Those paragraphs are pretty standard fare, but there could also be parameters…
…stored as an array.
This is the first of two pain points a lot of developers seem to have, as a structure like this is just not sustainable in the long run. Commented code is normally frowned upon in clean standards, and with WordPress using it as the primary source of templating for Gutenberg, it seems that (for the moment) the simple content looks bloaty on the inside. One of the biggest outside forces right now in the development cycle – other than adoption and testing – is for a better, cleaner, leaner way of storing data.
Adding a New Block
I've been fiddling with Gutenberg's block syntax all day, and I've finally come up with something of a boilerplate to use for plugins.
<?php
/**
* Plugin Name: Mitch's Gutenblocks
* Plugin URI: https://github.com/WordPress/mitch-gutenblocks
* Description: Mitch's playground for creating new blocks for Gutenberg.
* Version: 1.0.0.0
* Author: Mitch Canter
* Author URI: https://www.mitchcanter.me
*
* @package mitch-gutenblocks
*/
/** Defining Constants **/
define( 'SG_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
define( 'SG_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
/** Separating Files **/
require_once ( SG_PLUGIN_PATH . 'blocks/sample-block/sample-block.php');
For our main plugin file, I've defined constants and broken the actual block off into its own file.
Our structure looks something like this:
mitch-gutenblocks
|- blocks
|--- sample-block
|----- block.js
|----- index.php
|----- sample-block.php
|--- index.php
|- index.php
- mitch-gutenblocks.php
We have our root folder (with main plugin file), a separate folder for each block, and a javascript and php file inside of that folder (along with silencing indices for each level).
Let's look at the sample-block.php code:
<?php
function sample_block_editor_assets() {
wp_enqueue_script( 'sample-block', plugins_url( 'block.js', __FILE__ ), array(
'wp-blocks',
'wp-i18n',
'wp-element',
), time() );
wp_enqueue_style( 'giphy-block', plugins_url( 'editor.css', __FILE__ ), array( 'wp-blocks' ), time() );
}
add_action( 'enqueue_block_editor_assets', 'sample_block_editor_assets' );
But wait, you may ask… where is all of the plugin functionality?
Welcome to Gutenberg's second pain point with WordPress developers – all of the blocks are based on React JavaScript. I think that of the two major pain points, this is the loudest simply because WordPress developers see PHP as the defining language of their platform. I'll go into another post explaining why this is turning into an incorrect assumption another time, but the long story short is this: with WordPress turning into a REST-API powered CMS, we can start to focus on other languages to create WordPress sites. React is a natural choice, despite its baggage or emotional reaction.
Here is a VERY simple block.js file:
( function( wp, $, _ ) {
var __ = wp.i18n.__;
wp.blocks.registerBlockType( 'sample-block/sample-block', {
title: __( 'Sample Block', 'sample-block' ),
category: 'common',
icon: 'admin-plugins',
keywords: [ 'sample' ],
edit: function edit( props ) {
... code goes here ...
},
save: function save( props ) {
... code goes here ...
},
} );
} )( window.wp, window.jQuery, window._ );
Let's walk through it. If you're familiar with React, this syntax may be familiar. If not, here's what's going on:
The first few lines set up the function and call wp.blocks.registerBlockType – similar to firing up a class in PHP. We're using an abstracted layer to generate the guts of the block itself. We define a title, category, an icon (via Dashicon naming) and any keywords we want to have this pop up for in search.
There are two important sections: Edit, and Save. Editing functions are what happen as you use the block in the editor. You can modify the block at will with functions, and any inputs you have can be utilized in the next function.
Save functions fire when the box itself is manipulated. Moving a box, adding a box, or any other CRUD functions will fire the save command and make sure any data currently in the box isn't lost.
Change for Change Sake? Or Progression?
There are very, very loud opinions on both sides of the aisle on this topic. WordPress purists argue that PHP is the de-facto language for WordPress. Why use another framework to do something that we've been able to do for a long time – create content?
On the other hand, progress marches on, and others see value in allowing other frameworks that are maturing and progressing to interact with WordPress.
We're going to continue to look through the Gutenberg platform over the next days – adding a block is fine and dandy, but what does that mean for meta boxes, options in WordPress (stored via PHP) and other data we already have in WordPress?
That's a whole different post altogether!