Blog posts under the Gutenberg Editor tag https://webdevstudios.com/tags/gutenberg-editor/ WordPress Design and Development Agency Mon, 15 Apr 2024 16:00:54 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.2 https://webdevstudios.com/wp-content/uploads/2022/07/cropped-wds-icon.white-on-dark-60x60.png Blog posts under the Gutenberg Editor tag https://webdevstudios.com/tags/gutenberg-editor/ 32 32 58379230 Adding Custom Notices for the Gutenberg Editor https://webdevstudios.com/2022/07/19/custom-notices-gutenberg/ https://webdevstudios.com/2022/07/19/custom-notices-gutenberg/#respond Tue, 19 Jul 2022 16:00:13 +0000 https://webdevstudios.com/?p=25219 WordPress admin notices have changed and the good old PHP-based hooks no longer work for Gutenberg. This post covers the easy way to add admin notices when a post gets added or updated.

The post Adding Custom Notices for the Gutenberg Editor appeared first on WebDevStudios.

]]>
Change is the only constant, and developers all know it. WordPress admin notices have changed and the good old PHP-based hooks no longer work for Gutenberg.

This blog post covers the easy way to add admin notices when a post gets added or updated, focusing mainly on the Gutenberg notices.

Gutenberg Notices

Let’s start with this working example and customize it to your needs.

Hook into save action.

Here we are using the publish_post action to add our callback after every time a post gets saved. Add a did_action check to make sure this callback executes on the first time and doesn’t repeat.

Other plugins or customizations may also use this action hook, so it is recommended to perform this did_action check.

View the code on Gist.

Set the message on the callback.

Here is an example of a typical editorial workflow:

  • Author submits a blog post
  • Saved as Draft
  • Editor approves and publishes

The background action is sending email notifications to the author when the post gets published. Let your callback process the data and return the message you want to show in the notice. To keep this data easily accessible, we are using post meta.

View the code on Gist.

Create a custom endpoint.

Register an endpoint using register_rest_route. We will be using the namespace and route during the AJAX call.

View the code on Gist.

AJAX call

Now that we have an error message on meta, we have to fetch it via an AJAX request. To keep this simple, the admin script is added directly along with the PHP code. You can make it a separate file and enqueue it.

We need ‘subscribe’ and ‘select’ from WP data module.

const { subscribe,select } = wp.data;

Subscribe allows you to listen to changes in the state. By subscribing to isSavingPost(), you can call the AJAX request.

We are sending the post ID to the custom REST endpoint and displaying the message via createNotice.

View the code on Gist.

Get the error and render it.

Now we have the error, custom endpoint, and the AJAX callback. Retrieve the message from post_meta and send it to the response.

View the code on Gist.

Here is the plugin with the complete code in the repo. I hope you find this quick tip useful. Follow our blog for more WordPress tutorials.

The post Adding Custom Notices for the Gutenberg Editor appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2022/07/19/custom-notices-gutenberg/feed/ 0 25219
WordPress Blocks Backwards Compatibility https://webdevstudios.com/2020/12/29/wordpress-blocks-backwards-compatibility/ https://webdevstudios.com/2020/12/29/wordpress-blocks-backwards-compatibility/#respond Tue, 29 Dec 2020 17:00:01 +0000 https://webdevstudios.com/?p=23127 When I narrowed my development career focus from the PHP world at large to WordPress land, one of the things I enjoyed was WordPress’ commitment to backwards compatibility. As my fellow Minnesota coworker and pragmatist, Richard Aber, would say, new features are often syntactic sugar. In other words, I’m not going to save the world Read More WordPress Blocks Backwards Compatibility

The post WordPress Blocks Backwards Compatibility appeared first on WebDevStudios.

]]>
When I narrowed my development career focus from the PHP world at large to WordPress land, one of the things I enjoyed was WordPress’ commitment to backwards compatibility. As my fellow Minnesota coworker and pragmatist, Richard Aber, would say, new features are often syntactic sugar. In other words, I’m not going to save the world by typing [] instead of array().

But the compatibility landscape of WordPress 5.0 and beyond is much different. The new WordPress block editor Gutenberg is built upon React, and the development pace of React, Gutenberg, and all things JavaScript, in general, is extremely fast. I’m hoping this can serve as a reference or forewarning to those trying to keep up.

Gutenberg Versions

When you’re trying to build a Gutenberg block that is compatible back to WordPress 5.0, navigating this landscape is tricky. Since the Gutenberg editor is developed as a separate project, they have their own versions that get bundled with the major WordPress releases. Trying to find this historical information can be difficult.

After some research and discussion, Senior Backend Engineer, Sal Ferrarello, and Frontend Engineer, Mike England, started a compatibility matrix, which can be found on GitHub. But that didn’t answer all of the questions and solve all of the issues. The official Gutenberg Handbook itself is based on the latest Gutenberg code, which is ahead of the current version of WordPress. Sal opened an issue highlighting that the blocks API documentation is based off of the master branch of Gutenberg.

Block API Reference

Sadly, Sal’s documentation version issue wound up being closed citing:

We’re fixing bugs more than we’re introducing new APIs at this point.

But shortly after the version matrix was created and the version issue filed, a new page showed up in the block editor handbook highlighting the version information:

Versions in WordPress

Still, this “official” table can be a bit confusing. When you look at it, there is a range of Gutenberg versions included in a particular WordPress release:

This is a screenshot of the table. In the left column, it has the header Gutenberg Version. Beneath, in the column, it says eight point six hyphen nine point two. In the right column, the header says WordPress Version. Beneath in the column below, it says five point six.

This is because bug fixes are back-ported into the WordPress release bundle. If you’re using it for an API reference standpoint, always go with the smaller release number.

React Versions

There are several things to think about if you want to provide backwards compatibility to WordPress 5.0. One consideration is the React version included in WordPress.

If you want to create Functional Components instead of Class Components in your Gutenberg block, that requires React version 16.8. WordPress 5.2 is when React 16.8 was included. The easiest way I found to determine which versions of WordPress include which versions of React is to go to the source.

You can find the package.json for WordPress 5.2 here. This includes React 16.8.4. You can replace “5.2” with the version you’d like to investigate.

If you’ve written functional components for distribution in the WordPress.org plugin repository, don’t forget to add the “Requires at least” field to your plugin header:

/**
 * Plugin Name:       My Plugin
 * Requires at least: 5.2
 */

That way, people will not be able to upgrade/install your plugin automatically, unless they’re on WordPress 5.2 or newer.

Block Compatibility

My best advice is to tread lightly and go slowly. React and Gutenberg aren’t great at reporting where your errors are through the browser console. To start, I install the WP-Downgrade plugin so I can easily go back and forth between past and present versions.

If you’ve got something working, test it out and commit your changes. Then, test it for backwards compatibility. When you’re dealing with more than one compatibility error at a time, it’s difficult to hone in on what is going wrong. WordPress might not even load your Guten-block code if there are errors; and it also may not print a message in the console.

The most common issue I’ve encountered is with importing WordPress components. Sometimes things work by importing from a package. Sometimes they’ll only work by destructuring from the global wp object.

WordPress Gutenberg import versus Destructuring Global wp

You may have to experiment with both to see what works for maximum version compatibility.

Example: ServerSideRender

@wordpress/server-side-render

The documentation says once you include it in your package.json you can either import it:

import ServerSideRender from '@wordpress/server-side-render';

Or destructure it from the wp global:

const { serverSideRender: ServerSideRender } = wp;

But neither of those work in WordPress 5.0 (Gutenberg 4.6.1) because @wordpress/server-side-render wasn’t a package yet. It also isn’t at wp.serverSideRender at that time, it’s at wp.components.ServerSideRender.

If you want it to work in WordPress 5.0, you’ll need to destructure it from the wp global like this:

const { ServerSideRender } = wp.components;

In new versions of WordPress, you’ll get this warning message in the console:

wp.components.ServerSideRender is deprecated. Please use wp.serverSideRender instead.

The user may never see that, and it sure beats them seeing this in the editor:

This is a screenshot of a warning that could be seen in the WordPress Editor, that says, "Your site doesn't include support for the WP hyphen Strava back slash activity block. You can leave this block intact or remove it entirely."

Deprecation Hunting

Other popular components that have moved since WordPress 5.0 are BlockControls and InspectorControls. I’ve got them working in 5.0 with the following browser warnings:

wp.editor.BlockControls is deprecated. Please use wp.blockEditor.BlockControls instead.
wp.editor.InspectorControls is deprecated. Please use wp.blockEditor.InspectorControls instead.

But how did I find them? Going to the source is always best. Clone the Gutenberg project and check out the tag for the most recent version of WordPress:

git clone git@github.com:WordPress/gutenberg.git
cd gutenberg
git checkout v8.6.0

You can browse the tags on GitHub or list them with git tag. After checking out the tagged version, start looking for the component that’s not working. For InspectorControls I used grep to find it:

$ grep -r InspectorControls .
...
packages/editor/src/components/deprecated.js: 'InspectorControls'
...

There’s a lot of output when searching, but the path of the deprecated.js file gave me a clue: packages/editor. It used to be in wp.editor and is now in wp.blockEditor (which has the path packages/block-editor). Again, the documentation isn’t great, so you have to do some sleuthing and gather context clues.

Good luck out there, and always keep compatibility in mind!

The post WordPress Blocks Backwards Compatibility appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2020/12/29/wordpress-blocks-backwards-compatibility/feed/ 0 23127
How to Enable Frontend Editing with Gutenberg Blocks (Part 1) https://webdevstudios.com/2020/08/04/frontend-editing-gutenberg-blocks-1/ https://webdevstudios.com/2020/08/04/frontend-editing-gutenberg-blocks-1/#comments Tue, 04 Aug 2020 16:00:55 +0000 https://webdevstudios.com/?p=22518 The WordPress Block Editor (aka Gutenberg), despite all the bumps along the way, has completely changed how we write pages and posts. Instead of a text document, we now have access to an interactive page builder of sorts while editing content, at least on the admin side. But, what if you want to perform frontend Read More How to Enable Frontend Editing with Gutenberg Blocks (Part 1)

The post How to Enable Frontend Editing with Gutenberg Blocks (Part 1) appeared first on WebDevStudios.

]]>
The WordPress Block Editor (aka Gutenberg), despite all the bumps along the way, has completely changed how we write pages and posts. Instead of a text document, we now have access to an interactive page builder of sorts while editing content, at least on the admin side. But, what if you want to perform frontend editing?

Well, depending on your coding preferences, you could build a frontend form to update post meta, or implement some custom jQuery with AJAX, or use a page builder with frontend editing capabilities. If, on the other hand, you’ve been experimenting with your own blocks and are looking for a way to update block content and attributes from outside the confines of the post editor, then buckle up, and keep reading.

Note: The example snippets in this post are modified from @ravewebdev/initiative-tracker, my Initiative Tracker block plugin for table-top role-playing games, which was built with @WebDevStudios/create-block, the WDS block scaffolding CLI tool.

1. Block Setup

First off, we’re going to cover some necessary block configurations to consider when diving into frontend block editing:

  1. Unique block identifiers
  2. Frontend rendering

1.1. Unique Block Identifiers

When you work with blocks in the admin, WordPress handles differentiating blocks automatically. That means, when you add multiple instances of the same block, you don’t have to worry that editing one will somehow change anything about another. They’re unique and self-contained.

Unfortunately, when messing around with frontend editing, we don’t have access to the built-in block attributes for uniquely identifying and reliably targeting a block, so we’ll need to roll our own:

View the code on Gist.

First, we’ll add a new attribute called id with the type string to the block configuration. In our block’s edit function, we’ll set our new id attribute to some unique string.

You have several options here, but in this example, we’re using the built-in clientId property, an alphanumeric string such as 1bb09bce-77a1-46ee-bff5-ad6e41b13f3e that uniquely identifies a block.

The actual string itself is less important than ensuring it’s both unique and only set once, at the time the block is created. This ensures you can reliably and accurately target the correct block and prevents the value from being changed or overwritten later on.

Without the latter, the id attribute could change on every load of the edit screen and/or every render of the block, which makes WordPress think you’ve intentionally edited the post content. This triggers the dreaded “Are you sure you want to leave this page?” popup; and, the next time the post is edited, potentially displays the autosave warning, “The backup of this post in your browser is different from the version below.” Both of these instances, you are probably very familiar with and often find them annoying if you do a lot of development work in the block editor.

So, let’s try to avoid that, shall we? That’s where useEffect() comes in.

Our block’s edit property is a function component, so we’ll utilize the Effect Hook to perform a side effect, which will set our ID attribute. By passing an empty array, [], as the second argument, we specify that this effect should only occur once, on mount, i.e., immediately following the initial render. For more information, check out the note at the bottom of the Optimizing Performance section of the Effect Hook doc.

But, we’re not done, yet! While the Effect Hook helps us avoid extraneous attribute resetting on every render, it will still run every time the edit screen is loaded. To ensure we only run it once, right when the block is created, we’ll perform a quick check via if statement to see if the ID attribute has already been set.

1.2. Frontend Rendering

Now, we’re getting into the actual frontend display of our block, but before we get into the fun (tricky? mind-melting?) stuff, we need to ensure we’re building a dynamic block.

Luckily, that’s as simple as returning null in our block’s save function (as shown in the previous step), which instructs WordPress to save the block’s attributes without any markup. Without this step, frontend edits to our block could break it, causing a validation message like, “This block appears to have been modified externally,” the next time we try to edit our post in the admin.

Of course, returning null means our block no longer appears on the frontend at all. So, we need to handle its rendering another way… with PHP! To do this, we’ll provide a render_callback function when calling register_block_type() for our block, like below:

View the code on Gist.

This callback function receives an array of the block’s attributes and returns a string of HTML representing our block. For the most part, the HTML output here should mirror the JSX we’d use to display the block with React.

For the purposes of frontend editing, there are two important data attributes we need to output in our block wrapper:

  • id – The block ID attribute we created above.
  • post_id – The current post (or page or CPT) ID.

Note: It’s a good idea to pass any other block attributes you’ll need as additional data attributes to help with rendering your block in React later on.

2. Frontend React

At this point, our (currently static) block should be displaying on the frontend. Phew! Next, we’re going to tackle re-rendering our block with JavaScript and JSX by implementing the following steps:

  • Frontend React component
  • Static block replacement

2.1. Frontend React Component

For the most part, we’ll want to rely on any components already created for rendering our block in the admin to render it again on the frontend; however, creating a new frontend-only component is useful as an intermediary. So, that’s what we’ll be tackling now.

View the code on Gist.

Here we’re setting up the basic function component that we’ll use as a wrapper to render our block on the frontend. First, we destructure our props to get our dataAttributes, which will be an object created from the data attributes we defined in step 1.2. Given how we’ll be rendering our frontend component, the initial props we receive above won’t update when we change things in our block.

Therefore, if we want to track changes between renders, we’ll need to use the State Hook, useState(), within our new frontend component. In this instance, we’ll be keeping track of our block’s attributes with a single state variable, attributes, as an object; although you’re welcome to refactor your code to use multiple individual state variables instead.

Similar to earlier when we set the block ID in the admin in step 1.1., we’ll again take advantage of useEffect(), passing an empty array, [], as the second argument to apply this effect only once. Here, we’ll override our new state variable, attributes, with the values we were passed via dataAttributes.

This ensures the initial values of our data attributes are reflected in our block’s state. Later, when we actually get into the process of frontend editing, we’ll update this state variable to track any changes to our block attributes (e.g., with an input’s onChange event).

At the bottom of our new frontend component, we need to call our pre-existing components (the ones we used in the admin to display our block). Here, we’re wrapping everything in a React Fragment (<>)  in case we have multiple components to display, but if you only need to call one component, you can remove the wrapping fragment to simplify the return.

2.2. Static Block Replacement

Now that we’ve gotten the basics of our frontend component set up, we need to replace the static HTML block we created in PHP. The code in this section will need to be placed in a new JavaScript file enqueued on the frontend of the site. And, as a bit of foreshadowing, make sure to add wp-api-fetch as a dependency for this new file; this will allow us to use apiFetch() to make our frontend updates later on.

View the code on Gist.

We’ll define the target class for our block, use it to retrieve all instances of our target block with document.querySelectorAll(), then iterate over each instance. For each instance, we’ll extract the block attributes from the data attributes we defined in step 1.2. For some of these data attributes, we may want to parse the values to get the necessary data format. For example, we’ve used parseInt() to retrieve the integer value of the passed post ID.

Then we call wp.element.render(), an abstraction of ReactDOM.render(), which takes two parameters:

  • element: The element to be rendered—our frontend component—to which we pass the variable we just created, attributes, as the dataAttributes property value.
  • target: The DOM container node we want to update—the tracker element—which represents the current instance of our custom block. Note: the element passed will replace all contents of the target container but not the container node itself.

Hooray! Our block is now being displayed dynamically with React on the frontend.

 

Next Steps

We’ve laid the groundwork in preparation for frontend editing with our block. We covered properly identifying a block instance, dynamic block rendering with PHP, then replacing our plain HTML block with a frontend React component. Let’s take a breather before diving into the WordPress Rest API and request fetching in Part 2.

The post How to Enable Frontend Editing with Gutenberg Blocks (Part 1) appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2020/08/04/frontend-editing-gutenberg-blocks-1/feed/ 2 22518
Creating a Global Options Component in Gutenberg https://webdevstudios.com/2018/04/12/creating-a-global-options-component-in-gutenberg/ https://webdevstudios.com/2018/04/12/creating-a-global-options-component-in-gutenberg/#respond Thu, 12 Apr 2018 16:00:40 +0000 https://webdevstudios.com/?p=18285 At WebDevStudios (WDS), we’ve seen many iterations of page builders and page builder-esque tools over the years. I think it’s safe to say that the experimentation began with CMB2 and led us down an exciting path that included a handful of full-fledged page builders and our own custom-built page builder before we finally came to rely Read More Creating a Global Options Component in Gutenberg

The post Creating a Global Options Component in Gutenberg appeared first on WebDevStudios.

]]>
At WebDevStudios (WDS), we’ve seen many iterations of page builders and page builder-esque tools over the years. I think it’s safe to say that the experimentation began with CMB2 and led us down an exciting path that included a handful of full-fledged page builders and our own custom-built page builder before we finally came to rely on Advanced Custom Fields (ACF) as a way to allow clients the freedom to edit, arrange, and customize their pages and posts. While ACF isn’t a page builder per se, its robust customization has given us the ability to present our clients with a similar level of customization found in strict page builders. Now… enter Gutenberg.

Here’s what the CEO of our company, Brad Williams, recently tweeted about it, “WordPress Gutenberg is not a page builder.”

While not a full-fledged page builder, Gutenberg does allow for the type of customization we have been building via ACF for several years. It certainly changes how that customization occurs, and part of our directive here at WDS has been to take what we have built in ACF and transfer it to Gutenberg. So, what is the first stop on the ACF-to-Gutenberg brain train? It’s converting our set of globally-used block options.

Part of what we include with all of our default ACF blocks is a panel of options to allow for some major visual customizations. These options include the usage of a background image, video, or color, customizing the font color, adding animation options and any custom CSS classes that a user may need to further tweak their block once it hits the frontend. As important as it was for us to make sure these options are available to use on all of our Gutenberg blocks, it was also important for us to ensure:

  • The options are easy to include for developers
  • The options exist in one central location to keep our code DRY
  • The options work visually in a Gutenberg block the same way they work currently in an ACF block

Getting Started

My first step was to get completely overwhelmed. Digging into reusable Gutenberg components is no small task. After running through Zac Gordon’s Gutenberg Development course, I was comfortable building blocks and even components in the Inspector Controls panel, but this took on a whole new level. We needed conditional fields and, as stated earlier, a way to keep this code as DRY as possible to avoid simple mistakes from being made when attempting to include the Background Options on a new block.

Our options panel is broken down into separate parts, so it made sense to tackle these one at a time rather than trying to do all of the things in one sitting. We’ve broken down the various options into:

  • Background Options
  • Text Options
  • Other Options

For the sake of this post, we’ll be focusing on Background Options. Before we get into the code, take a look at the file structure for our component.
View the code on Gist.

Let’s start by looking at what lives in our outlier JavaScript files, because their contents will be what makes the rest of our component work.

First, we have attributes.js. Like any regular Gutenberg block, our component needs attributes to save when its values are edited. We broke this out into an individual file because it would help keep our index.js file clean, and it makes it easier to import our attributes into our blocks later on. Inside of our attributes.js file we have:
View the code on Gist.

What we’re doing here is setting our default attribute types and then exporting the entire set of attributes for use later on. Now if we ever need to update our Background Options attributes, we won’t have to edit them across all of our various blocks. We’ll just edit them once here and let them trickle down into our blocks wherever they are being used.

Next up is our classes.js file. Neither classes.js, inline-styles.js, or video.js are required by Gutenberg; these are files that will drive markup for functionality for us later on when we begin building our blocks. In classes.js, we’re checking to see which Background Type is selected (image, video, color, or none) and adding a matching class to our block:
View the code on Gist.

In inline-styles.js, we’re doing a similar thing as in classes.js . We’re checking to see which Background Type has been selected and then pulling in its value as an inline style. Specifically, this checks to see if we are using a background color or a background image and sets that value as an inline style on our parent container if either is found:
View the code on Gist.

Finally, our video.js file outputs the video selected when using the “video” Background Type. Since we can’t set a video to be a background element of a container the same way we can with a color or image, we have to output the video markup in the container and then position everything via CSS. Inside of our video.js file is where we’ll keep the markup for our video output:
View the code on Gist.

With that out of the way, it’s time to start building the functionality of our component. The first thing we need to do in our index.js file is import any core WordPress and Gutenberg dependencies we’ll be using. These will vary slightly from component to component depending on what types of fields you’ll be using, but for us, we wound up with:
View the code on Gist.

In order to keep our main file clean, as noted above, we broke out as many things as possible into individual files. Next, we have to import them into the index.js file and export them so we can use them later on in our individual blocks. That last part will make sense once we get into creating a block. For now, let’s just assume you trust me, we import and export our internal dependencies like so:
View the code on Gist.

Now, we can actually get into the nitty-gritty of building out the functionality for our Background Options component. First, we need to create a new function and export it so we can use it in our blocks:
View the code on Gist.

Note that we’re passing in props —this is important because we’re going to be using these to check, get, and set attributes throughout this function. Before we get into any of that, though, let’s set some variables for our various event listeners so we have something to hook into when we want to change the background color, background image, or anything else we’ll be customizing in this function:
View the code on Gist.

Now, it’s time for the fun stuff! The first piece of the puzzle we’ll be building out is our Background Image Selector. Let’s kick this off:
View the code on Gist.

Before we do anything, let’s check to see which Background Type has been selected. If the user has selected the “video” Background Type, then there’s no point in displaying the Background Image Selector.
View the code on Gist.

Now that we know for sure whether or not we’re actually selecting an image, we can build out some further functionality. With this next bit of code, we want to check to see if we have a background image already set. If we do, then we don’t need to display the MediaUpload component. But, if we’re starting fresh and want to select an image, then we definitely need that component handy. This utilizes the core Gutenberg MediaUpload component that we imported way at the top of this file:
View the code on Gist.

But, what if we already have an image? In that case, we want to display the image we’ve already uploaded as well as a way to remove it and replace it with a new image:
View the code on Gist.

Since this comes after our first conditional check, we don’t need to check whether or not an image is already set. If we’ve made it this far in our function, then we know we already have an image saved and are safe to try and output the saved image.

Next, let’s prepare our Video Background Selector. The code here is going to look somewhat similar to the Image Selector we just built, but of course, there are little touches here and there that make it its own special thing. It begins just the same way by setting a const:
View the code on Gist.

Just as we did with the image, let’s check which Background Type has been selected before proceeding:
View the code on Gist.

Now, we need to see if we have a video saved already. This is pretty darn identical to our Image Selector above, except it’s specifying “video” as the value for “type” in the MediaUpload component:
View the code on Gist.

We want our users to know which video they’ve uploaded to a particular block. So if a video is already set, we’re going to display a non-playing version of it in our component:
View the code on Gist.

Finally, we want to be able to select a background color if the “color” Background Type is selected. Just like with the two previous examples, let’s start things by setting a const for our Color Selector:
View the code on Gist.

This particular selector is going to be a lot more streamlined, as we don’t have to worry about including an uploader or outputting anything visually in our component that doesn’t already come from core Gutenberg. First things first, let’s check our background type:
View the code on Gist.

And if we know that we’re looking to set a background color, then we know that we need to display Gutenberg’s PanelColor and ColorPalette components:
View the code on Gist.

We’re almost there! At this point, we’ve created the core functionality of all three of our Background Types: image, video, and color. But, how do we actually tell our component which one of these options we want to use? And how do we actually get any of this stuff to show up in our Inspector Controls panel?

To start, we’re going to veer from what we’ve been doing so far and simply return rather than setting a const. At this point, we’re actually beginning to output the contents of our component rather than building its individual parts. First, we need to start a PanelBody container:
View the code on Gist.

Inside of PanelBody , we want to have unique rows. One will house the Background Type select while the other will house the output for whichever value we have selected. Each of these will live inside of a core Gutenberg PanelRow component. For our Background Type selector, we’ll need to build a selector dropdown and, lucky for us, we can use another core Gutenberg component! We also want this particular option to be visible regardless of the selected Background Type because we want to give our users the ability to change Background Type at any time.
View the code on Gist.

Gutenberg really comes through and makes this easy for us. We’re simply creating a select dropdown and specifying the labels and values for each of our options. Remember all of the conditionals we set earlier in our function where we checked for backgroundType? This SelectControl is what sets the backgroundType value and allows those conditionals to work. Make sure your value for each of these match up to what you’re going to be checking for elsewhere in your functions.

Lastly, we need a way to set our background image, video, or color. Remember when we created our const variables above and did all of the work of setting our image, video, and color values? The reason we set those as const variables the way we did is so we could create a cleaner output in this return. Just below the PanelRow we created for the Background Type selector, create another PanelRow to output our settings:
View the code on Gist.

You might be yelling at me right now that this won’t work—that we’re simply outputting all three of these individual Selectors with no rhyme or reason. Untrue! If you recall, when we set our const variables above, we also checked to see if the selected Background Type matched the type of Selector we were about to display. Inside of all of those const variables, we’re already checking to see which Background Type is set and either bailing if we don’t have a match or displaying the settings if we do. Checking inside of the const lets us keep a very clean and streamlined render at the end of our function.

To see the full version of this file, check out the Gist here!

If you’re still with me… good! We just have a few more things to do before we can see this sucker when editing a block. So far, we’ve built the functionality out but have yet to add it to a block. We’ll do that next. I won’t go over how to build the entire block, because that’s a blog post for another day. If you want to see the end product of what we have in our Default Block as it stands now, you can view that here.

For our purposes, we’ll assume you have the block built already and are looking to add a Background Options panel to your block.

First, we need to make sure you’re importing InspectorControls from Gutenberg core in addition to whatever other blocks you’re importing:
View the code on Gist.

Remember back in our Background Options index.js file when we imported our attributes.js, classes.js, inline-styles.js, and video.js files then immediately exported them? We did that so we could easily and cleanly import all of our necessary Background Options pieces in one line:
View the code on Gist.

With that one line, we’re gaining access to the entire BackgroundOptions function we built as well as all of the goodies that we’re using to make our magic happen. Now, we need to actually begin including those things in our blocks. The first step is to include our attributes. Like I’ve said before, we strive to keep our code as DRY as possible and this was no exception. We didn’t want our developers to have to copy and paste a complete set of attributes every single time they created a new block, and we especially didn’t want to have to update a bunch of different files if our attributes changed at any point in the future.

The beautiful thing here is that with another sweet, single line we can import all of our attributes:
View the code on Gist.

Next, we need to actually output our options panel. This happens inside of the edit function of our Gutenberg block and, again, by utilizing exports and imports we’ve made the process super easy. First, we check to see if our block is in focus and, if it is, we add our InspectorControls panels:
View the code on Gist.

Again, with that single line, we’re pulling in all of our BackgroundOptions functionality and passing in our props so we’ll have access to them in our component. This is really what makes the whole thing work. Without those few lines, we won’t have anything displayed in our InspectorControls panel.

Finally, we need to output some markup so our block will listen for our Background Options and behave accordingly. For the next section, just know that you will have to output the same markup in both your edit and save functions to ensure your block functions properly and displays your options on both the frontend and backend.

We’re using a section tag to wrap our block, and because we want to add a class and potentially inline styles based on our Background Options choices, we’ll need to tell our markup to do just that:
View the code on Gist.

With those in place, we’ll now be able to see the background image or background color set for our block when using the “image” or “color” Background Type. But, what if we’ve selected “video” and have uploaded a beautiful MP4 to display in the background? Easy! We just need to display our video output using the import from the top of our block.
View the code on Gist.

To see the full version of this file, check out the Gist here.

And that’s it!

I know, I know… “that’s it.” There’s a lot to digest here. A lot of this may have been overwhelming to read (it was overwhelming to write, too!), but I would encourage you to do exactly what I did when I started building this component. Do it wrong, get confused, and then start over. When I first started trying to build the Background Options component, I did it by starting with some code Jeffrey de Wit wrote. I had a hard time understanding what he was doing or why it was working. So, I broke everything down to its simplest form. Instead of going all out and building the entire Background Options panel, I started with just the Background Type select dropdown so that I could understand how values were passed between files and functions and just how everything worked at its core.

Once I had an understanding of that one component, I was able to piece everything else together in my brain to make it work. Along the way, I had some help from Eric Fuller, a noted JavaScript guru around these parts, who helped me break everything out into individual files and keep things as smartly-written as possible.

After the Background Options were taken care of, building the Text Options and Other Options panels were a bit of a breeze. They are far less complex than dealing all that came with building the Background Options panel, so they came together much more easily. As always, you can follow along with the progress of our WDS Blocks plugin and check out how we’re handling our other global components in our Github repo.

What brave, new worlds have you come across when getting to know Gutenberg? What have you built that seemed crazy at first, but wound up being completely worth the confusion and frustration that comes with trying to do something outside of your comfort zone? And, what are you looking forward to in Gutenberg as its inclusion in WordPress core gets closer and closer? Let us know in the comments below.

The post Creating a Global Options Component in Gutenberg appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2018/04/12/creating-a-global-options-component-in-gutenberg/feed/ 0 18285
How Existing Content Will Be Affected by Gutenberg WordPress Editor https://webdevstudios.com/2018/01/02/existing-content-affected-wordpress-gutenberg/ https://webdevstudios.com/2018/01/02/existing-content-affected-wordpress-gutenberg/#comments Tue, 02 Jan 2018 17:00:17 +0000 https://webdevstudios.com/?p=17797 By now, you’ve likely heard about something different coming to your WordPress website called Gutenberg—a new way in which you will edit your website using a concept of data blocks. I think it’s safe to say that the Gutenberg WordPress editor is the single largest change to the open-source platform since… heck, I can’t think of anything Read More How Existing Content Will Be Affected by Gutenberg WordPress Editor

The post How Existing Content Will Be Affected by Gutenberg WordPress Editor appeared first on WebDevStudios.

]]>
By now, you’ve likely heard about something different coming to your WordPress website called Gutenberg—a new way in which you will edit your website using a concept of data blocks. I think it’s safe to say that the Gutenberg WordPress editor is the single largest change to the open-source platform since… heck, I can’t think of anything as a close second. This. Is. Big. So, let’s take a look at it and how this change will affect your existing content.

But First… an Overview

The Gutenberg editor will completely replace the current post editor you have been using with your standard WordPress installation. In other words, creating content in WordPress is going to be a whole new experience with Gutenberg. For example, if you’re creating a blog post, you may start with a block of text. Then you add a block that contains an image, and then you add another block of text. Each block can then be edited individually, including the order in which the blocks are displayed.

Two Disclaimers

There are two things I want to make clear before we go any further:

  1. Until recently, I would have said the Gutenberg WordPress editor is a way of editing the content on your website, but as I’ve learned, the longterm plans for it involve the ability to edit all aspects of your website.
  2. WordPress’ Gutenberg is still in active development and isn’t planned to be ready until at least April 2018. It’s important to remember that things will continue to change, even after you’ve read this blog post. Gutenberg will get better itself and third-party themes and plugins will get better at integrating with it.

For now, though, we’re only going to focus on how the Gutenberg editor affects the existing content on your website with a standard WordPress installation (not page builders; we’ll cover that another time). Now, let’s dig in.

Converting Content To Blocks

After you install the Gutenberg plugin, when you edit a page, you’re going to see the new editor. By default, Gutenberg will treat all of the existing content on the page as a single HTML block. As you can see from the screenshot, you have the ability to leave the page as-is and simply edit the page as HTML. This may be fine for users who are comfortable editing raw HTML, but that’s not why we’re here now, is it?

Just below the “Edit as HTML” menu item is another important item: “Convert to blocks.” When clicked, this button will convert all of the content into individual blocks.

Before Converting to blocks

If your page contains nothing but paragraphs of text, each paragraph will become its own block of text. If you have mixed content, like in the “Contact Us” page example, the text and shortcodes each became their own individual blocks. As you can see, the shortcode is now clearly defined and I can edit it, or any of the text blocks on their own.

After conversion to blocks

While the visual in the admin area has changed, your website visitors won’t see a difference in the content. To them, it will look the exact same as it did before the content conversion.

Editing Individual Blocks

Now that content has been converted into blocks, we have the ability to edit each content block on its own. This is where the true power of the Gutenberg WordPress editor shines.

In this screenshot example, I am editing the top block of text. You can see from the available tools on the right, the font size and color can be modified, but I can also add a background color to the block of text as a whole. Also, I can add a unique CSS Class name to this block, which will make it easy to target for adding additional custom CSS.

Editing a text block in Gutenberg

The list of available editing tools on the righthand side will change based on the type of content you are editing. At the time of this writing, there are 23 different block types including Image, Gallery, Heading, Quote, List, Video and a whole lot more. There are also 35+ simple embed options from different sites (for example, YouTube). You simply drop the embed block where you want it to show up, paste in the YouTube video URL, and you’re all set.

Big Change ≠ Bad Change

In the beginning, I made the mistake of listening to all the complaining on the internet about Gutenberg. It helped form my early impression that Gutenberg was the devil before I had even installed it and given it a try. This was a huge mistake on my part as a large portion of those complaining about it probably haven’t even tried it themselves.

So, before you start looking at alternative platforms to run your website, I’m here to assure you that the sky is not falling. There have been other big changes that have come to WordPress (the Customizer comes to mind) that we all survived. The Gutenberg WordPress editor is a big change. And, most people fear change. I get that.

Many of my concerns were put to rest when I watched this presentation from WordCamp US. I suggest you do the same. Then, set up a copy of your site on a development server and install the Gutenberg plugin. Try it out for yourself.

I’ve only touched the surface of Gutenberg and how it will affect your website. In the weeks and months to come, I will be researching how Gutenberg affects page editors such as Beaver Builder and Visual Composer, and how it affects themes with their own page builders built in, such as Divi. There’s no need to fear change, but being prepared and informed is definitely a smart move!

The post How Existing Content Will Be Affected by Gutenberg WordPress Editor appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2018/01/02/existing-content-affected-wordpress-gutenberg/feed/ 14 17797
Preparing for Gutenberg https://webdevstudios.com/2017/08/03/preparing-for-gutenberg/ https://webdevstudios.com/2017/08/03/preparing-for-gutenberg/#respond Thu, 03 Aug 2017 16:00:06 +0000 https://webdevstudios.com/?p=17413 Your WordPress editor is about to get a makeover! While the details aren’t complete yet, we know that soon, the way we edit our content in WordPress is going to change. It’s called the Gutenberg Editor, and the time has come for you to prepare for it. Typically when you log into your website, you go Read More Preparing for Gutenberg

The post Preparing for Gutenberg appeared first on WebDevStudios.

]]>
Your WordPress editor is about to get a makeover! While the details aren’t complete yet, we know that soon, the way we edit our content in WordPress is going to change. It’s called the Gutenberg Editor, and the time has come for you to prepare for it.

Typically when you log into your website, you go to a Post, Page, or other “thing” to add or edit text, images, and more. Central to your website experience is a the big blank Text Editor. Most of the stuff you want to show your users goes into this Text Editor. If your site has a bit more customization, you’ll have extra meta boxes to add extra bits of information and content. Whether it’s for SEO or linking to related resources, these meta boxes aren’t always displayed in the editor where they show up in your content. Heck, sometimes they don’t even show up in your content at all.

When you think about, it’s not the most intuitive way to deal with your content. How did we end up here? Years ago, the WordPress admin interface was revolutionary, if you wanted to publish and still own your content. Instead of having to learn HTML, you could simply enter a username/password, write, and show the world—totally friction-less. Just type, publish, and it went live.

As website complexity has grown and site owners have figured out how visitors use websites, our understanding of content has expanded well beyond just a wall of text and a picture. Content, these days, can be relationships to other posts and products, supporting images, sales pipelines, tutorials, forms, and a billion other things. Essentially, web publishing has outgrown the humble Text Editor view. WordPress agencies and plugin developers have been dealing with this by bolting on meta boxes as needed.

WordPress core developers see this Frankenstein approach as problematic. The solution is Gutenberg. Named after Johannes Gutenberg, who invented a printing press with movable type more than 500 years ago, the Gutenberg Editor is very much beta software. Each point (0.0.x) release of Gutenberg has significant changes and improvements over the previous, so it’s difficult at this point to see where it will end up. Because the developers are seeking active feedback, each update polishes the user experience a bit more. However, we’re still months from Gutenberg being part of WordPress core. So, expect many more changes before all the dust settles.

Gutenberg is an attempt to make the editing experience feel a bit more logical. This is accomplished by treating everything as a block. Ideally, this will make the task of creating content much more intuitive (and heck maybe even fun?). One of the biggest changes that hasn’t been accounted for in Gutenberg is what to do with all of the “legacy meta boxes.” In some cases, they’ll make sense as a block that is added to the content. But some meta isn’t necessarily something you’ll need to display. That kind of content doesn’t fit in the Gutenberg block model.

We expect Gutenberg will ship in WordPress 5.0. That’ll probably be in the second quarter of 2018. In the meantime, it will be important to stay on top of both WordPress core and plugin updates as some of the groundwork for dealing with Gutenberg will be laid before it’s available in the backend. Start thinking about the metadata you use in your posts. Unlike when Facebook changes the interface, WordPress is giving us a huge amount of notice. If you need help in either of these areas, reach out to experts at Maintainn. They’re actively preparing for Gutenberg and are fluent in all things WordPress.


Photo by Bruno Martins on Unsplash

The post Preparing for Gutenberg appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2017/08/03/preparing-for-gutenberg/feed/ 0 17413