The (Gutenberg) block editor is undoubtedly the center of modern WordPress. With full site editing on its way to WordPress Core, blocks and all they promise are here to stay.
However, blocks don’t always do what we want or look the way we like. If you design and build sites for a living, you know that cookie-cutter stuff only goes so far on the web. At some point, we need that “block” on the page to look or behave in a really particular way.
Custom blocks are the solution here! But custom blocks require, for many folks who’ve been rolling in WordPress for a while, a very different approach to dev.
I’m going to show you how you can easily build a completely custom block. And it’s gonna take about 10 minutes. For any freelancer or agency crew here wanting to skill-up around the block editor, I think you’ll like this!
Let’s imagine we’re working on a project and a designer hands us a sweet design for an eCommerce website. It uses the best of WordPress + WooCommerce, but there are a few pieces that just don’t work off the shelf. One of these is this right here:
Holup! This looks familiar! 😉
Yep, we’re gonna rebuild the Flywheel pricing table as a custom block. 🔥 There are plug-n-play pricing table blocks around, but ours here is pretty unique, so we’re going to roll our own.
- Fresh WordPress install – compliments of Local
- Genesis Custom Blocks (free one) installed and active
- A child theme for the Genesis Block Theme
Important Note: Genesis Custom Blocks is not dependent on the Genesis Framework, the above Genesis Block Theme, or any other plugins or themes.
Registering & configuring the block
The beauty of this plugin is that we get to do so much in the WordPress admin.
In the WordPress admin, in the lefthand menu, go to Custom Blocks > Add New
The screen we now see is the Block Builder, which is where we’re going to configure a bunch of things for our block including adding fields.
The way this plugin works is that it creates custom blocks where the user, working in the Block Editor, enters content and data via fields in a form-like interface. This simplified/opinionated interface is one of the things that speeds up the custom block creation process. You don’t need to figure out the input UI.
The Block Details we add are:
- Name: Pricing Table
- Slug: pricing-table
- Icon: Genesis Planet
The Fields we add are:
Adding fields to our custom block looks like this:
Once we’ve added all our fields, this is what it looks like:
When we hit publish, we get a prompt prompting us what to do next.
This leads us to the next step:
Templating the block
The block is actually registered and available in the block editor now. You could jump over to a new post/page and add the block like you would any other. It would not (yet) display anything though. This is where templating comes in.
Genesis Custom Blocks lets WordPress devs leverage a lot of the templating practices we’ve honed over the last decade or so. It’s super simple and will feel very familiar.
In our child theme, we add a couple of new folders and files like this:
/genesis-block-child-theme /blocks /pricing-table block.php block.css
Things to take note of here:
- We add a
blocksfolder in our theme (child theme).
- We add a folder specific to the block we are currently working on and name it whatever the blocks slug is, which in this case is
- We add a PHP file and CSS file. These are where we will be adding our template code.
Starting with our PHP file, let’s begin with our basic HTML markup and CSS classes.
This will look like this:
<div class="fw-pricing-table"> <img src=""> <h3 class="fw-pricing-table__name"></h3> <p class="fw-pricing-table__description"></p> <div class="fw-pricing-table__price"> <span>$</span> <span></span> <span>/mo</span> </div> <a class="fw-pricing-table__btn" href="">Get Started</a> <div class="fw-pricing-table__site-count"> <span></span> <span>WordPress Site</span> </div> <div class="fw-pricing-table__resources"> <div> <p><span> monthly visits</span></p> <progress value="" max="400000"></progress> </div> <div> <p><span>GB Disk</span></p> <progress value="" max="50"></progress> </div> <div> <p><<span>GB bandwidth</span></p> <progress value="" max="500"></progress> </div> </div> </div>
Things to take note of:
- We’ve got a bunch of CSS classes ready to go. Note: you can tackle the CSS however makes sense to you.
- We’re going to use the
<progress>HTML tag to handle our resource bars.
Now we’re going to work with a simple PHP function the plugin makes available to us. There are a bunch available, but you’ll probably spend most of your time using these 2 below. We’re exclusively using the first in this block.
|Function||What it does|
|Fetches and outputs the data entered into the field by the user when adding the block to a page/post.|
|Fetches the data entered into the field by the user when adding the block to a page/post.|
So, with these functions, our PHP template file now looks like this:
<div class="fw-pricing-table"> <img src="<?php block_field( 'icon' ); ?>"> <h3 class="fw-pricing-table__name"><?php block_field( 'name' ); ?></h3> <p class="fw-pricing-table__description"><?php block_field( 'description' ); ?></p> <div class="fw-pricing-table__price"> <span>$</span> <span><?php block_field( 'price' ); ?></span> <span>/mo</span> </div> <a class="fw-pricing-table__btn" href="<?php block_field( 'url' ); ?>">Get Started</a> <div class="fw-pricing-table__site-count"> <span><?php block_field( 'site-count' ); ?></span> <span>WordPress Site</span> </div> <div class="fw-pricing-table__resources"> <div> <p><?php block_field( 'monthly-visits' ); ?><span> monthly visits</span></p> <progress value="<?php block_field( 'monthly-visits' ); ?>" max="400000"></progress> </div> <div> <p><?php block_field( 'disk-space' ); ?><span>GB Disk</span></p> <progress value="<?php block_field( 'disk-space' ); ?>" max="50"></progress> </div> <div> <p><?php block_field( 'bandwidth' ); ?><span>GB bandwidth</span></p> <progress value="<?php block_field( 'bandwidth' ); ?>" max="500"></progress> </div> </div> </div>
You can see where we’ve used that
block_field() function to fetch and output the data. We simply use the slug of the field as an argument in the function. E.g.
block_field( ‘icon’ ). This, being an image field type, returns the URL for that image.
For our CSS, we place this in the block.css template file. Once again, CSS can be spun whichever way you want and the specific code I’ve written is not particularly relevant to this tutorial, but I’ll leave it here for you to check out.
.fw-pricing-table border-radius: 4px; transition: box-shadow .3s ease-in-out; border: 1px solid #e7e7e7; background-color: #fff; padding: 2rem 2em 4em; display: flex; flex-direction: column; align-items: center; text-align: center; .fw-pricing-table:hover box-shadow: 0 5px 22px 0 rgb(0 0 0 / 10%); .fw-pricing-table img max-height: 100px; width: auto; .fw-pricing-table__name margin-top: 20px; font-weight: 400; .fw-pricing-table__description font-size: 16px; font-style: italic; font-family: serif; max-width: 160px; .fw-pricing-table__price color: #50c6db; display: flex; align-items: flex-start; font-size: 46px; font-weight: 500; .fw-pricing-table__price span:last-child font-size: 24px; margin-top: 6px; .fw-pricing-table__btn display: block; background-color: #338199; color: #fff; padding: 6px 20px; border-radius: 18px; font-size: 13px; text-transform: uppercase; letter-spacing: 1px; font-weight: 500; margin-top: 10px; .fw-pricing-table__btn:hover background-color: #01516e; color: #fff; .fw-pricing-table__site-count font-size: 14px; margin-top: 24px; font-weight: 500; color: #50c6db; border-top: 1px solid #ddd; padding-top: 20px; .fw-pricing-table__resources margin-top: 8px; .fw-pricing-table__resources>div display: flex; flex-direction: column; align-items: flex-start; .fw-pricing-table__resources p font-size: 13px; font-weight: 600; margin-bottom: 0; margin-top: 18px; .fw-pricing-table__resources progress[value] margin-top: 6px; -webkit-appearance: none; appearance: none; height: 6px; border: none; border-radius: 3px; overflow: hidden; .fw-pricing-table__resources progress[value]::-webkit-progress-bar background-color: #e7e7e7; .fw-pricing-table__resources progress[value]::-webkit-progress-value background-color: #50c6db; border-radius: 3px;
The most interesting part of the CSS here is the styling of the
<progress> tag. A bit fiddly, but it is what it is. You could switch to a nested div setup for those and calculate set widths if you’d like to avoid
And that’s it! 💪
- We added and configured the block in the WP Admin
- We created a PHP template file with a measly 29 lines of basic HTML and a single PHP function
- We dropped some CSS into
block.cssfor our styling.
Using our custom block
So now we can jump over and create a new post or page and add the block. To keep that 4-column style for the pricing options, we first add a columns block and then drop our custom pricing table block into each column.
Clicking the “Add block” button, you can see here our Pricing Table block is ready to go.
The below shows how I’ve got four columns and have added the custom block four times. As I select an individual block you can see it switch to the form UI that gives us our fields for dropping in content. Clicking away from the form view gives us the preview.
Looks lovely in the block editor and looks just as good on the front end. Because we’re leveraging the columns block as well, everything is nice and responsive.
With our designs done for us to work from and being able to lean on the responsive columns block of Gutenberg, the total build time of this block for me was less than 10 min. 🙂
There are a couple of things you could do to improve the block even further:
- There are a few strings that need to be pluralized. I.e. “WordPress Site” should be “WordPress Sites” for plans with more than 1 site limit. Some basic logic in the PHP template file could solve this.
- You could skip the columns block and instead use the Repeater field (Pro feature) and contain all the plans in a single block.
- Add commas to larger numbers.
- The progress bars show exact value to max relationships. This looks a little odd. You could switch to something more conceptual of the values.
Wrapping things up
If you would like to download and install this block, you can download the files here. Documentation on importing custom blocks can be found here.
Other important links:
If you’d like to see a bit more of Genesis Custom Blocks in action, in a recent session at DECODE, I built & demo’d four separate custom blocks (of increasing complexity) in about 15 minutes. Check out the on-demand recording right here.
I hope you found this useful and got an understanding of how leveraging the power of the Block Editor for custom designs and builds is really very easy.
Get free access to Genesis-built StudioPress themes with Flywheel!
It’s important that your hosting provider does the most for you, and that goes beyond performance and security! With access to more than 35 Genesis-built StudioPress themes at no extra cost, Flywheel provides you with a beautiful library of themes so you can build or reconfigure your sites in a way that fits your website goals! Learn more about Flywheel here.