Gutenberg Sidebar – Filling in the Sidebar

Gutenberg - Filling in the Sidebar

Before we have a chance to include content in our sidebar besides a “Hello World”, we need to assume a few things.

  1. We need to set the defaults of our sidebar content. The default will be that the landing page is off and a body color is not set.
  2. We need to read in any saved post meta to make sure our interface is up-to-date.
  3. We need to save any of that post meta if a user makes an interaction with our sidebar.

Let’s get started by adding a sidebar.js file in our src folder like so:

. └── landing-page-gutenberg-template/ ├── dist/ │ ├── sidebar.js (compiled JS) │ └── template.css (compiled SCSS) └── src/ └── js/ ├── index.js └── sidebar.js
Code language: AsciiDoc (asciidoc)

Setting up the Dependencies

We’ll need a few dependencies to get this sidebar up and running. We’ll be using React hooks to set up our initial state, read in the saved meta values, and saving them as soon as the post has been updated.

const { __ } = wp.i18n; const { Fragment, useState, useEffect } = wp.element; const { PanelBody, PanelRow, ToggleControl, } = wp.components; const { withDispatch } = wp.data; const { PanelColorSettings } = wp.blockEditor;
Code language: JavaScript (javascript)

The main things you may recognize is the useState and useEffect React hooks. We’ll be using those to set a default state also read in the stored meta values.

Setting Initial State

const Sidebar = (props) => { const [enabled, setEnabled] = useState(false); const [bodyColor, setBodyColor] = useState(false);
Code language: JavaScript (javascript)

We start off by setting the initial state of two variables we’ll be using for state: enabled and bodyColor. We’ll set these two to false as they are unused if nothing is selected.

Next, we’ll use useEffect to initialize our state variables.

Reading In Meta Values

/* Initialize the initial state */ useEffect(() => { const { _wpajax_enable_landing_template, _wpajax_set_body_color, } = wp.data.select("core/editor").getEditedPostAttribute("meta"); if ( _wpajax_enable_landing_template != null && _wpajax_enable_landing_template.length != 0 ) { setEnabled(_wpajax_enable_landing_template); } else { setEnabled(false); } if (_wpajax_set_body_color != null && _wpajax_set_body_color.length != 0) { setBodyColor(_wpajax_set_body_color); } else { setBodyColor(""); } }, []);
Code language: JavaScript (javascript)

We grab the meta names by variable name (meta key name) and check if they are set or not. If they are set, then we re-set state to what is stored at the post level.

The Components

The sidebar components will consist of a toggle control and a color picker.

return ( <Fragment> <PanelBody title={__('Landing Template', 'landing-page-gutenberg-template')}> <PanelRow> <ToggleControl label={__( "Enable Landing Page Template", "landing-page-gutenberg-template" )} checked={enabled} onChange={(value) => { props.setMetaFieldValue("_wpajax_enable_landing_template", value); setEnabled(value); }} /> </PanelRow> {enabled && ( <Fragment> <PanelRow> <PanelColorSettings title={ __( 'Colors', 'landing-page-gutenberg-template' ) } initialOpen={ true } colorSettings={ [ { value: bodyColor, onChange: ( value ) => { props.setMetaFieldValue("_wpajax_set_body_color", value); setBodyColor(value); }, label: __( 'Select a Body Background Color', 'landing-page-gutenberg-template' ), } ] } /> </PanelRow> </Fragment> )} </PanelBody> </Fragment> ); };
Code language: JavaScript (javascript)

When we have an on-change event, we call a prop function called setMetaFieldValue. We’ll use a fancy WordPress trick to be able to access the post meta to tell WordPress to save our meta and/or record a change so the user is alerted that navigating away from the page will result in lost data.

export default withDispatch((dispatch) => { return { setMetaFieldValue: function (key, value) { dispatch("core/editor").editPost({ meta: { [key]: value } }); }, }; })(Sidebar);
Code language: JavaScript (javascript)

The Entire File

Here is the entire sidebar.js file as a matter of reference.

const { __ } = wp.i18n; const { Fragment, useState, useEffect } = wp.element; const { PanelBody, PanelRow, ToggleControl, } = wp.components; const { withDispatch } = wp.data; const { PanelColorSettings } = wp.blockEditor; const Sidebar = (props) => { const [enabled, setEnabled] = useState(false); const [bodyColor, setBodyColor] = useState(false); /* Initialize the initial state */ useEffect(() => { const { _wpajax_enable_landing_template, _wpajax_set_body_color, } = wp.data.select("core/editor").getEditedPostAttribute("meta"); if ( _wpajax_enable_landing_template != null && _wpajax_enable_landing_template.length != 0 ) { setEnabled(_wpajax_enable_landing_template); } else { setEnabled(false); } if (_wpajax_set_body_color != null && _wpajax_set_body_color.length != 0) { setBodyColor(_wpajax_set_body_color); } else { setBodyColor(""); } }, []); return ( <Fragment> <PanelBody title={__('Landing Template', 'landing-page-gutenberg-template')}> <PanelRow> <ToggleControl label={__( "Enable Landing Page Template", "landing-page-gutenberg-template" )} checked={enabled} onChange={(value) => { props.setMetaFieldValue("_wpajax_enable_landing_template", value); setEnabled(value); }} /> </PanelRow> {enabled && ( <Fragment> <PanelRow> <PanelColorSettings title={ __( 'Colors', 'landing-page-gutenberg-template' ) } initialOpen={ true } colorSettings={ [ { value: bodyColor, onChange: ( value ) => { props.setMetaFieldValue("_wpajax_set_body_color", value); setBodyColor(value); }, label: __( 'Select a Body Background Color', 'landing-page-gutenberg-template' ), } ] } /> </PanelRow> </Fragment> )} </PanelBody> </Fragment> ); }; export default withDispatch((dispatch) => { return { setMetaFieldValue: function (key, value) { dispatch("core/editor").editPost({ meta: { [key]: value } }); }, }; })(Sidebar);
Code language: JavaScript (javascript)

The Main Sidebar File

Now that we have working sidebar innards (in theory), let’s go back to index.js and place all the placeholders into place and get rid of our “Hello World.”

. └── landing-page-gutenberg-template/ ├── dist/ │ ├── sidebar.js (compiled JS) │ └── template.css (compiled SCSS) └── src/ └── js/ ├── index.js └── sidebar.js
Code language: JavaScript (javascript)
import Sidebar from "./sidebar"; const { __ } = wp.i18n; const { registerPlugin } = wp.plugins; const { PluginSidebar, PluginSidebarMoreMenuItem } = wp.editPost; const { Fragment } = wp.element; registerPlugin("landing-page-gutenberg-template", { icon: ( <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24" > <path d="M0 0h24v24H0z" fill="none" /> <path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" /> </svg> ), render: () => { return ( <Fragment> <PluginSidebarMoreMenuItem target="landing-page-sidebar"> {__("Landing Page", "anding-page-gutenberg-template")} </PluginSidebarMoreMenuItem> <PluginSidebar name="landing-page-sidebar" title={__("Full Width", "anding-page-gutenberg-template")} > <Sidebar /> </PluginSidebar> </Fragment> ); }, });
Code language: JavaScript (javascript)

Conclusion

We finally have a working Gutenberg sidebar. What’s left to do?

  1. Read in any saved post meta and output a full-screen template.
  2. Populate this template and output all the blocks.

Let’s concentrate on how to read in this saved post meta and do something with it such as loading a landing page template.