Introduction

Before the 4th of July 2024, my website (yes, this one) exclusively used the popular WordPress theme Divi. You can read more about this build here.

I’ve had a love-hate relationship with Divi over the years. When I was first learning the ropes of WordPress, I found Divi to be an excellent tool to help me produce attractive websites with minimal effort or front-end development knowledge. At the time, quite a few years ago at this point, it was certainly appropriate.

Fast forwarding to the last few years, I diversified from being a backend developer to labelling myself as full stack. I’d put a lot of hard work into learning about front-end development, design principles, and accessibility standards. Once I reached a point of being confident in these newly found skills, I found I couldn’t bear the look of my website. It was time for something to change.

I will say, anecdote aside, Divi is perfectly capable and known for making beautiful sites. However, I felt no desire to stay with Divi when a custom Block Theme is free, fast, and has come a long way over the last few years. I work with ‘classic’ themes every day in my full-time job, and I felt it was time to try this new approach that WordPress is pushing for so hard.

Now that I’m done, I’ll admit: I enjoyed it.

Why choose a Block Theme over Divi

When considering this question, here are the immediate differences that come to mind when comparing Divi to a custom Block theme:

  • Divi is big and slow.
  • Divi comes with a lot of bloat, as it’s unlikely you’ll use everything it offers.
  • Divi is not free.
  • Block themes are easy to get started with thanks to the ‘Create Block Theme’ plugin from WordPress.
  • Block themes utilise Gutenberg, instead of working against it by shipping with a whole extra editor.

There are, of course, reasons to use Divi instead of a Block Theme, but I won’t be covering that today.

How to rebuild a Divi site with a Block Theme

This is a little bit too complicated to provide a one-size-fits-all answer. Instead, I’m going to lay out some expectations for what it means to rebuild a site with a block theme and outline a generalised list of steps for how I’ve approached this task.

What does rebuilding mean?

Unfortunately, there’s no elegant solution (that I’m aware of) that facilitates ‘converting’ Divi-themed websites into a Block Theme. But that would be pretty awesome.

When I say ‘rebuilding’, I literally mean to build your website again: Open up your current website on one monitor, then remake it on a new site on another monitor.

Depending on the size of your website, this can be a lengthy process. There’s no way around this, sadly. As Divi is a proprietary theme that generates revenue by selling licenses, it’s not in their interest to provide you with an easy way to jump ship. If you want to break free from that grasp, you will have to put in a little bit of work first.

The steps to making a custom Block Theme

Here’s a high-level overview of the steps I’ve taken to rebuild my website using a custom Block Theme. While this will vary for your project in some ways, this should afford you a glimpse as to what you’ll be required to do:

  1. Create a new WordPress installation, or copy your existing one to a development copy.
    • This allows you to work on your new site without having any downtime on your existing one.
    • If you’re unable to work from a staging/development environment, I’d highly encourage you to research this first to ensure it’s something you can do if you intend to do a rebuild like this.
    • Creating a new installation means you’ll lose your content. If you didn’t use Divi throughout your whole website, such as with posts, then migrating your database to the new website might save you some copying and pasting, at the expense of having to remove some Divi shortcodes from various pages.
  2. Install the ‘Create Block Theme’ plugin and use it to create your new Block Theme files.
  3. If you’re recreating the site one-to-one, then you can use the old site as a design to follow. If not, you should consider doing your redesign in a different tool such as Figma, before then starting to make code changes.

Creating reusable Gutenberg Blocks

Within Divi, you can save reusable blocks and then place them throughout your page templates. Luckily, you can do the exact same thing in a custom Block Theme.

  1. Design your block within Gutenberg.
  2. Right-click the block in the list view on the left, and select ‘Create pattern’:
  3. Enter the name for your pattern. If you’d like changes to reflect everywhere the block is used, select ‘Synced’.
  4. To add one of your patterns, use the ‘Patterns’ category of the addition menu, then navigate to the patterns you created.

Adding code to the site’s header/body in a Block Theme

Divi provides the option to easily add code to the website’s header and body, right from the admin menu:

A screenshot of the integrations Divi theme options screen.
A screenshot of the integrations Divi theme options screen.

Sadly, you can’t replicate this behaviour from the Admin panels in a Block Theme without installing a plugin. You can, however, enqueue scripts from your theme’s code via a little PHP:

<?php

namespace jackwhitworth\hooks;


if ( !defined('tagManagerCookiesHead') ) {
    /**
     * Loads the inline content for GTM and the Cookie banner in the head tag
     */
    function tagManagerCookiesHead(): void
    {
        require(JW_PATH . '/partials/gtm-head.php');
        require(JW_PATH . '/partials/cookies-head.php');
    }
    \add_action('wp_head', '\jackwhitworth\hooks\tagManagerCookiesHead');
}

if ( !defined('tagManagerBody') ) {
    /**
     * Loads the inline content for GTM and the Cookie banner after the body tag
     */
    function tagManagerCookiesBody(): void
    {
        require(JW_PATH . '/partials/gtm-body.php');
        require(JW_PATH . '/partials/cookies-body.php');
    }
    \add_action('wp_body_open', '\jackwhitworth\hooks\tagManagerCookiesBody');
}

In the above code, which is located in jackwhitworth/includes/hooks/gtm.php (Where jackwhitworth is the name of my theme), is included in the theme’s functions.php file. When this runs, the two functions tagManagerCookiesHead and tagManagerCookiesBody are both defined and then assigned to the wp_head and wp_body_open actions.

These functions then load in some template partials from jackwhitworth/partials/*. Here’s an example of what these files contain:

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-5L34BMNF');</script>
<!-- End Google Tag Manager -->

This is gtm-head.php. As you can see, it’s just the HTML which I want to be added to the website’s head. With all of this in place, when you inspect the source code of the website, you’ll then see the GTM code in place as you’d expect:

A screenshot showing GTM code in the head of my website which uses a custom block theme.
A screenshot showing GTM code in the head of my website which uses a custom block theme.

This approach can be expanded upon and used to add any code to the head and body tags of your website with ease.

Using templates for different archives and post types

In Divi, there’s a menu called ‘Theme Builder’. This allows you to create templates which are used as default views for different types of content. This same approach can be taken when using a Block Theme.

To find the equivalent menu in a Block Theme, go to ‘Appearance’ > ‘Editor’ > ‘Templates’.

A screenshot showing the templates menu for Block Themes.
A screenshot showing the templates menu for Block Themes.

Using the ‘+’ at the top, you can add templates for the different post types and archives. There are many resources for learning how this all works, so I won’t go into lots of detail here. What it interesting to know about is the ‘CUSTOM’ category that I’ve circled in the above screenshot.

While all standard post types and archives are accommodated within the default set of templates, if you have any custom post types then you’ll need to set up custom templates for them. As Divi ships with a custom post type called ‘Projects’ by default, I manually recreated it for my rebuild and then had to set up these templates to get everything working.

As you can see, the names of the custom templates are as follows:

  • Archives: archive-{post_type_slug}
  • Single Page: single-{post_type_slug}
  • Taxonomies: taxonomy-{taxonomy_slug}

Restoring Divi’s Projects post type for your Block Theme

Divi ships with a custom post type called ‘Projects’ by default. If you never utilised it, then this won’t be important. However, if you did utilise them and you wanted to still have your projects available in your new custom Block Theme, you’ll need to restore/recreate the post type manually.

There are two main approaches that I’d utilise for this:

  1. Create the post type and taxonomy via PHP code in your theme.
  2. Create the post type and taxonomy via the Advanced Custom Fields (ACF) plugin.
ACF JSON for Projects post type.

Projects post type

{
    "key": "post_type_6682be989e694",
    "title": "Projects",
    "menu_order": 0,
    "active": true,
    "post_type": "project",
    "advanced_configuration": true,
    "import_source": "",
    "import_date": "",
    "labels": {
        "name": "Projects",
        "singular_name": "Project",
        "menu_name": "Projects",
        "all_items": "All Projects",
        "edit_item": "Edit Project",
        "view_item": "View Project",
        "view_items": "View Projects",
        "add_new_item": "Add New Project",
        "add_new": "Add New Project",
        "new_item": "New Project",
        "parent_item_colon": "Parent Project:",
        "search_items": "Search Projects",
        "not_found": "No projects found",
        "not_found_in_trash": "No projects found in the bin",
        "archives": "Project Archives",
        "attributes": "Project Attributes",
        "featured_image": "",
        "set_featured_image": "",
        "remove_featured_image": "",
        "use_featured_image": "",
        "insert_into_item": "Insert into project",
        "uploaded_to_this_item": "Uploaded to this project",
        "filter_items_list": "Filter projects list",
        "filter_by_date": "Filter projects by date",
        "items_list_navigation": "Projects list navigation",
        "items_list": "Projects list",
        "item_published": "Project published.",
        "item_published_privately": "Project published privately.",
        "item_reverted_to_draft": "Project reverted to draft.",
        "item_scheduled": "Project scheduled.",
        "item_updated": "Project updated.",
        "item_link": "Project Link",
        "item_link_description": "A link to a project."
    },
    "description": "",
    "public": true,
    "hierarchical": true,
    "exclude_from_search": false,
    "publicly_queryable": true,
    "show_ui": true,
    "show_in_menu": true,
    "admin_menu_parent": "",
    "show_in_admin_bar": true,
    "show_in_nav_menus": true,
    "show_in_rest": true,
    "rest_base": "",
    "rest_namespace": "wp\/v2",
    "rest_controller_class": "WP_REST_Posts_Controller",
    "menu_position": "",
    "menu_icon": {
        "type": "dashicons",
        "value": "dashicons-admin-post"
    },
    "rename_capabilities": false,
    "singular_capability_name": "post",
    "plural_capability_name": "posts",
    "supports": [
        "title",
        "editor",
        "thumbnail",
        "custom-fields"
    ],
    "taxonomies": [
        "project-tag"
    ],
    "has_archive": true,
    "has_archive_slug": "projects",
    "rewrite": {
        "permalink_rewrite": "post_type_key",
        "with_front": "0",
        "feeds": "0",
        "pages": "1"
    },
    "query_var": "post_type_key",
    "query_var_name": "",
    "can_export": true,
    "delete_with_user": false,
    "register_meta_box_cb": "",
    "enter_title_here": "",
    "modified": 1719927128
}
ACF JSON for Project tags taxonomy.

Project Tag taxonomy

{
    "key": "taxonomy_6683ff4230eba",
    "title": "Project Tags",
    "menu_order": 0,
    "active": true,
    "taxonomy": "project-tag",
    "object_type": [
        "project"
    ],
    "advanced_configuration": 1,
    "import_source": "",
    "import_date": "",
    "labels": {
        "name": "Project Tags",
        "singular_name": "Project Tag",
        "menu_name": "Project Tags",
        "all_items": "All Project Tags",
        "edit_item": "Edit Project Tag",
        "view_item": "View Project Tag",
        "update_item": "Update Project Tag",
        "add_new_item": "Add New Project Tag",
        "new_item_name": "New Project Tag Name",
        "search_items": "Search Project Tags",
        "popular_items": "Popular Project Tags",
        "separate_items_with_commas": "Separate project tags with commas",
        "add_or_remove_items": "Add or remove project tags",
        "choose_from_most_used": "Choose from the most used project tags",
        "most_used": "",
        "not_found": "No project tags found",
        "no_terms": "No project tags",
        "name_field_description": "",
        "slug_field_description": "",
        "desc_field_description": "",
        "items_list_navigation": "Project Tags list navigation",
        "items_list": "Project Tags list",
        "back_to_items": "← Go to project tags",
        "item_link": "Project Tag Link",
        "item_link_description": "A link to a project tag"
    },
    "description": "",
    "capabilities": {
        "manage_terms": "manage_categories",
        "edit_terms": "manage_categories",
        "delete_terms": "manage_categories",
        "assign_terms": "edit_posts"
    },
    "public": 1,
    "publicly_queryable": 1,
    "hierarchical": 0,
    "show_ui": 1,
    "show_in_menu": 1,
    "show_in_nav_menus": 1,
    "show_in_rest": 1,
    "rest_base": "",
    "rest_namespace": "wp\/v2",
    "rest_controller_class": "WP_REST_Terms_Controller",
    "show_tagcloud": 1,
    "show_in_quick_edit": 1,
    "show_admin_column": 0,
    "rewrite": {
        "permalink_rewrite": "custom_permalink",
        "slug": "projects\/tags",
        "with_front": "0",
        "rewrite_hierarchical": "0"
    },
    "query_var": "post_type_key",
    "query_var_name": "",
    "default_term": {
        "default_term_enabled": "0"
    },
    "sort": 1,
    "meta_box": "default",
    "meta_box_cb": "",
    "meta_box_sanitize_cb": "",
    "modified": 1719935203
}

You can use these JSON files to import the post types via ACF, should you wish to use this approach.

These are set up to show the Projects at the /project/{project_slug} endpoint, and the taxonomy will be at the /project-tag/{project_tag_slug} endpoint. If you’re curious to see how this works, you can navigate the projects on my website which utilise this approach.

Because the slug for this custom post type matches Divi’s, you’ll find that any existing Projects in your database will be restored.

Removing Divi shortcode from pages which used the Divi Builder

Sadly, there’s no quick way to go about this. I found that I simply had to delete all of the shortcode and page content for any pages built with the Divi Builder, then recreate them manually within the Gutenberg editor.

If you used the Gutenberg editor for any content on your old Divi site, this should work straight away without the need for amendments.

Conclusion

While this post was a little bit un-structured, I hope that there have been some useful information here for you as you contemplate/start rebuilding your Divi site with a custom block theme.

If there’s anything I’ve missed, or if you have any questions on this topic, please feel free to leave a comment below or send me a message via my contact form.

Leave a Reply

Your email address will not be published. Required fields are marked *