Building Dynamic Gutenberg Blocks inside Awesome XP

With Awesome XP you can build fully native Gutenberg blocks without Advanced Custom Fields or a build step. Layout, controls, CSS, JavaScript and server-side rendering all live in WordPress, in one post under Add Awesome Gutenberg Blocks. Each block is a set of templates: Register, Controls, Render, Styles and Scripts.

Compatibility: the block style in this article (Styles and Scripts templates, row_repeater, innerblocks, select and toggle controls, sidebar sections) works in Awesome XP only. It is not supported in the Awesome Enterprise WP plugin. The basic three-template block (Register, Render, Controls with text, title and textarea fields) is the older pattern from version 3.2.2.

What works where

Feature Awesome XP Awesome Enterprise WP plugin
Register, Render and Controls templates Supported Supported (3.2.2)
styles_service and scripts_service Supported Not supported
description in block config Supported Not supported
select and toggle controls Supported Not supported
Sidebar sections ([sidebar _value="true" /]) Supported Not supported
row_repeater with table layout Supported Not supported
innerblocks field Supported Not supported

1. The Register template

Register maps the block to its templates. Two things changed from the older pattern: the config takes a description, and there are two new services, styles_service and scripts_service.

Important: the name in the config must match the middle part of every service path. A block named awx-testimonial-card uses gb_blocks.awx-testimonial-card.render, .controls, .styles and .scripts. If they don’t match, the block can’t find its templates.

Both modules use the wrapper class wp-block-dgb-<name> in their Render template, for example wp-block-dgb-awx-testimonial-card. All your CSS and JavaScript selectors hang off that class.

2. The Controls template

Controls define the editor UI and the block’s data. Each field writes to a key under content.* or style.* through attr_name, and Render reads the same keys back. Fields are grouped into sections, and every field can carry a default.

Field types used in the modules

Type Use it for Notes
text Short single-line values Good for badges, roles, extra CSS classes
title Main heading or name Supports "validation": { "required": true }
textarea Longer text Quotes, descriptions
select Pick one option Takes an options array of label and value. Store CSS class names as values and drop them straight into the markup
toggle On or off "default": true
row_repeater A list of rows See below
innerblocks Nested WordPress blocks See below

A section with [sidebar _value="true" /] appears in the settings sidebar.

Repeating rows with row_repeater

row_repeater stores an array of rows at its attr_name. Each column is a repeater_fields entry with its own width, and "layout": "table" edits the rows as a table. The default array seeds the first rows.

Nested blocks with innerblocks

An innerblocks field gives editors a slot for any WordPress block, such as buttons, paragraphs or media. It needs only a label and an attr_name.

3. The Render template

Render runs on the server and returns the block’s front-end HTML. Read each value with [template.get] using the same content.* or style.* key you set in Controls, and give it a default so empty blocks still render. Use o.set to park a value in a template variable.

Print [template.get wp.wrapper_attributes /] on the outer element so WordPress can add its own block attributes.

The select value goes straight into the class list (testimonial-inner card--elevated), so the style options in Controls and the modifier classes in Styles must use the same names.

Looping over a row_repeater

Guard the loop with c.not_empty, then iterate with [loop.@f ...]. Inside the loop, read every column through .item: @f.item.title, never @f.title.

Printing nested blocks

The innerblocks field is output with a plain [template.get] on its attr_name. Put it inside a wrapper you can style.

A toggle such as style.show_icons is read the same way and tested with [if.true ...]. The showcase module sets its default to "1" in Render, alongside the toggle’s true default in Controls.

4. The Styles template

Styles hold plain CSS for the block, with no shortcodes. Awesome XP extracts it from the post and compiles it into a content-hashed file on disk.

Three rules keep it safe:

  • Scope every selector under the block’s wrapper class, such as .wp-block-dgb-awx-testimonial-card, so styles can’t leak into the rest of the page.
  • **Use --awx-* tokens with fallbacks** for spacing, colour, radius and type, so the block follows your Awesome CSS design system and still looks right without it.
  • Match the modifier classes to the values in your select fields. card--bordered, card--elevated and card--minimal below come straight from the Card Style options.

Cascade layers

The showcase module wraps all its CSS in @layer blocks { ... }, so the block’s rules sit in a known layer and are easy to override from your theme. Wrap yours the same way when you want that control.

The column count works the same way as the card style: the select value 3 becomes the class has-cols-3 in Render, and the CSS reacts to it.

5. The Scripts template

Scripts hold plain front-end JavaScript, with no shortcodes and no <script> tags. Like Styles, it is compiled to a hashed file. Scope your selectors to the block’s wrapper class and wait for DOMContentLoaded.

This script toggles the is-highlighted class from Styles when a visitor clicks a testimonial.

Keep the visual state in CSS classes, as here, rather than writing inline styles from JavaScript. The showcase module does set borderColor inline on hover, but a class is easier to theme and override.

Complete testimonial module

Paste this into a single post under Add Awesome Gutenberg Blocks in Awesome XP. It will not work in the Awesome Enterprise WP plugin.

Updated on Nov 05, 2026