Page Generator Pro

from $99/yr

Documentation

Dynamic Tags

Overview

Info icon

Dynamic Tags are available in Page Generator Pro 5.5.7, releasing Friday 10th July 2026 23:59 UTC

Dynamic Tags allow parts of content, header code and footer code to be replaced with information about the currently viewed Post at the point the Post is rendered on the frontend.

Unlike Keywords or Shortcodes (which are resolved at generation time and stored in the generated Post), Dynamic Tags are resolved at output time. This means:

  • The value is always current – if you change the site name, the Post’s Featured Image or the Post’s title, the output reflects that change immediately, with no need to regenerate.
  • You can reference values that don’t exist yet at generation time, such as the generated Post’s own URL or ID.
  • The same Content Group field can be used for many different Posts, each resolving to its own Post’s data.

For example, you might want to:

  • Output the generated Post’s URL in a canonical <link> tag in Header Code,
  • Output the generated Post’s Featured Image URL in a JSON-LD structured data block,
  • Output the current year in a footer copyright notice, without ever needing to regenerate content when the year changes.

Where Dynamic Tags Work

Dynamic Tags are resolved on the frontend, immediately before content is output, in the following Content Group fields:

  • Header Code
  • Footer Code
  • Content

They are resolved after Shortcodes, meaning a Shortcode’s output can also contain Dynamic Tags, and those tags will still be replaced.

Dynamic Tags are not replaced at generation time, and are not replaced in the Content Group edit screen preview. If you view the source of a generated Post directly (i.e. edit the Post in the WordPress Editor), you’ll still see the raw %%tag%% syntax – this is expected. The replacement happens as WordPress renders the Post to a visitor.

Syntax

In any supported field, the following syntax can be used for a Dynamic Tag:

%%tag_name%%

Some tags accept an optional argument, which is separated from the tag name by a colon:

%%tag_name:argument%%

Syntax must start with %% and end with %%. If either are missing, the Dynamic Tag will not be replaced.

If a tag name is not registered, or if a registered tag throws an error at output time, the original %%tag%% syntax is left in the content untouched. This is intentional, so that a broken hook doesn’t silently strip a marker from your source.

Available Tags

The following Dynamic Tags are registered out of the box.

Post

These tags resolve to information about the currently viewed generated Post.

TagDescription
%%post_id%%The Post’s ID.
%%post_title%%The Post’s Title.
%%post_url%%The Post’s permalink.
%%post_thumbnail_url%%The URL of the Post’s Featured Image. Accepts an optional image size argument (defaults to full).
%%post_excerpt%%The Post’s Excerpt.
%%post_content%%The Post’s Content.
%%post_date%%The Post’s published date. Accepts an optional PHP date format argument (defaults to the site’s Date Format setting).
%%post_modified_date%%The Post’s last modified date. Accepts an optional PHP date format argument (defaults to the site’s Date Format setting).
%%post_author%%The Post Author’s display name.
%%post_author_url%%The URL to the Post Author’s archive page.

Site

These tags resolve to information about the WordPress Site.

TagDescription
%%sitename%%The Site Title, as defined in Settings > General.
%%site_url%%The Site’s home URL.
%%site_description%%The Site Tagline, as defined in Settings > General.

Date and Time

These tags resolve to the current date or time at the moment the Post is rendered.

TagDescription
%%current_year%%The current four-digit year (e.g. 2026).
%%current_date%%The current date. Accepts an optional PHP date format argument (defaults to the site’s Date Format setting).
%%current_time%%The current time. Accepts an optional PHP date format argument (defaults to the site’s Time Format setting).

Tags with Arguments

Some Dynamic Tags accept a single argument after a colon, allowing the tag’s output to be customized.

For image tags, the argument is a WordPress image size:

%%post_thumbnail_url:medium%%
%%post_thumbnail_url:thumbnail%%
%%post_thumbnail_url:full%%

For date and time tags, the argument is a PHP date format string:

%%post_date:Y-m-d%%
%%post_modified_date:F j, Y%%
%%current_date:l, jS F Y%%
%%current_year%%

If the argument is omitted, the tag falls back to a sensible default (full for image sizes; the site’s Date Format or Time Format setting for dates and times).

Changing the Tag Prefix and Suffix

By default, Dynamic Tags are wrapped in %%. This syntax is also used by some SEO plugins (Yoast SEO, Rank Math, SEOPress), which may cause conflicts if you’re using Dynamic Tags in fields those plugins also process.

The prefix and suffix can be changed using the page_generator_pro_dynamic_tags_get_prefix_suffix filter. For example, to change to [[ / ]]:

add_filter(
    'page_generator_pro_dynamic_tags_get_prefix_suffix',
    function( $prefix_suffix ) {
        return '[[';
    }
);

Once changed, tags must use the new prefix and suffix throughout your Content Group:

[[post_url]]
[[post_thumbnail_url:medium]]

The prefix and suffix are treated as identical strings, so if you set the filter to [[, tags will be wrapped in [[...]].

Registering Custom Dynamic Tags

You can register additional Dynamic Tags using the page_generator_pro_dynamic_tags filter. Each tag maps a tag name to a callable that returns the tag’s value.

The callable receives the current Post ID as its first argument, and an optional string argument (from %%tag:argument%%) as its second.

add_filter(
    'page_generator_pro_dynamic_tags',
    function( $tags ) {

        // Add a %%reading_time%% tag.
        $tags['reading_time'] = function( $post_id ) {
            $post = get_post( $post_id );
            if ( ! $post ) {
                return '';
            }

            $words   = str_word_count( wp_strip_all_tags( $post->post_content ) );
            $minutes = max( 1, (int) ceil( $words / 200 ) );

            return sprintf( '%d min read', $minutes );
        };

        // Add a %%custom_field:field_name%% tag.
        $tags['custom_field'] = function( $post_id, $field_name = '' ) {
            if ( $field_name === '' ) {
                return '';
            }
            return (string) get_post_meta( $post_id, $field_name, true );
        };

        return $tags;
    }
);

The callable must return a string. Any value returned is cast to a string before being inserted into the content.

Examples

Output the Generated Post’s URL

To output a canonical link tag in Header Code that references the generated Post’s URL:

<link rel="canonical" href="%%post_url%%" />

To reference the generated Post’s Featured Image in an Open Graph meta tag in Header Code:

<meta property="og:image" content="%%post_thumbnail_url:full%%" />

To reference a smaller size:

<meta property="og:image" content="%%post_thumbnail_url:medium%%" />

To output a copyright notice in Footer Code that always shows the current year, without needing to regenerate content annually:

<p>&copy; %%current_year%% %%sitename%%. All rights reserved.</p>

Output the Post’s Published Date in a Custom Format

To output the generated Post’s published date in Year-Month-Day format in Content:

Published: %%post_date:Y-m-d%%

To output the last modified date in a longer format:

Last updated: %%post_modified_date:F j, Y%%

Output Structured Data in the Header

To output a JSON-LD Article schema block in Header Code, referencing the generated Post’s own data:

<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "Article",
    "headline": "%%post_title%%",
    "url": "%%post_url%%",
    "image": "%%post_thumbnail_url:full%%",
    "datePublished": "%%post_date:c%%",
    "dateModified": "%%post_modified_date:c%%",
    "author": {
        "@type": "Person",
        "name": "%%post_author%%",
        "url": "%%post_author_url%%"
    },
    "publisher": {
        "@type": "Organization",
        "name": "%%sitename%%",
        "url": "%%site_url%%"
    }
}
</script>

Common Issues

Tags are not replaced

  • Ensure the tag is wrapped in the correct prefix and suffix (%% by default), with no spaces between the prefix, tag name and suffix.
  • Ensure the tag name matches one of the registered tags exactly. Tag names are case sensitive.
  • Ensure the tag is placed in a supported field: Header Code, Footer Code or Content. Tags placed in other fields (e.g. the Post Title) will not be replaced.
  • If you have changed the prefix and suffix via the page_generator_pro_dynamic_tags_get_prefix_suffix filter, ensure your tags use the new prefix and suffix throughout.

Tag conflicts with another Plugin

If another Plugin (such as Yoast SEO, Rank Math or SEOPress) is also processing %% style tags in the same field, the tag may be replaced before Page Generator Pro can process it, or vice versa.

The recommended solution is to change the Dynamic Tag prefix and suffix to something unique using the page_generator_pro_dynamic_tags_get_prefix_suffix filter, as described in Changing the Tag Prefix and Suffix.


Published

Last Updated