My Gutenberg Breakthrough: Adding a Custom Notification

A custom notification for RSVPMaker templates.

One of the differences between “traditional” WordPress plugin development and creating software that works with the new Gutenberg editor is the scarcity of adequate, understandable documentation.

I speak as a WordPress developer who is largely self-taught, by which I mean I’ve learned by reading books, tutorials and the official WordPress documentation for developers. For virtually anything I wanted to learn how to do, there has almost always been a reasonably clear function definition if not a tutorial or a StackOverflow question and answer that was in the ballpark. Over the years, I have become reasonably proficient in PHP and MySQL and WordPress utility functions, actions and filters. Within those bounds, I like to think I’ve occasionally had an original idea or two.

The Gutenberg framework is in a much different place, in terms of documentation and code examples. There are some good tutorials out there on how to create Gutenberg blocks (units of content that can have their own editor properties). Thank God for create-guten-block, which makes many aspects of setting up your development environment easier if you’re just learning.

There is a Gutenberg Handbook, but a lot of it seems to be written for people who already understand React (the Facebook open source framework from Facebook that Gutenberg is based on). I can do a few things with JQuery but until recently didn’t realize how behind-the-times I was, at least from the viewpoint of enthusiasts for “modern JavaScript.” Telling me that the WordPress state management system is similar to Redux (yet another JavaScript framework often used with React) doesn’t help me.

If I wanted to display a custom notification to be displayed anywhere else on the administrator’s dashboard, there would be dozens of tutorials that would tell me exactly how to do that with a few lines of PHP. But those PHP-generated notifications aren’t displayed on the editor screen when Gutenberg is active. Aside from any technological reasons for this, it’s part of an intentional decluttering of the editor screens.

That means if you want to display a notification on the Gutenberg-powered editor screen, you have to do it with Gutenberg APIs. It has taken me literally months to figure out how to do that. All my Googling for answers came to naught. Finally, I came across a discussion on on the Github issues discussion board for Gutenberg where someone else was asking approximately the same question.

In response, one developer gave a pretty detailed example of how to generate a notification (thank you, Daniel Bachhuber). The only missing piece was some way of making the notification display in response to an event, like a post being saved. Mr. Bachhuber told me I would have to do more research because he didn’t know that, either.

In my use case, certain posts of the type rsvpmaker are used as templates for specific events. The RSVPMaker plugin needs to display a notice prompting the user who has updated a template to click through to another screen if they want to create or update events based on that template. This feature has essentially been broken in RSVPMaker when used in combination with Gutenberg.

To get the rest of the way to an answer, I had to go spelunking through other people’s source code. The routine shown below is loosely based on code Gutenberg uses internally to save metabox content on post save. I wrapped the code modeled on that example around my createNotification command, and finally I had something that worked.

// context check: if this is an rsvpmaker template, this will have be available as localized data from PHP
if((typeof rsvpmaker_json !== 'undefined' ) && rsvpmaker_json.projected_url) {
let wasSavingPost = wp.data.select( 'core/editor' ).isSavingPost();
let wasAutosavingPost = wp.data.select( 'core/editor' ).isAutosavingPost();
let wasPreviewingPost = wp.data.select( 'core/editor' ).isPreviewingPost();
// determine whether to show notice
subscribe( () => {
const isSavingPost = wp.data.select( 'core/editor' ).isSavingPost();
const isAutosavingPost = wp.data.select( 'core/editor' ).isAutosavingPost();
const isPreviewingPost = wp.data.select( 'core/editor' ).isPreviewingPost();
const hasActiveMetaBoxes = wp.data.select( 'core/edit-post' ).hasMetaBoxes();
// Save metaboxes on save completion, except for autosaves that are not a post preview.
const shouldTriggerTemplateNotice = (
( wasSavingPost && ! isSavingPost && ! wasAutosavingPost ) ||
( wasAutosavingPost && wasPreviewingPost && ! isPreviewingPost )
);
// Save current state for next inspection.
wasSavingPost = isSavingPost;
wasAutosavingPost = isAutosavingPost;
wasPreviewingPost = isPreviewingPost;
if ( shouldTriggerTemplateNotice ) {
wp.data.dispatch('core/notices').createNotice(
'info', // Can be one of: success, info, warning, error.
__('After updating this template, click'), // Text string to display.
{
id: 'rsvptemplateupdate', //assigning an ID prevents the notice from being added repeatedly
isDismissible: true, // Whether the user can dismiss the notice.
// Any actions the user can perform.
actions: [
{
url: rsvpmaker_json.projected_url,
label: __('create / update events')
}
]
}
);
}
/* placeholder for logic to remove notice
else {
console.log('remove notice');
}
*/
} );
}

In this example, the url for the admin page where generate event posts based on a template is localized under the rsvpmaker_json variable. On the PHP side, we test that the post is of type rsvpmaker before outputting that variable. In the JavaScript code, we test that the url is set to something other than an empty string.

We then subscribe to Gutenberg events. Every time a triggering event in the editor happens, the subscribe function fires.

We use functions like wp.data.select( ‘core/editor’ ).isSavingPost() to determine what sort of event that is. This checks whether the post is in the process of being saved (and verifies that it’s not an autosave). If yes, then the notice is displayed.

Updated: Originally, I had an issue with the same notification being added repeatedly if the user made additional changes and updating the post again. After attending Zac Gordon’s talk at WordCamp Miami, I realized I could explore the currently registered notifications from the console using

wp.data.select('core/editor').getNotices()
Console detective work.

I saw that my notices were being assigned a random id. Once I added id:’rsvptemplateupdate’ to the createNotice command, the problem with notifications being added repeatedly went away. Apparently, I just had to give the notifications system a clue of how to check whether it had already been added.

I’m still getting all this figured out.

Custom notification -when the user saves an RSVPMaker template, we prompt them to create or update events based on that template.

Leave a comment