Blog posts under the block tag https://webdevstudios.com/tags/block/ WordPress Design and Development Agency Mon, 15 Apr 2024 15:57:35 +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 block tag https://webdevstudios.com/tags/block/ 32 32 58379230 We Built a Custom Gutenberg Block for a CPG Client https://webdevstudios.com/2022/09/06/custom-gutenberg-block-cpg/ https://webdevstudios.com/2022/09/06/custom-gutenberg-block-cpg/#respond Tue, 06 Sep 2022 16:00:18 +0000 https://webdevstudios.com/?p=25380 Early this year, one of our consumer packaged goods (CPG) clients came to us needing a new custom Gutenberg block. They were in the process of creating a new marketing campaign landing page and wanted to feature recipes by collection. This functionality existed on the custom taxonomy recipe collection archive pages where editors could add Read More We Built a Custom Gutenberg Block for a CPG Client

The post We Built a Custom Gutenberg Block for a CPG Client appeared first on WebDevStudios.

]]>
Early this year, one of our consumer packaged goods (CPG) clients came to us needing a new custom Gutenberg block. They were in the process of creating a new marketing campaign landing page and wanted to feature recipes by collection.

This functionality existed on the custom taxonomy recipe collection archive pages where editors could add individual recipes to the collection sections and drag and drop the recipes in the order they wanted them to appear. However, they were not able to add the same functionality to a page (in the WordPress sense).

We needed to give editors the ability to add a recipe collection section to a regular page. Adapting the existing functionality into a custom Gutenberg block gave our client the ability to create the pages they needed for their upcoming campaign.

Recipe Collection Block Front End

Block Functionality Needs

On the campaign page our client was creating, they wanted to showcase a collection of recipes in any order they wanted. They wanted a Load More button in case there was more than one row of recipes. The user could choose to see them or not.

Our client also wanted a button that linked to the recipe collection term archive page. Since the functionality existed in another part of the site, I looked at how it was built to inform how to create the new Gutenberg block.

Custom Recipe Collection Block

Enter the custom recipe collection block. Creating a custom Gutenberg block meant our client could add the recipe collection section to any page, post, or custom post type, on any part of the site.

In the admin, editors are able to set the block’s title and description and use a dropdown to select their desired recipe collection term. When the recipe collection term is selected, the block title and description automatically populate with the term name and description. Both the block title and description can be manually overridden if the editor chooses.

Recipe Collection Block Admin

Once the recipe collection is chosen, recipes are individually selected and added to the block. When recipes are added manually, only those recipes are displayed in this custom Gutenberg block.

The recipes may be dragged and dropped into the order they should appear. The order in which the recipes are arranged is the order in which they display in the collection block.

If no recipes are selected, then all recipes from the collection are listed and sorted by rating. The block also allows the user to toggle between displaying a button that links to the recipe collection archive.

Need a Custom Gutenberg Block on Your Website?

While this particular solution was developed for a CPG client, any company in any industry benefits from the specialized functions of a custom Gutenberg block. When you find yourself in need of one on your site, contact WebDevStudios.

The post We Built a Custom Gutenberg Block for a CPG Client appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2022/09/06/custom-gutenberg-block-cpg/feed/ 0 25380
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
Gutenberg Filters: registerBlockStyle https://webdevstudios.com/2020/04/30/gutenberg-filters-registerblockstyle/ https://webdevstudios.com/2020/04/30/gutenberg-filters-registerblockstyle/#comments Thu, 30 Apr 2020 16:00:17 +0000 https://webdevstudios.com/?p=21454 One of my favorite ways to customize a Gutenberg block is by utilizing registerBlockStyle. It’s a simple Gutenberg filter that can improve styling in the editor or frontend by adding a class name when the Block Style is selected. Not only is this feature quick to set up, it’s a user-friendly way interface for customizing Read More Gutenberg Filters: registerBlockStyle

The post Gutenberg Filters: registerBlockStyle appeared first on WebDevStudios.

]]>
One of my favorite ways to customize a Gutenberg block is by utilizing registerBlockStyle. It’s a simple Gutenberg filter that can improve styling in the editor or frontend by adding a class name when the Block Style is selected. Not only is this feature quick to set up, it’s a user-friendly way interface for customizing a block.

Fancy Quote block style
Custom style registered on the core/quote block.

Understanding Register Block Style Function

Before going too far, let’s take a look at how we can register a block style by checking out the parameters in the source code.

View the code on Gist.

blockName: Name of block (example: “core/quote”).

styleVariation: An object containing a name and label property.

Name Property: The name value for the object being passed in is a unique lowercase hyphenated string. This is the string that will be rendered in the block class name attribute. WordPress will render this by default as “is-style-” followed by the provided value.

Label Property: The label value is a string that will display underneath the block style in the editor.

Creating a Register Block Style Filter

Here, we’re registering a filter that will add a block style variation named “Fancy Quote” to the quote block. This will set up a new style on the block in the editor. When the “Fancy Quote” style is selected the class name .is-style-fancy-quote will be applied to the wrapper element of the block. Next, we need to enqueue our Javascript file.

View the code on Gist.

Enqueuing the Filter

For this filter to work, it’s important that we make sure the JavaScript file we created is enqueued into the editor. If you’re unsure how to enqueue a file, check out Enqueuing Block Scripts from the Gutenberg handbook.

View the code on Gist.

Verifying the Filter Works

Fancy Quote block frontend

Now that the file is enqueued, it’s time to verify that everything works as expected.

  1. Verify that the expected change happens in the editor.
  2. Check that your class name is visible in the front end of the site by inspecting the block wrapper element.
  3. Experiment with what happens if the filter is disabled or removed.

Step 3 is very important! Sometimes, a disabled filter can trigger a block recovery in the editor.

Take-Aways

The registerBlockStyle filter is my favorite way to demonstrate what filters can do in the Gutenberg Editor. It’s incredibly simple and can make a big difference when adding custom styles to blocks  in the editor. If you enjoyed this article, check back later for the next article in this series registerBlockType filter.

The post Gutenberg Filters: registerBlockStyle appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2020/04/30/gutenberg-filters-registerblockstyle/feed/ 3 21454