Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To run a shortcode in a WordPress theme template, pass the complete bracketed string to do_shortcode() and print the returned value:

<?php echo do_shortcode( '' ); ?>

Use add_shortcode() when you need to create your own shortcode handler. The handler must return replacement content; it should not echo it.

Run an existing shortcode in a theme template

WordPress normally processes shortcodes in post content through the_content. A PHP template does not automatically process a string you write yourself, so call do_shortcode() where the output should appear.

<?php echo do_shortcode( '' ); ?>

The shortcode argument must be a string containing the square brackets. Attributes go inside the same string:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php echo do_shortcode( '' ); ?>

This is the pattern shown in the WordPress Theme Handbook gallery documentation. Place the PHP in the template file where the generated markup belongs, such as a page template, single-post template, or theme-part file.

Build a shortcode string from a value

If an ID or other value comes from a trusted configuration or WordPress data, assemble the string before passing it to do_shortcode(). Validate and escape values for their intended context rather than concatenating unchecked request data into executable markup.

<?php
$ids = '10, 205, 552';
echo do_shortcode( '' );
?>

Why a shortcode may appear as literal text

do_shortcode() only replaces tags that are registered at the time it runs. If no shortcode tags are defined, the function returns the input unchanged, so visitors can see the brackets. Confirm all of the following:

  • The plugin or theme code that registers the shortcode is active.
  • The registration runs before the template executes.
  • The tag spelling matches exactly, including underscores and other characters.
  • Attributes use the names and format expected by the handler.

See the do_shortcode() reference for its processing behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a custom shortcode

Register a distinctive tag with add_shortcode( $tag, $callback ). The callback receives attributes, enclosed content, and the shortcode tag, and returns the text that replaces the shortcode.

<?php
function site_example_shortcode( $atts = [], $content = null ) {
    return '<span class="example">Example output</span>';
}
add_shortcode( 'site_example', 'site_example_shortcode' );
?>

You can then use [site_example] in post content or execute it from a template:

<?php echo do_shortcode( '[site_example]' ); ?>

Handle attributes safely

Use shortcode_atts() to define supported defaults and discard unknown attributes. WordPress lowercases attribute names before passing them to the callback.

<?php
function site_greeting_shortcode( $atts = [] ) {
    $atts = shortcode_atts(
        [ 'name' => 'friend' ],
        $atts,
        'site_greeting'
    );

    return 'Hello, ' . esc_html( $atts['name'] ) . '!';
}
add_shortcode( 'site_greeting', 'site_greeting_shortcode' );
?>

esc_html() is appropriate here because the value is being returned as text inside HTML. Use an escaping function that matches the actual output context when returning URLs, attributes, JavaScript, or other markup.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Accept enclosed content

A shortcode may wrap content:

[notice]Text inside the shortcode[/notice]

The callback receives Text inside the shortcode as its $content argument. Decide whether that content may contain HTML, escape it when it should be text, or filter it deliberately before including it in returned markup.

<?php
function site_notice_shortcode( $atts = [], $content = null ) {
    $text = $content === null ? '' : wp_kses_post( $content );
    return '<div class="notice">' . $text . '</div>';
}
add_shortcode( 'notice', 'site_notice_shortcode' );
?>

If the enclosed content should contain other shortcodes, the callback can call do_shortcode( $content ) explicitly. Do this only when the recursion and resulting markup are intentional.

Template execution versus editor content

Situation Recommended approach Why
An existing plugin shortcode must appear in a PHP template Call do_shortcode( '[tag ...]' ) The template supplies the shortcode string directly.
Editors should place the feature in post content Register a shortcode with add_shortcode() and use its tag in content WordPress processes registered tags during content filtering.
The feature is site functionality that should survive a theme switch Consider registering it in a plugin or site-specific functionality layer The registration is less likely to disappear when presentation changes.

WordPress documentation does not require one universal location for custom shortcode code. Keeping functionality outside a presentation theme is a maintainability decision, not an API rule.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Shortcode naming, output, and parser limitations

Choose a unique tag

Use a distinctive prefix or site-specific name. If two registrations use the same tag, the later registration takes precedence according to load order. The API documentation also cautions against hyphens in shortcode names.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Return output; do not echo it

A shortcode callback must return the replacement string. Echoing from the callback can send markup at the wrong point in the page and produce broken output.

Understand nesting behavior

Shortcodes are parsed in a single pass. Same-name nested enclosing shortcodes are a documented limitation. Other nested behavior depends on callback logic; process enclosed content recursively only when required and safe.

Security checklist for theme authors

  • Use shortcode_atts() to whitelist supported attributes.
  • Escape every value for its output context, such as esc_html() for text and esc_attr() for an HTML attribute.
  • Filter enclosed HTML with an intentional policy such as wp_kses_post(), or escape it as plain text.
  • Do not treat shortcode attributes supplied by visitors as trusted input.
  • Return complete, valid markup from the callback and keep side effects out of rendering where possible.

Shortcode API references

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.