Update: 3/4/2025
The following blocks have also been added:
- Carousel
- Swiper
- Content Wrapper
- Enhanced cover block
- Lazy loading options for the image and videos
- Setting for the cover block background to extend past its container to the edge of the screen (left or right)
- Tabbed Panels
- Alerts
I’ve always been fascinated by how WordPress can be customized well beyond simple themes and plugins. Over the past few weeks, I decided to fully embrace Gutenberg’s block editor and Bootstrap 5. My goal was to create a set of dynamic, reusable blocks—including Rows, Columns, Accordions, and Modals—that could neatly snap into any WordPress site and offer advanced layout capabilities.
In this post, I’ll share how I brought these blocks to life, the components and files involved, and a direct link to my GitHub repository so you can explore the code yourself.
Why Custom Blocks?
As a longtime WordPress developer, I found that classic shortcodes or older page builders didn’t give me the crisp, integrated editing experience I wanted. With the Gutenberg (Block Editor) API and Bootstrap 5, I could:
- Leverage dynamic blocks (
render.php
) so the markup is generated on the server for full control. - Use
block.json
and WordPress Scripts to structure each block. - Mix the power of InnerBlocks for nested content and Bootstrap classes for columns, rows, accordions, and modals.
Breaking Down the Files & Structure
Each block follows a Gutenberg best-practice pattern:
block.json
– Describes the block (name, category, attributes, and references to script files).index.js
– Registers the block, imports styles, and designates theedit
andsave
(or dynamic render) behavior.edit.js
– The React component used in the editor. This might have InspectorControls, FormTokenField for class selection, or a simple RichText for titles.render.php
– For dynamic blocks, this file outputs the block’s final HTML with$attributes
and$content
.editor.scss
&style.scss
– SCSS or CSS for styling in both the editor and front end.view.js
(Optional) – Handles front-end JavaScript if the block needs interactive behavior outside of Bootstrap’s own scripts.
Key Components We Created
- Row Block – A dynamic, Bootstrap-friendly
<div class="row">
. We set up custom token fields to allow margin, padding, align-items, and other classes—then merged them into a finaladditionalClasses
attribute. - Column Block – Manages column classes (
col
,col-6
, etc.) with optional offsets, orders, or alignment. It too relies on dynamic attributes, usesInnerBlocks
, and arender.php
that merges all selected classes. - Accordion & Accordion Item – A parent
accordion
block holds multipleaccordion-item
child blocks, each with collapsible content. We usedInnerBlocks
for the accordion item’s body. The items each have a title attribute, and they output a Bootstrap 5–compliant<div class="accordion">
structure. - Modal Block – A dynamic block that renders a Bootstrap modal, including a header, body, and footer. It relies on an ID-based approach, so we can link to it using…
- Modal Button – A separate block (or variation of
core/button
) that setsdata-bs-toggle="modal"
anddata-bs-target="#myModalId"
. By matching themodalId
, the button triggers the modal’s display.
The WordPress Plugin & PHP Setup
All these blocks live inside a plugin structure. For instance, our main file (e.g., fs-blocks.php
) registers blocks by pointing to folders in build/
. Each folder has block.json
, scripts, and a render_callback
referencing a partial render.php
. We also created a small settings page to toggle Bootstrap 5 loading in the editor or front end, ensuring everything is neatly integrated.
Render Callbacks:
- We keep them in a separate
render-callbacks.php
file, each function named likefsblocks_render_row_block
orfsblocks_render_modal_block
. - For dynamic blocks, WordPress calls the relevant PHP function, passes
$attributes
&$content
, and includes the appropriaterender.php
.
Explore the Code on GitHub
I’ve open-sourced the entire project here:
Custom-Blocks GitHub Repository
Feel free to clone, adapt, or star the repo. I’ve tried to comment each file and keep the code tidy so you can follow along. If you’d like to see additional enhancements—like more advanced token fields or different Bootstrap versions—pull requests are welcome!
Final Thoughts
Switching to a dynamic, Bootstrap-centric block approach has transformed how I build WordPress layouts. Instead of sprinkling shortcodes or wrestling with random editors, I can craft polished, snappy experiences natively in Gutenberg. I hope this little journey shows how a few well-structured block files, some smart attributes, and WordPress Scripts can give you a plugin that’s both developer-friendly and user-friendly.
If you’ve been curious about building custom blocks or integrating Bootstrap 5, I encourage you to give it a shot. Check out the GitHub repo, test the plugin, and let me know how it goes!
Thanks for reading—and happy block building!