Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/ihebgrayaa/ecommerce-block/archive/refs/heads/main.zip# 📦 Ecommerce Block
Custom WordPress Gutenberg Blocks with Multiple Styles
Ecommerce Block provides a modular framework for WordPress developers to create custom Gutenberg blocks with dynamic content, multiple render styles, and full integration with ACF fields
GitHub: https://github.com/ihebgrayaa/ecommerce-block
Overview
- Each block lives in its own folder under
addons/. - Blocks are automatically registered via
Kernel.php. - Blocks can pull data from post meta or post content.
- Blocks can have multiple render styles, like hero layouts or boxed/minimal author blocks.
How Blocks Work
Block Registration
- Each block has a main PHP file (e.g.,
AuthorBlock.php) that defines metadata. Kernel.phpautomatically detects the block folder and registers it.
Example from AuthorBlock:
Understanding AuthorBlock.php
AuthorBlock.php is the main class for the AuthorBlock. It demonstrates how to create a custom Gutenberg block with ACF fields, multiple styles, and a renderer. You can use it as a template to create new blocks.
Block Class Basics
class AuthorBlock extends Block {
public function __construct() {
parent::__construct(_x('Author Block', 'title', ECOMMERCE_TEXT_DOMAINE), 'author-block');
}
}
- AuthorBlock extends Geniem\ACF\Block.
- The constructor sets the block title and slug.
- _x() is used for translation purposes.
- When creating a new block, change the class name, title, and slug.
Adding ACF Fields
The block uses classes like Textarea, Text, Image, Color, and Accordion to define ACF fields. These are wrappers around ACF Pro fields.
$quote = new Textarea(_x('Quote','field', ECOMMERCE_TEXT_DOMAINE),'quote','quote');
$author = new Text(_x('Author','field',ECOMMERCE_TEXT_DOMAINE),'author','author');
$role = new Text(_x('Role', 'field',ECOMMERCE_TEXT_DOMAINE),'role','role');
$image = new Image(_x('Image', 'field',ECOMMERCE_TEXT_DOMAINE),'image','image');
Textarea→ ACF Textarea field for multi-line text.Text→ ACF Text field for single-line text.Image→ ACF Image field.
All of these classes come from Geniem ACF wrapper and are based on ACF Pro documentation: ACF Field Types
Grouped Fields (Accordion Example)
You can group fields using an Accordion field:
$color_setting = new Accordion(_x('Color settings','field', ECOMMERCE_TEXT_DOMAINE),'color-setting','color-setting');
$background_color = new Color(_x('Background Color', 'field',ECOMMERCE_TEXT_DOMAINE),'background_color','background_color');
$text_color = new Color(_x('Text Color','field', ECOMMERCE_TEXT_DOMAINE),'text_color','text_color');
$color_setting->add_fields([
$background_color,
$text_color,
]);
- Accordion creates a collapsible panel in the block editor.
- Color fields allow the user to customize colors per block.
- This improves editor usability and block flexibility.
Setting Block Styles
$this->set_styles([ [ 'name' => 'default', 'label' => _x('Default', 'block style', ECOMMERCE_TEXT_DOMAINE), 'isDefault' => true, ], [ 'name' => 'boxed', 'label' => _x('Boxed', 'block style', ECOMMERCE_TEXT_DOMAINE), ], [ 'name' => 'minimal', 'label' => _x('Minimal', 'block style', ECOMMERCE_TEXT_DOMAINE), ] ]); - Styles let users switch between different block layouts.
- You can add new styles by creating a renderer in styles/ and adding it here.
Connecting the Renderer
$this->set_renderer(new AuthorBlockRenderer());
- The renderer class determines which HTML is output on the frontend.
- The dispatcher uses block classes (like is-style-boxed) to choose the correct style renderer.
- This keeps your block modular and maintainable.
Renderer System
- Each block can have multiple renderers in
styles/. - Example for AuthorBlock:
AuthorBlockBoxedRenderer.phpAuthorBlockDefaultRenderer.phpAuthorBlockMinimalRenderer.php
- Renderer classes define how the block content is output in HTML.
Main Renderer
- Each block has a main
BlockRenderer.php(e.g.,AuthorBlockRenderer.php). - This file decides which style to use based on ACF settings or post meta.
🛠 Adding a New Block
- Create a folder under
addons/with the block name. - Add:
YourBlock.php→ Registers the blockYourBlockRenderer.php→ Handles rendering logicstyles/→ Optional, for multiple renderers/styles
Kernel.phpwill auto-register your block—no manual registration needed.- Add ACF fields for dynamic content as needed.
Example structure:
addons/MyCustomBlock/
├── styles/
│ ├── MyCustomBlockStyleOne.php
│ └── MyCustomBlockStyleTwo.php
├── MyCustomBlock.php
└── MyCustomBlockRenderer.php
🔹 Rendering Example
class AuthorBlockRenderer implements Renderer {
public function render(array $props): string {
$classes = $props['block']['className'] ?? '';
return match (true) {
str_contains($classes, 'is-style-boxed') =>
(new AuthorBlockBoxedRenderer())->render($props),
str_contains($classes, 'is-style-minimal') =>
(new AuthorBlockMinimalRenderer())->render($props),
default =>
(new AuthorBlockDefaultRenderer())->render($props),
};
}
}
AuthorBlockBoxedRenderer.php
AuthorBlockBoxedRenderer.php is one of the style renderers for the AuthorBlock. It defines how the boxed style of the block is displayed on the frontend.
Purpose
- Renders the boxed layout of the AuthorBlock.
- Highlights the quote, author name, and role in a card-like style.
- Includes the author image if available.
- Provides a clean, semantic HTML structure.
How it Works
- Gets the block data from
$props['data']:
$data = $props['data'];
$image = $data['image']['url'] ?? '';
$datacontains all ACF field values for the block.$imageretrieves the URL of the author’s image if it exists.
Returns the HTML structure for the boxed style:
<section class="author author--boxed">
<div class="author__box">
'.($image ? '<img src="'.esc_url($image).'" alt="'.esc_attr($data['author'] ?? '').'">' : '').'
<blockquote>'.esc_html($data['quote'] ?? '').'</blockquote>
<strong>'.esc_html($data['author'] ?? '').'</strong>
<span>'.esc_html($data['role'] ?? '').'</span>
</div>
</section>