First Gutenberg Project

December 10, 2021

As I mentioned in the weeknote post last week, I recently filled out a questionnaire for my bi-annual review. One of the questions was to discuss an accomplishment that I was most proud of this past six months. My answer was a project I built for GenesisHR.

There are a lot of different reasons why this project stood out to me among the many other projects. But one of the most important reasons is that it was my first site built to incorporate the Gutenberg editor that WordPress introduced in late 2018.

There are several different reasons that I have been hesitant to build a site with Gutenberg. In the interim, I have used the Classic Editor plugin to disable the Gutenberg editor and continued to build sites with Advanced Custom Fields (ACF). But we have been discussing how to give a more premium experience to our clients by making our WordPress builds more flexible so that the client did not have to come back to us as often to have us build new custom features. After looking at the goals of the GenesisHR project, I decided that it was a great candidate to incorporate the Gutenberg editor into.

In this post, I am going to walk through different decisions I made as I built with Gutenberg and share some thoughts at the end about pain points or things I would like to do differently in the future.

Turned off the default Gutenberg styles

One of the first things that I addressed in the functions.php file was to turn off the default Gutenberg styles that are built-in.

function smartwp_remove_wp_block_library_css(){
  wp_dequeue_style( 'wp-block-library' );
  wp_dequeue_style( 'wp-block-library-theme' );
}
add_action( 'wp_enqueue_scripts', 'smartwp_remove_wp_block_library_css' );

I decided to turn off the default styles because I was not planning to use many of the Gutenberg blocks. And when I was, I wanted to create my own styles to match our design and not have to overwrite default styles. By turning off the styles, I removed unneeded code and made the site more performant.

I did have to add some of those default styles back into my stylesheet. But I believe in the end the trade-off was worth it.

This also had the effect of disabling styling that the client could have added to the page through the block editor. I believe a CMS should be focused on content. We have a strategy when we create a design and we don’t want to empower clients to make design or layout decisions that would detract from the hard work that our strategy or design team has put into the project.

Created custom blocks with Advanced Custom Fields

One hesitancy I had in using Gutenberg for this project is that we did not have many repeating components that we reused throughout the design. But in the end, I saw the value of creating components based on the design of the site that could be reused in new ways in the future. I also created some components based on the types of repeatable components that seem to find their way into every project.

One of the barriers to entry for Gutenberg is that WordPress decided to build Gutenberg blocks with React. I do not know React so when I first learned about Gutenberg three years ago, I was a bit discouraged by that choice.

I was excited when the creator of the Advanced Custom Fields plugin announced that he was adding support to the plugin to build custom Gutenberg blocks using ACF. I had already used ACF for years and have always appreciated the ease of use. This tutorial from Torque Magazine walked me through the steps to build my own blocks with ACF.

  • Register your block – involves writing PHP in functions.php file (your define the location of the block template that will render your block in your page template)
  • Create your fields in ACF
  • Create a block template to render your block (these templates are PHP and were not any different than the code I normally write for a WordPress template)

Example of one of the blocks I created and registered in functions.php:

function acf_question_answer_block() {  // check function exists
  if( function_exists('acf_register_block') ) {
    // register a portfolio item block
    acf_register_block(array(
      'name' => 'question-answer-block',
      'title'	=> __('Question and Answer Block'),
      'description' => __('A custom block with heading, subheading and text content.'),
      'render_template' => 'template-parts/blocks/question-answer.php',
      'category' => 'lgnd',
      'icon' => file_get_contents( get_template_directory() . '/dist/question-icon.svg' ),
      'keywords' => array( 'question'),
      'mode' => 'edit',
      'supports' => ['mode' => false],
      'post_types' => array('page')
    ));
  }
}
add_action('acf/init', 'acf_question_answer_block');

As you can see from the code, it is pretty straightforward. I define the rendering template, assign it to a category (see custom block categories below), and can set an icon that will display in the Block Editor interface.

Created custom block categories

I created some custom block categories for this project. Some of the blocks I created were only used on the homepage. Other blocks were used on other pages of the site. And there were some blocks that were only to be used within blog posts.

Screenshot of the custom blocks as displayed in the Block Editor in the WordPress backend.

To create custom block categories, you have to define these categories in the functions.php file. Here is an example from the project:

function filter_block_categories_when_post_provided( $block_categories, $editor_context ) {
  if ( ! empty( $editor_context->post ) ) {
    array_push(
      $block_categories,
      array(
        'slug' => 'genesis-block',
        'title' => __( 'Genesis Blocks', 'custom-plugin' ),
        'icon'  => null,
     )
    );
  }
  return $block_categories;
}
add_filter( 'block_categories_all', 'filter_block_categories_when_post_provided', 10, 2 );

The category slug for the Genesis Homepage Block is lgnd, which you will see referenced in my custom block example.

Displaying  select block categories

I did not want to use most of the prebuilt Gutenberg blocks in this project so I found a way to only show the blocks that I specified. Utilizing the allowed_block_types_all filter, you specify only the blocks you want to be displayed in the WordPress editor. (I had used the allowed_block_types filter when I built the site but I saw that filter has been deprecated as of WP 5.8).

add_filter( 'allowed_block_types', 'lgnd_allowed_block_types' );
function lgnd_allowed_block_types(
 $allowed_blocks ) {
  return array(
    ...
    'acf/video-block'
    'acf/home-hero'
    'acf/secondary-page-hero'
    ...
  };
}

Disabling Gutenberg editor for certain custom post types

When I originally planned to use the Gutenberg editor, I was only going to use it for the blog posts. But after some further thought, I decided to use Gutenberg blocks on other pages of the site. Those pages would have their own defined advanced custom fields but then allow the client to have more flexible content in the bottom portion of each page.

Originally I had found a way to only use the Gutenberg editor for posts. But after deciding to expand my use of Gutenberg, I needed to find a new solution that did not use the Gutenberg editor on several custom post types that I had already built advanced custom fields for content editing on those posts. After searching, I found a new solution that allowed me to use the use_block_editor_for_post_type function to disable the editor for an array of post types.

add_filter('use_block_editor_for_post_type', 'prefix_disable_gutenberg', 10, 2);
function prefix_disable_gutenberg($current_status, $post_type)
{
  if ($post_type === 'testimonial' || $post_type === 'timeline' || $post_type === 'people' || $post_type === 'experts' || $post_type === 'resources') return false;
  return $current_status;
}

Theme support – colors

There was one feature of Gutenberg Block Editor that I wanted to take advantage of. I wanted to define a color palette for the editor to use with the color picker. I utilized this feature on one of my blocks for the homepage where we list the custom solutions that GenesisHR offers. The design called for a different border color for each of the list items which I later expanded to be the background color of the card when the user hovered over it.

By adding editor-color-palette to my functions.php file, I was able to define these colors and have them come up in the color picker as shown below.

// Defining the colors for the palette using variables
$teal = '#0382ac';
$fire = '#F16036';
...
add_theme_support(
  'editor-color-palette',
  array(
    array(
      'name'  => esc_html__( 'Teal', 'genesis-hr' ),
      'slug'  => 'teal',
      'color' => $teal,
    ),
    array(
      'name'  => esc_html__( 'Fire', 'genesis-hr' ),
      'slug'  => 'fire',
      'color' => $fire,
    ),
    ...
  )
);

Styles for WordPress Admin

One thing that I was not pleased with using Gutenberg blocks is the labeling in the WP admin. I decided to solve this problem by adding my own custom styles for the WordPress admin.

// Declaring the location of my custom administrative styles
function admin_style() {
  wp_enqueue_style('admin-styles', get_template_directory_uri().'/css/admin.min.css');
}
add_action('admin_enqueue_scripts', 'admin_style');

I added the name of the block using ::before and also added a border around the Gutenberg blocks as well as a bit more spacing between blocks.

I also added some CSS from my theme so that components like the “Custom Solutions” would display the content similar to what the user would see on the actual page. The Custom Solutions Listing Block did not require any content input on the page that the block was placed on. All the content from that block was pulled from child pages under the Solutions parent page. I created several Gutenberg blocks that did not require any content edits on the page the block was displayed in but pulled content from custom post types. A testimonial block on the homepage is an example of that.

I also added some styling so that the ACF and Yoast blocks had the same amount of horizontal spacing as the Gutenberg blocks.

GenesisHR WP Admin with applied custom admin styles.

WordPress guide incorporated into WP Admin

Over the last several years, I have tried to put together a WordPress guide for each WordPress build so that our clients can understand how they can update or add content to the site. Documentation is one of the harder tasks that I engage in. It is a communication challenge to put into words the right instructions and the right amount of information that will equip the client to feel confident to own the management of their content.

I usually create these guides in a Word or Google document and export it as a PDF. I use a mixture of text and images to help guide the client through the process of creating and updating content. I try to communicate just enough that they have a basic understanding of our custom builds and how they might differ from a typical WordPress build that they might find in any number of tutorials on the Web. I would email or send the PDF in a Slack message.

On a couple of projects last year, I incorporated a link to the PDF document within the WordPress dashboard so that the client would always know how to find it and not have to search through email or Slack to find it. This was always a better approach given the fact that the person responsible for updating the site may change in the future and might not be forwarded those PDF guides.

But my longer-term vision has always been to create a WordPress guide that lives within the WordPress Admin area and would be a series of coded pages that would be more interactive than PDF documents as you could link to different sections more easily or link straight to things like options pages directly in the guide since they are already logged into the admin area. It also gave me the ability to add videos to the guide, which I utilized in this project.

I decided that this was the project that I needed to learn how to build the guide into the WordPress backend. And so I did. It was not difficult. The following is an overview of the process:

  1. Use the admin_menu hook to reference the function to create the pages
  2. Create a function to add the menu page and the subpages under it.
  3. Create the individual guide pages. I created a folder entitled ‘wordpress-guide’ and saved PHP files for each of the pages of the guide
  4. Create functions to link the menu page and subpages in your page definitions.
  5. Add CSS declarations to my custom admin styles for styling and layout of the guide pages

Here is a sample of my functions.php file:

add_action( 'admin_menu', 'wordpress_guide' );
function wordpress_guide() {
  add_menu_page( 'LGND WordPress Guide', 'WordPress Guide', 'manage_options', 'wordpress-guide.php', 'wordpress_page', 'dashicons-wordpress-alt', 20  );
  add_submenu_page( 'wordpress-guide.php', 'Homepage', 'Homepage', 'manage_options', 'homepage', 'wordpress_subpage_home' );
  add_submenu_page( 'wordpress-guide.php', 'Solutions', 'Solutions Page', 'manage_options', 'solutions-landing', 'wordpress_subpage_solutions' );
  ...
}

function wordpress_page() {
  require __DIR__."/wordpress-guide/pages/wordpress-guide.php";
}

function wordpress_subpage_home() {
  require __DIR__."/wordpress-guide/pages/homepage.php";
}

function wordpress_subpage_solutions() {
  require __DIR__."/wordpress-guide/pages/solutions-landing.php";
}

...

I am very happy with how the guide turned out. The client was able to use the guide to make some updates to the site just days after it launched. One of our practices at LGND is to have a meeting with the client to provide WordPress training. We record those Zoom meetings and I was able to add the video of that conversation to the first page of the guide. Putting together the guide was very useful to prepare me for the training. But I knew it would also be a valuable reference to the client. And it took some of the pressure off during that training to cover everything.

Post-Mortem lessons and thoughts

  • There are still things about the Gutenberg editor that don’t function correctly or as expected. The ones that I found were in the block editor and had to do with re-ordering blocks. I made notes in the WordPress guide I created so that the client would know and provided workarounds.
  • An edit page using Gutenberg will place the Gutenberg editor first and then add blocks like ACF and Yoast. My strategy for most of the pages of the GenesisHR site was to have defined content using Advanced Custom Fields and then give flexibility at the bottom of those pages to add Gutenberg blocks. Because of the ordering, the Gutenberg blocks were displayed first, then my defined ACF. I would have preferred to have the ACF blocks display first and then the Gutenberg blocks. I understand why the order is that way (the page title field is part of the Gutenberg editor). But it would be nice to have the flexibility to build pages a little bit differently.
  • I originally wanted to use the group block to create sections on pages. But I was not happy with the group block functionality. I found it difficult to add more than one Gutenberg block within the group block using the visual editor. I decided to abandon the idea of using the group block because I felt it would be too difficult for the client to build out the page.
  • Gutenberg is still in a lot of flux. The WordPress team is still working on it and making changes to how some things work with different WordPress updates. The update from version 5.7 to 5.8 caused me to have to go back and rewrite some code and find different solutions because of the changes the WordPress team made. It makes developing with Gutenberg feel much more fragile knowing that things could break in future updates. I am hoping that the WordPress team can bring more stability to the editor so developers can count on things to continue working into the future.
  • After creating custom blocks with ACF, I can see the value of writing those blocks in React. There is a lot of block functionality that you could tap into coding in React that you cannot do with ACF. Depending on how much I adopt Gutenberg in the future, I may need to set aside some time to learn enough React so that I can customize my blocks a bit more.

Links to resources I bookmarked along the way

Comments are closed.