Gutenberg is a new editor for WordPress that will totally replace the current TinyMCE-powered editor. It is an ambitious project that will arguably change WordPress in many ways and would affect both regular end-users and developers, specifically, those who depend on the editor screen for working on WordPress. Here is how it looks.

Gutenberg Editor with sidebar on the right opened and a block option is displayedGutenberg Editor with sidebar on the right opened and a block option is displayed
It’s obvious that it’s inspired by the Medium editor UI.

Gutenberg also introduces a new paradigm in WordPress called “Block”.

“Block” is the abstract term used to describe units of markup that are composed form the content or layout of a webpage. The idea combines concepts of what in WordPress today we achieve with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience.

Setting Up the Project

Knowing the fact that Gutenberg is built on top of React, some developers are worried that the barrier is too high for entry-level developers for developing Gutenberg.

Setting up React.js could be quite time-consuming and confusing if you’ve just getting started with it. You’ll need at least, JSX transformer, Babel, depending on your code you might need some Babel plugins, and a Bundler like Webpack, Rollup, or Parcel.

Fortunately, some people within WordPress community stepped-up and are trying to make developing Gutenberg as easy as possible for everyone to follow. Today, we have a tool that will generate a Gutenberg boilerplate so we can start writing code right away instead of befuddling with the tools and the configurations.

Create Guten Block

The create-guten-block is an initiate project by Ahmad Awais. It’s a zero-configuration tool kit (#0CJS) that will allow you to develop Gutenberg block with some modern stacks preset including React, Webpack, ESNext, Babel, ESLint, and Sass. Follow the instruction to get started with Create Guten Block.

Using ES5 (ECMAScript 5)

Using all these tools to create a simple “hello-world” block might seem just too much. If you like to keep your stacks lean, you can actually develop a Gutenberg block using a plain good ol’ ECMAScript 5 that you might already have familiarity with. If you have WP-CLI 1.5.0 installed on your computer, you can simply run…

wp scaffold block  [--title=] [--dashicon=<dashicon>] [--category=<category>] [--theme] [--plugin=<plugin>] [--force]</pre>
<p>…to <strong>generate the Gutenberg block boilerplate to your plugin or theme</strong>. This approach is more sensible, particularly, for existing plugins and themes that you’ve developed before the Gutenberg era.</p>
<p>Instead of creating a new plugin to accommodate the Gutenberg blocks, you might want to integrate the blocks to your plugins or the themes. And to make this tutorial easy to follow for everyone, <strong>we’ll be using ECMAScript 5 with WP-CLI</strong>.</p>
<h4>Registering a New Block</h4>
<p>Gutenberg is currently developed as a plugin and will be merged to WordPress 5.0 whenever the team feels it’s ready. So, for the time being, you will need to install it from the <strong>Plugins page in <code>wp-admin</code></strong>. Once you have installed and activated it, run the following command in the Terminal or the Command Prompt if you’re on a Windows machine.</p>
<pre class="bash">
wp scaffold block series --title="HTML5 Series" --theme</pre>
<p>This command will generate a Block to the currently active theme. Our Block will consists of the following files:</p>
<pre class="bash">
├── series
│   ├── block.js
│   ├── editor.css
│   └── style.css
└── series.php
<p>Let’s load the main file of our blocks in the <code>functions.php</code> of our theme:</p>
<pre class="javascript">
if ( function_exists( 'register_block_type' ) ) {
	require get_template_directory() . '/blocks/series.php';
<p>Notice that we enclose the file loading with a conditional. This ensures <strong>compatibility with previous WordPress version that our block is only loaded when Gutenberg is present</strong>. Our Block should now be available within the Gutenberg interface.</p>
<figure><span class="img-ratio-placeholder"><IMG src="" alt=""><img loading="lazy" src="image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="" width="750" height="430"><span class="img-ratio-placeholder__fill" style="padding-bottom:57%;max-width:750px"></span></span></figure>
<p>This how it looks when we insert the block.</p>
<figure><span class="img-ratio-placeholder"><IMG src="" alt=""><img loading="lazy" src="image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="" width="750" height="350"><span class="img-ratio-placeholder__fill" style="padding-bottom:46%;max-width:750px"></span></span></figure>
<h3>Gutenberg APIs</h3>
<p>Gutenberg introduces two sets of APIs to register a new Block. If we look at the <code>series.php</code>, we will find the following code that registers our new Block. It also <strong>loads the stylesheet and JavaScripts on the front-end and the editor</strong>.</p>
<pre class="javascript">register_block_type( 'twentyseventeen/series', array(
    'editor_script' => 'series-block-editor',
    'editor_style' => 'series-block-editor',
    'style' => 'series-block',
) );</pre>
<p>As we can see above, our Block is named <code>twentyseventeen/series</code>, the Block name must be unique and <a href="" target="_blank">namespaced</a> to avoid collision with the other Blocks brought by the other plugins.</p>
<p>Furthermore, <strong>Gutenberg provides a set of new JavaScript APIs to interact with the “Block” interface</strong> in the editor. Since the API is quite abundant, we’ll be focusing on some specifics that I think you should know to get a simple yet functioning Gutenberg Block.</p>
<p>First, we will be looking into <code>wp.blocks.registerBlockType</code>. This function is used to <strong>register a new “Block” to the Gutenberg editor</strong>. It requires two arguments. The first argument is the Block name which should follow name registered in the <code>register_block_type</code> function in the PHP side. The second argument is an <strong>Object defining the Block properties</strong> like title, category, and a couple of functions to render the Block interface.</p>
<pre class="javascript">
var registerBlockType = wp.blocks.registerBlockType;

registerBlockType( 'twentyseventeen/series', {
    title: __( 'HTML5 Series' ),
    category: 'widgets',
    keywords: [ 'html' ],
    edit: function( props ) { },
    save: function( props ) { }
} );
<p>This function allows you to create the element within the “Block” in the post editor. The <code>wp.element.createElement</code> function is basically an abstraction of the <a href="">React <code>createElement()</code> function</a> thus it accepts the same set of arguments. The first argument takes the type of the element for example a paragraph, a <code>span</code>, or a <code>div</code> as shown below:</p>
<pre class="bash">wp.element.createElement('div');</pre>
<p>We can <strong>alias the function into a variable</strong> so it’s shorter to write. For example:</p>
<pre class="bash">
var el = wp.element.createElement;
<p>If you <strong>prefer using the new ES6 syntax</strong>, you can also do it this way:</p>
<pre class="bash">
const { createElement: el } = wp.element;
<p>We can also <strong>add the element attributes</strong> such as the <code>class</code> name or <code>id</code> on the second parameter as follows:</p>
<pre class="javascript">
var el = wp.element.createElement;
el('div', {
    'class': 'series-html5',
    'id': 'series-html-post-id-001'
<p>The <code>div</code> that we created would not make sense without the content. We can <strong>add the content on the argument of the third parameter</strong>:</p>
<pre class="javascript">
var el = wp.element.createElement;
el('p', {
    'class': 'series-html5',
    'id': 'series-html-post-id-001'
}, 'This article is part of our "HTML5/CSS3 Tutorials series" - dedicated to help make you a better designer and/or developer. Click here to see more articles from the same series' );</pre>
<p>The <code>wp.components</code> contain a collection of, as the name implies, the Gutenberg components. These components technically are <a target="_blank" href="">React custom components</a> which include the Button, Popover, Spinner, Tooltip, and a bunch of others. We can <strong>reuse these components into our own Block</strong>. In the following example, we add a button component.</p>
<pre class="javascript">
var Button = wp.components.Button;
el( Button, {
    'class': 'download-button',
}, 'Download' );</pre>
<p>The Attributes is the way to store the data in our Block, this data could be like the content, the colors, the alignments, the URL, etc. We can get the attributes from the Properties passed on the <code>edit()</code> function, as follows:</p>
<pre class="javascript">
edit: function( props ) {
    var content = props.attributes.seriesContent;

    return el( 'div', {
        'class': 'series-html5',
        'id': 'series-html-post-id-001'
    }, content );
<p>To update the Attributes, we use the <code>setAttributes()</code> function. Typically we would change the content on certain action such as when a button is clicked, an input is filled, an option is selected, etc. In the following example, we use it to add a <strong>fallback</strong> content of our Block in case something unexpected happened to our <code>seriesContent</code> Attribute.</p>
<pre class="javascript">
edit: function( props ) {

    if ( typeof props.attributes.seriesContent === 'undefined' || ! props.attributes.seriesContent ) {
            seriesContent: 'Hello World! Here is the fallback content.'

    var content = props.attributes.seriesContent;

    return [
        el( 'div', {
            'class': 'series-html5',
            'id': 'series-html-post-id-001'
        }, content ),
<h4>Saving the Block</h4>
<p>The <code>save()</code> function works similarly to the <code>edit()</code>, except it defines the content of our Block to save to the post database. Saving the Block content is quite straightforward, as we can see below:</p>
<pre class="javascript">
save: function( props ) {

    if ( ! props || ! props.attributes.seriesContent ) {

    var content = props.attributes.seriesContent;

    return [
        el( 'div', {
            'class': 'series-html5',
            'id': 'series-html-post-id-001'
        }, content ),
<h3>What’s Next?</h3>
<p>Gutenberg will change WordPress ecosystem for the better (or possibly the worse). It enables developers to <strong>adopt a new way of developing WordPress plugins and themes</strong>. Gutenberg is just a start. Soon the “Block” paradigm will be expanded to other areas of WordPress such as the Settings APIs and the Widgets.</p>
<p><a href="">Learn JavaScript Deeply</a>; it’s the only way to get into Gutenberg and stay relevant to the future in WordPress industry. If you’re already familiar with the JavaScript basics, the quirks, the functions, the tools, the goods and the bads, I’m really sure you will get up to speed with Gutenberg.</p>
<p>As mentioned, Gutenberg exposes an abundance of APIs, enough to do almost anything to your Block. You can choose whether to <strong>code your Block with a plain old JavaScript, JavaScript with ES6 syntax, React, or even Vue</strong>.</p>
<h4>Ideas and Inspirations</h4>
<p>I’ve created a very (very) simple Gutenberg Block that you can find in the <a href="" target="_blank"> repository of our Github account</a>. Furthermore, I’ve also put together a number of repositories from where you can drive inspiration on building a more complex Block.</p>
<li><a href="" target="_blank">Gutenblocks</a> – A collection of Blocks by Mathieu Viet written in JavaScript with ES5 Syntax</li>
<li><a href="" target="_blank">Jetpack Gutenblocks Project</a> – a collection of Blocks bundled in Jetpack</li>
<li><a href="">A List of Examples of Gutenberg Implementation</a> including with Vue.js</li>
<h3>Further Reference</h3>
<li><a href="">Gutenberg Official Repository</a></li>
<li><a href="">Gutenberg Handbook</a></li>
<p>The post <a rel="nofollow" href="">Gutenberg: All You Need to Know About WordPress’ Latest Editor</a> appeared first on <a rel="nofollow" href="">Hongkiat</a>.</p>
</div> <!-- .entry-content -->
<div class="et_post_meta_wrapper">
<!-- You can start editing here. -->
<section id="comment-wrap">
<div id="comment-section" class="nocomments">
<!-- If comments are open, but there are no comments. -->
<div id="respond" class="comment-respond">
<h3 id="reply-title" class="comment-reply-title"><span>Submit a Comment</span> <small><a rel="nofollow" id="cancel-comment-reply-link" href="/gutenberg-all-you-need-to-know-about-wordpress-latest-editor/#respond" style="display:none;">Click here to cancel reply.</a></small></h3><p class="must-log-in">You must be <a href="">logged in</a> to post a comment.</p>	</div><!-- #respond -->
</section>					</div> <!-- .et_post_meta_wrapper -->
</article> <!-- .et_pb_post -->
</div> <!-- #left-area -->
<div id="sidebar">
<div id="text-2" class="et_pb_widget widget_text">			<div class="textwidget"><p><a style="display:block; text-align: center; margin-bottom: 28px" title="WordPresss Maintenance and Updates" href="/#wordpress-maintenance">WordPress® Care Plans</a></p>
</div> <!-- end .et_pb_widget --><div id="search-2" class="et_pb_widget widget_search"><form role="search" method="get" id="searchform" class="searchform" action="">
<label class="screen-reader-text" for="s">Search for:</label>
<input type="text" value="" name="s" id="s" />
<input type="submit" id="searchsubmit" value="Search" />
</form></div> <!-- end .et_pb_widget -->
<div id="recent-posts-2" class="et_pb_widget widget_recent_entries">
<h4 class="widgettitle">Recent Posts</h4>
<a href=""> Business Plan Review – What You Get And Is It Worth It? (2019)</a>
<a href="">How to Recreate ET’s Layout Pack Previews with Fan-Out Hover Effects in Divi</a>
<a href="">Top 3 FlyWheel/WP Engine Alternatives To Avoid the Acquisition Blues</a>
<a href="">How to Streamline Web Development Workflow with Yeoman</a>
<a href="">Bringing Technology to Our Creatives</a>
</div> <!-- end .et_pb_widget --><div id="categories-2" class="et_pb_widget widget_categories"><h4 class="widgettitle">Categories</h4>
<li class="cat-item cat-item-1"><a href="">Everything Else</a>
<li class="cat-item cat-item-10"><a href="">Website Security</a>
<li class="cat-item cat-item-12"><a href="">WordPress® Backups</a>
</div> <!-- end .et_pb_widget -->	</div> <!-- end #sidebar -->
</div> <!-- #content-area -->
</div> <!-- .container -->
</div> <!-- #main-content -->

<footer id="main-footer">
<div id="et-footer-nav">
<div class="container">
<ul id="menu-footer-bar" class="bottom-nav"><li id="menu-item-88" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-home menu-item-88"><a href="">Home</a></li>
<li id="menu-item-299" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-299"><a href="/#pricing">Packages & Pricing</a></li>
<li id="menu-item-90" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-90"><a href="">Partners?</a></li>
<li id="menu-item-89" class="menu-item menu-item-type-post_type menu-item-object-page current_page_parent menu-item-89"><a href="">WP News</a></li>
<li id="menu-item-92" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-92"><a href="">Terms</a></li>
<li id="menu-item-303" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-303"><a href="">Privacy Policy</a></li>
<li id="menu-item-106" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-106"><a href="">My Account</a></li>
<li id="menu-item-302" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-302"><a href="/#support">Support</a></li>
</ul>					</div>
</div> <!-- #et-footer-nav -->
<div id="footer-bottom">
<div class="container clearfix">
<p id="footer-info">Copyright © 1997 - 2021 <a href="" target="_blank">CollinMEDIA</a> | CollinMEDIA creates <a href="" target="_blank">Amazing Websites</a> | PROUDLY <a href="" target="_blank">POWERED BY WORDPRESS®</a></p>					</div>	<!-- .container -->
</footer> <!-- #main-footer -->
</div> <!-- #et-main-area -->
</div> <!-- #page-container -->
<script type='text/javascript' defer='defer' src='' id='anti-spam-script-js'></script>
<script type='text/javascript' defer='defer' src='' id='comment-reply-js'></script>
<script type='text/javascript' id='divi-custom-script-js-extra'>
/* <![CDATA[ */
var DIVI = {"item_count":"%d Item","items_count":"%d Items"};
var et_shortcodes_strings = {"previous":"Previous","next":"Next"};
var et_pb_custom = {"ajaxurl":"https:\/\/\/wp-admin\/admin-ajax.php","images_uri":"https:\/\/\/wp-content\/themes\/Divi\/images","builder_images_uri":"https:\/\/\/wp-content\/themes\/Divi\/includes\/builder\/images","et_frontend_nonce":"f08d0e1df4","subscription_failed":"Please, check the fields below to make sure you entered the correct information.","et_ab_log_nonce":"ae6b7f11a7","fill_message":"Please, fill in the following fields:","contact_error_message":"Please, fix the following errors:","invalid":"Invalid email","captcha":"Captcha","prev":"Prev","previous":"Previous","next":"Next","wrong_captcha":"You entered the wrong number in captcha.","wrong_checkbox":"Checkbox","ignore_waypoints":"no","is_divi_theme_used":"1","widget_search_selector":".widget_search","ab_tests":[],"is_ab_testing_active":"","page_id":"3219","unique_test_id":"","ab_bounce_rate":"5","is_cache_plugin_active":"yes","is_shortcode_tracking":"","tinymce_uri":""}; var et_builder_utils_params = {"condition":{"diviTheme":true,"extraTheme":false},"scrollLocations":["app","top"],"builderScrollLocations":{"desktop":"app","tablet":"app","phone":"app"},"onloadScrollLocation":"app","builderType":"fe"}; var et_frontend_scripts = {"builderCssContainerPrefix":"#et-boc","builderCssLayoutPrefix":"#et-boc .et-l"};
var et_pb_box_shadow_elements = [];
var et_pb_motion_elements = {"desktop":[],"tablet":[],"phone":[]};
var et_pb_sticky_elements = [];
/* ]]> */
<script type='text/javascript' defer='defer' src='' id='divi-custom-script-js'></script>
<script type='text/javascript' defer='defer' src='' id='et-core-common-js'></script>
<script type='text/javascript' defer='defer' src='' id='wp-embed-js'></script>
<!-- Child theme custom CSS created by Divi Children - -->
<style type="text/css" media="screen">
#footer-widgets {padding-top:80px;}
.footer-widget {margin-bottom:50px!important;}
#main-footer { background-color:#ffffff!important;}
.footer-widget .title {color:#bcbcbc!important;}
.footer-widget .title {font-size:18px;}
.footer-widget, .footer-widget li, .footer-widget li a {color:#ababab!important; font-size:14px;}
.footer-widget li a:hover, #footer-widgets .et_pb_widget li a:hover {color:#0c71c3!important;}
.footer-widget li:before {border-color:#0c71c3!important;}
.footer-widget li:before {-moz-border-radius: 0!important; -webkit-border-radius: 0!important;  border-radius: 0!important;}
#footer-bottom { background-color:#ffffff;}
#footer-bottom {padding:45px 0 30px;}
#footer-info, #footer-info a {color:#bcbcbc;}
#footer-info, #footer-info a {font-size:12px;}
#footer-bottom li a {color:#ffffff;}
#footer-bottom li a:hover {color:#0c71c3!important;}
#footer-bottom li a {font-size:18px;}
#footer-bottom li {margin-left:12px;}
#main-content .container:before {display:none;}
#sidebar h4.widgettitle {font-size:18px;}
#sidebar li {padding: 0 0 4px 14px; position: relative; }
#sidebar li:before {color:#0c71c3; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; border-style: solid; border-width: 3px; content: ""; position: absolute; top: 9px;  left: 0;}
#sidebar li, #sidebar li a {font-size:14px;}
<!-- End Child theme custom CSS -->
</html><!-- WP Fastest Cache file was created in 0.40624499320984 seconds, on 22-07-21 0:07:21 -->