Gutenberg Custom Fields with TypeRocket

You Will Learn

Gutenberg Custom Fields Using TypeRocket

Contents

At present, adding custom fields to Gutenberg requires knowing a little JavaScript and React.

In this tutorial, I will walk you through the basics of adding a custom field to Gutenberg using TypeRocket.

In terms of adding custom fields to the Gutenberg block editor, TypeRocket does not provide an API... it is simply too early in the Gutenberg development cycle to start building an encapsulating API. Plus, WordPress already provides a decent API for adding custom fields. However, that doesn't mean TypeRocket will not help you add custom fields to Gutenberg.

In fact, TypeRocket makes it easy to get started by leveraging Laravel mix's React functionality. Let's take a look at that now.

React File

To get started making our custom field we need to set up a jsx React file to write our JS code. In your TypeRocket webpack.mix.js file locate the Admin section and add the following code.

// Admin
mix.js('resources/js/admin.js', 'wordpress/assets/templates/js')
    .react('resources/js/gutenberg.jsx', 'wordpress/assets/templates/js') // add this

Next, create a file called gutenberg.jsx in the typerocket resources/js folder. Then, all you need to do is run npm install and npm run watch from the typerocket folder.

npm install
npm run watch

Perfect! On to the PHP!

The PHP

We only need to do two things with PHP for our Gutenberg custom field.

  1. First, we need to register our compiled version of gutenberg.jsx. Depending on how you install TypeRocket the location of your file will vary. Just be sure your URL is correct.
  2. Last, register our post meta field. We need to register our post meta because Gutenberg uses the WordPress REST API. Use register_meta for that.
add_action( 'enqueue_block_editor_assets', function() {

    // update $url based on your JS files location 
    $url = get_template_directory_uri() . '/js/gutenberg.js';

    wp_enqueue_script(
        'gutenberg-main-js',
        $url,
        ['wp-plugins', 'wp-edit-post', 'wp-element', 'wp-components', 'wp-data']
    );

});

// update $field_name based on the post meta name 
// you want to save the data under
$field_name = 'video_url';

register_meta( 'post', $field_name, array(
    'show_in_rest' => true,
    'single' => true,
    'type' => 'string',
) );

With PHP in place, you are ready to start writing the React code needed for our custom field.

Avoid Bugs!

As a quick note when adding custom fields using Gutenberg be sure you are not also adding custom fields using TypeRocket's PHP API. If you are adding the same custom field in a metabox with TypeRocket PHP your custom Gutenberg field will not save!

The Custom Field

Below is all the code needed to get a custom field working in Gutenberg. Add the following code to your gutenberg.jsx and save the file.

const { PluginSidebar, PluginSidebarMoreMenuItem } = wp.editPost;
const { TextControl: Text, Panel, PanelBody, PanelRow } = wp.components;
const { registerPlugin } = wp.plugins;
const  { withSelect, withDispatch } = wp.data;

let mapSelectToProps = function( select ) {
    return {
        metaFieldValue: select( 'core/editor' )
            .getEditedPostAttribute( 'meta' )
            [ 'video_url' ]
    }
};

let mapDispatchToProps = function( dispatch ) {
    return {
        setMetaFieldValue: function( value ) {
            dispatch( 'core/editor' ).editPost(
                { meta: { video_url: value } }
            );
        }
    }
};

// This is where your custom field goes
const CustomizePanel = (props) => (
    <Panel>
        <PanelBody
            title="Featured Video"
            initialOpen={ true }
        >
            <Text
                label="Video URL"
                value={props.metaFieldValue}
                help="YouTube or Vimeo URL"
                type="text"
                onChange={( content ) => props.setMetaFieldValue( content ) }
            />
        </PanelBody>
    </Panel>
);

let CustomizePanelWithData = withSelect( mapSelectToProps )( CustomizePanel );
let MetaBlockFieldWithDataAndActions = withDispatch( mapDispatchToProps )( CustomizePanelWithData );

const Component = () => (
    <React.Fragment>
        <PluginSidebarMoreMenuItem
            target="sidebar-name"
        >
            Customize
        </PluginSidebarMoreMenuItem>
        <PluginSidebar
            name="sidebar-name"
            title="Customize"
        >
            <MetaBlockFieldWithDataAndActions />
        </PluginSidebar>
    </React.Fragment>
);

registerPlugin( 'plugin-name', {
    icon: 'format-video',
    render: Component,
} );

You now have a Gutenberg custom field!

The UI

gutenberg-ui-custom-field

Finally, let's take a look at our custom field. It looks great! But why did we add the custom field the way we have? There are so many questions that need to be answered.

Let's walk through a few of the questions:

  1. Where to find the custom field?
  2. Why do we need to use the custom plugin panel?
  3. What about blocks?!

Where to find the custom field?

Your custom field is located in what is called a PluginSidebar. If you unstar your plugin sidebar it will need to be "re-pinned". To "re-pin" your custom field's "Plugin Sidebar" click the "tools & options" button and then under "Plugins" click on "Customize". "Customize" is the plugin sidebar we added and that sidebar holds our Panel that holds our custom field.

gutenberg-custom-field-sidebar-show

If you are not using PluginSidebarMoreMenuItem you will not have the option to "re-pin" your sidebar, be sure you have it!

Why do we need to use the custom plugin panel?

WordPress is trying to remove the idea of Metaboxes. With Gutenberg, they are pushing for "Blocks" and "Panels". At the moment the only way to add a "Panel" is to add it into a "Plugin Sidebar". That is why you need a "Plugin Sidebar".

What about blocks?!

We are not using "Blocks" for one big reason. Custom fields were never meant to live in "Blocks", blocks and custom fields are two very different things.

I could go on for a while about "Blocks" but I'll keep it brief for the topic of custom fields... We may or may not like it but "Blocks" are the future of WordPress. Custom fields still have their place but that place is not in "Blocks". So, I digress.

If you want to add custom fields to "Blocks" you can. But, I will not cover it here.

Maybe we will come round to that topic. But, it is a huge topic and needs a very deep explanation to really cover how to think about and use "Blocks".

Final Thoughts

Custom fields are a big topic and this post in no terms does the topic justice. If you need a lot of custom fields Gutenberg is probably not the best place for them.

That is why TypeRocket is so helpful. If you need a lot of custom fields you should use TypeRocket custom fields. You can do that in custom post types or in custom resources.

No matter what your need for custom fields may be I give you a word of advice... Think differently, new problems will not likely be solved with old solutions.

Share this on