GenerateBlocks dynamic tags insert dynamic content into blocks using a {{tag_name}} syntax. The registration system lets you create your own tags, which people insert through the editor UI.
To change how existing tags output data, see Dynamic tags: output and rendering. For who can use tags and which data they can read, see Dynamic tags: meta access and security.
Jump to
- Overview
- Basic registration
- Registration parameters
- Writing callback functions
- Complete examples
- Available filters
- Tag parameter syntax
- Quick reference
Overview
A tag is a name, a callback that returns its output, and settings for how it appears in the editor. GenerateBlocks registers 15 tags itself, such as post_title, post_meta and featured_image, in includes/dynamic-tags/class-dynamic-tags.php. GenerateBlocks Pro registers more, such as the archive, site, user meta, term meta and loop tags.
Basic registration
GB Free
Dynamic tags are registered using the GenerateBlocks_Register_Dynamic_Tag class, typically on the init action:
add_action( 'init', function() {
new GenerateBlocks_Register_Dynamic_Tag( [
'title' => __( 'Post Title', 'textdomain' ),
'tag' => 'post_title',
'type' => 'post',
'supports' => [ 'link', 'source' ],
'return' => 'my_callback_function',
] );
} );
The class does nothing if tag, return or title is missing.
Related: Registration parameters Guide: Dynamic Tags
Registration parameters
Required parameters
title(string): the human-readable name shown in the tag selector UI.tag(string): the tag identifier used in content,{{tag_name}}. Use lowercase with underscores.return(callable): the callback that generates the tag’s output. It receives($options, $block, $instance).
Optional parameters
type (string), default 'post': the entity type this tag relates to. The options are:
'post': WordPress posts, pages and custom post types'author': post authors (users)'user': any WordPress user'term': taxonomy terms'media': media library items
supports (array), default []: the features available for this tag:
'source': allow selecting a specific entity (post ID, user ID and so on)'link': wrap the output in a link'meta': access meta fields with thekey:parameter'date': date formatting options'image-size': image size selector'taxonomy': taxonomy selector'comments': comments-related features'instant-pagination': query pagination support
options (array): custom UI controls shown in the tag modal. Each key is the option name with its config:
'options' => [
'length' => [
'type' => 'number',
'label' => __( 'Excerpt Length', 'textdomain' ),
'placeholder' => '55',
'default' => 55,
'help' => __( 'Number of words to display.', 'textdomain' ),
],
'useTheme' => [
'type' => 'checkbox',
'label' => __( 'Use Theme Defaults', 'textdomain' ),
'default' => true,
'help' => __( 'Use theme settings.', 'textdomain' ),
],
'format' => [
'type' => 'select',
'label' => __( 'Format', 'textdomain' ),
'default' => 'plain',
'options' => [
[ 'value' => 'plain', 'label' => 'Plain Text' ],
[ 'value' => 'html', 'label' => 'HTML' ],
],
],
'separator' => [
'type' => 'text',
'label' => __( 'Separator', 'textdomain' ),
'placeholder' => ', ',
'help' => __( 'Text between items.', 'textdomain' ),
],
],
Option types: 'text', 'number', 'checkbox', 'select'.
description (string): help text shown below the tag selector in the UI.
visibility (array): controls when the tag appears in the selector. It can be:
true: always visible (the default)false: never visible[ 'context' => [ 'key1', 'key2' ] ]: only when the block’s editor context has every one of the keys[ 'attributes' => [ ... ] ]: conditional on the block’s attributes. Every condition must match. Each condition has aname, avalueand acompareoperator.
Example visibility based on the block’s tagName:
'visibility' => [
'attributes' => [
[
'name' => 'tagName',
'value' => [ 'a', 'button', 'img' ],
'compare' => 'NOT_IN',
],
],
],
Comparison operators: '===' (the default), '!==', 'IN' and 'NOT_IN'.
Related: generateblocks.editor.tagSpecificControls Guide: Dynamic Tags
Writing callback functions
Callbacks receive three parameters and must return a string:
function my_tag_callback( $options, $block, $instance ) {
// $options - Parsed tag parameters from {{tag param1:value|param2:value}}
// $block - The block data array
// $instance - Block instance object with context
// Get the source ID (respects user's source selection)
$id = GenerateBlocks_Dynamic_Tags::get_id( $options, 'post', $instance );
if ( ! $id ) {
return ''; // No output if no ID
}
// Get your data
$output = get_post_meta( $id, 'my_meta_key', true );
// Apply transformations and wrapping
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
}
$options always includes tag_name, the name of the tag being resolved.
The output() helper
GenerateBlocks_Dynamic_Tag_Callbacks::output() applies the built-in transformations:
trunc:50: truncate to 50 characterstrunc:10,words: truncate to 10 wordstrim,trim:left,trim:right: remove whitespacecase:lower,case:upper,case:title: transform casereplace:"old","new": string replacementwpautop: add paragraph tagslink:post: wrap in a link (if supported)
Always use output() as your return unless you need raw output. Its result passes through generateblocks_dynamic_tag_output.
Related: generateblocks_dynamic_tag_id Guide: Dynamic Tags
Complete examples
Example 1: simple meta field tag
new GenerateBlocks_Register_Dynamic_Tag( [
'title' => __( 'Product SKU', 'textdomain' ),
'tag' => 'product_sku',
'type' => 'post',
'supports' => [ 'source' ],
'return' => function( $options, $block, $instance ) {
$id = GenerateBlocks_Dynamic_Tags::get_id( $options, 'post', $instance );
$sku = get_post_meta( $id, '_sku', true );
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $sku, $options, $instance );
},
] );
Usage: {{product_sku}} or {{product_sku id:123}}
Example 2: tag with custom options
new GenerateBlocks_Register_Dynamic_Tag( [
'title' => __( 'User Bio', 'textdomain' ),
'tag' => 'user_bio',
'type' => 'user',
'supports' => [ 'source' ],
'options' => [
'length' => [
'type' => 'number',
'label' => __( 'Max Words', 'textdomain' ),
'default' => 50,
],
],
'return' => function( $options, $block, $instance ) {
$user_id = GenerateBlocks_Dynamic_Tags::get_id( $options, 'user', $instance );
$bio = get_user_meta( $user_id, 'description', true );
// Use custom option
$length = $options['length'] ?? 50;
$bio = wp_trim_words( $bio, $length );
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $bio, $options, $instance );
},
] );
Usage: {{user_bio length:25}}
Example 3: image tag with multiple keys
new GenerateBlocks_Register_Dynamic_Tag( [
'title' => __( 'Author Avatar', 'textdomain' ),
'tag' => 'author_avatar',
'type' => 'author',
'supports' => [ 'source' ],
'options' => [
'key' => [
'type' => 'select',
'label' => __( 'Output', 'textdomain' ),
'default' => 'url',
'options' => [ 'url', 'id', 'alt' ],
],
'size' => [
'type' => 'number',
'label' => __( 'Size (px)', 'textdomain' ),
'default' => 96,
],
],
'return' => function( $options, $block, $instance ) {
$id = GenerateBlocks_Dynamic_Tags::get_id( $options, 'post', $instance );
$author_id = get_post_field( 'post_author', $id );
$size = $options['size'] ?? 96;
switch ( $options['key'] ?? 'url' ) {
case 'id':
return (string) $author_id;
case 'alt':
return get_the_author_meta( 'display_name', $author_id );
case 'url':
default:
$url = get_avatar_url( $author_id, [ 'size' => $size ] );
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $url, $options, $instance );
}
},
] );
Example 4: conditional visibility
Only show for non-interactive elements:
new GenerateBlocks_Register_Dynamic_Tag( [
'title' => __( 'Term Links', 'textdomain' ),
'tag' => 'term_links',
'type' => 'post',
'supports' => [ 'source', 'taxonomy' ],
'visibility' => [
'attributes' => [
[
'name' => 'tagName',
'value' => [ 'a', 'button' ],
'compare' => 'NOT_IN',
],
],
],
'return' => 'my_term_links_callback',
] );
Available filters
Each of these filters has its own entry in Dynamic tags: output and rendering, with the full list of parameters.
Modify tag replacement
See generateblocks_dynamic_tag_replacement.
add_filter( 'generateblocks_dynamic_tag_replacement', function( $replacement, $args ) {
// $args contains: tag, full_tag, content, block, instance, options, supports
return $replacement;
}, 10, 2 );
Before tag replacement (modify HTML)
See generateblocks_before_dynamic_tag_replace.
add_filter( 'generateblocks_before_dynamic_tag_replace', function( $content, $args ) {
// Manipulate content before tag is replaced
return $content;
}, 10, 2 );
Filter the source ID
See generateblocks_dynamic_tag_id.
add_filter( 'generateblocks_dynamic_tag_id', function( $id, $options, $instance ) {
// Override which post/user/term ID is used
return $id;
}, 10, 3 );
Filter output after all transformations
See generateblocks_dynamic_tag_output.
add_filter( 'generateblocks_dynamic_tag_output', function( $output, $options, $raw_output ) {
// Modify final output
return $output;
}, 10, 3 );
Add custom source options
This is a JavaScript filter, so add it with wp.hooks.addFilter() in a script that loads in the block editor. See generateblocks.dynamicTags.sourceOptions.
wp.hooks.addFilter(
'generateblocks.dynamicTags.sourceOptions',
'my-plugin/source-options',
( options, context ) => [ ...options, { label: 'Custom Source', value: 'custom' } ]
);
Tag parameter syntax
Users insert tags with this syntax:
{{tag_name}} // Simplest form
{{tag_name id:123}} // With source ID
{{tag_name id:123|key:meta_field}} // Multiple parameters
{{tag_name param:value|trunc:50}} // With transformations
{{tag_name sep:\|}} // Escaped special chars
Built-in parameters, available on all tags:
id:123: a specific entity IDrequired:false: don’t render the block if the tag is emptylink:post: wrap in a link (if supported)trunc:N: truncate the outputcase:lower|upper|title: transform casetrim,wpautop,replace:"a","b": text transformations
Parameters are separated by a pipe (|). A value with a colon or pipe in it needs a backslash in front of that character.
Quick reference
Get the current post in a loop:
$id = GenerateBlocks_Dynamic_Tags::get_id( $options, 'post', $instance );
Get post meta:
$value = GenerateBlocks_Meta_Handler::get_post_meta( $id, $key, true );
Get user meta:
$value = GenerateBlocks_Meta_Handler::get_user_meta( $user_id, $key );
Access a custom option:
$my_option = $options['my_option'] ?? 'default_value';
Conditional output:
if ( empty( $output ) ) {
return ''; // Block won't render
}
Meta values read through GenerateBlocks_Meta_Handler follow the access rules in Dynamic tags: meta access and security.