Back to Blog

WordPress Shortcodes: Complete Guide with Examples

Shortcodes let you add dynamic content to WordPress posts and pages with simple bracketed tags. From displaying the current date to showing user-specific content, shortcodes bridge the gap between static content and dynamic functionality.

Key Takeaways

  • Shortcodes are bracketed tags like [shortcode] that execute PHP code
  • WordPress includes built-in shortcodes for galleries, audio, video, and more
  • Custom shortcodes are created with add_shortcode() in functions.php
  • Shortcodes can accept parameters and wrap content
  • For 50+ ready-to-use shortcodes, consider a shortcode plugin instead of coding each one

What Are WordPress Shortcodes?

Shortcodes are small pieces of code wrapped in square brackets that WordPress replaces with dynamic content when the page loads. They were introduced in WordPress 2.5 to let non-developers add complex functionality without writing PHP.

When WordPress renders a page, it scans the content for registered shortcode tags and replaces them with the output of their associated PHP functions.

// In your content:
[current_year]

// Output on the page:
2026

Built-in WordPress Shortcodes

WordPress includes several shortcodes by default:

Shortcode Purpose Example
[gallery] Display image gallery [gallery ids="1,2,3"]
[audio] Embed audio player [audio src="file.mp3"]
[video] Embed video player [video src="file.mp4"]
[playlist] Audio/video playlist [playlist ids="1,2,3"]
[caption] Image with caption [caption]<img> Caption text[/caption]
[embed] Embed external content [embed]https://youtube.com/...[/embed]

Creating Custom Shortcodes

To create a shortcode, use the add_shortcode() function in your theme's functions.php or a custom plugin:

// Basic shortcode - no parameters
add_shortcode('current_year', 'display_current_year');
function display_current_year() {
    return date('Y');
}

// Usage: [current_year]
// Output: 2026

Shortcodes with Parameters

Shortcodes can accept attributes that modify their output:

// Shortcode with parameters
add_shortcode('button', 'custom_button_shortcode');
function custom_button_shortcode($atts) {
    // Set defaults and merge with user attributes
    $atts = shortcode_atts(array(
        'text' => 'Click Here',
        'url'  => '#',
        'color' => 'blue'
    ), $atts);

    return sprintf(
        '<a href="%s" class="btn btn-%s">%s</a>',
        esc_url($atts['url']),
        esc_attr($atts['color']),
        esc_html($atts['text'])
    );
}

// Usage: [button text="Learn More" url="/about" color="green"]

Enclosing Shortcodes

Shortcodes can wrap content between opening and closing tags:

// Enclosing shortcode
add_shortcode('highlight', 'highlight_shortcode');
function highlight_shortcode($atts, $content = null) {
    $atts = shortcode_atts(array(
        'color' => 'yellow'
    ), $atts);

    return sprintf(
        '<span style="background-color: %s;">%s</span>',
        esc_attr($atts['color']),
        do_shortcode($content) // Process nested shortcodes
    );
}

// Usage: [highlight color="pink"]Important text[/highlight]

Common Shortcode Examples

Display Current Date

add_shortcode('date', 'current_date_shortcode');
function current_date_shortcode($atts) {
    $atts = shortcode_atts(array(
        'format' => 'F j, Y'
    ), $atts);

    return date($atts['format']);
}

// [date] = April 10, 2026
// [date format="Y-m-d"] = 2026-04-10

Show Content to Logged-in Users Only

add_shortcode('members_only', 'members_only_shortcode');
function members_only_shortcode($atts, $content = null) {
    if (is_user_logged_in()) {
        return do_shortcode($content);
    }
    return '<p>Please log in to view this content.</p>';
}

// [members_only]Secret content here[/members_only]

Display User Information

add_shortcode('user_name', 'user_name_shortcode');
function user_name_shortcode() {
    if (is_user_logged_in()) {
        $user = wp_get_current_user();
        return esc_html($user->display_name);
    }
    return 'Guest';
}

// Hello, [user_name]!

Recent Posts List

add_shortcode('recent_posts', 'recent_posts_shortcode');
function recent_posts_shortcode($atts) {
    $atts = shortcode_atts(array(
        'count' => 5,
        'category' => ''
    ), $atts);

    $args = array(
        'posts_per_page' => intval($atts['count']),
        'post_status' => 'publish'
    );

    if (!empty($atts['category'])) {
        $args['category_name'] = sanitize_text_field($atts['category']);
    }

    $posts = get_posts($args);

    if (empty($posts)) {
        return '<p>No posts found.</p>';
    }

    $output = '<ul class="recent-posts">';
    foreach ($posts as $post) {
        $output .= sprintf(
            '<li><a href="%s">%s</a></li>',
            get_permalink($post->ID),
            esc_html($post->post_title)
        );
    }
    $output .= '</ul>';

    return $output;
}

// [recent_posts count="3" category="tutorials"]

Display Site Information

add_shortcode('site_info', 'site_info_shortcode');
function site_info_shortcode($atts) {
    $atts = shortcode_atts(array(
        'show' => 'name'
    ), $atts);

    switch ($atts['show']) {
        case 'name':
            return get_bloginfo('name');
        case 'description':
            return get_bloginfo('description');
        case 'url':
            return home_url();
        case 'admin_email':
            return antispambot(get_bloginfo('admin_email'));
        default:
            return '';
    }
}

// [site_info show="name"]
// [site_info show="description"]

Useful Shortcode Patterns

Pattern Use Case Example
Dynamic dates Evergreen content [year], [date], [time]
User personalization Personalized greetings [user_name], [user_email]
Conditional content Role-based access [if_logged_in], [if_admin]
Site information Avoid hardcoding [site_url], [site_name]
Content queries Dynamic listings [recent_posts], [related_posts]
Utility Common elements [button], [divider], [spacer]

Writing shortcodes from scratch takes time. Essential Shortcodes Pro includes 50+ ready-to-use shortcodes for dates, user info, conditional content, and more. One plugin instead of dozens of functions.php snippets.

Shortcodes in Gutenberg

The block editor includes a dedicated Shortcode block. You can also type shortcodes directly into paragraph blocks.

Adding the Shortcode Block

  1. Click the + button to add a block
  2. Search for "Shortcode"
  3. Add the block and enter your shortcode

Alternatively, type the shortcode in any text block. WordPress processes it on the frontend even if you don't see the output in the editor.

Shortcodes in Widgets

Shortcodes work in text widgets by default (since WordPress 4.9). Just add your shortcode to a Text widget or Custom HTML widget.

For older WordPress versions, you may need to add this to functions.php:

add_filter('widget_text', 'do_shortcode');

Shortcodes in Theme Files

To use shortcodes in PHP template files, use the do_shortcode() function:

// In a theme template
<?php echo do_shortcode('[recent_posts count="3"]'); ?>

// With content
<?php
echo do_shortcode('[members_only]
    <p>This is premium content.</p>
[/members_only]');
?>

Shortcode Best Practices

Always Escape Output

// Bad - XSS vulnerability
return '<a href="' . $url . '">' . $text . '</a>';

// Good - escaped
return '<a href="' . esc_url($url) . '">' . esc_html($text) . '</a>';

Use Unique Prefixes

Prevent conflicts with other plugins by prefixing your shortcode names:

// Might conflict with another plugin
add_shortcode('button', 'my_button');

// Better - prefixed
add_shortcode('mytheme_button', 'my_button');

Return, Don't Echo

Shortcode callbacks must return output, not echo it:

// Wrong - will output in wrong place
function bad_shortcode() {
    echo "Hello";
}

// Correct - returns output
function good_shortcode() {
    return "Hello";
}

Support Nested Shortcodes

If your shortcode wraps content, process nested shortcodes:

function wrapper_shortcode($atts, $content = null) {
    // do_shortcode() processes any shortcodes inside $content
    return '<div>' . do_shortcode($content) . '</div>';
}

Removing Shortcodes

To remove a registered shortcode:

// Remove a specific shortcode
remove_shortcode('gallery');

// Remove all shortcodes from content
$clean_content = strip_shortcodes($post->post_content);

Debugging Shortcodes

If a shortcode isn't working:

  1. Check registration: Ensure add_shortcode() is called
  2. Check hooks: Code should run on init or earlier
  3. Check spelling: Shortcode names are case-sensitive
  4. Check conflicts: Another plugin might use the same name
  5. Check return: Callback must return, not echo
// List all registered shortcodes
global $shortcode_tags;
echo '<pre>' . print_r($shortcode_tags, true) . '</pre>';

50+ Shortcodes Ready to Use

Category Examples Use Cases
Date/Time [year], [date], [time], [month] Evergreen content, copyright notices
User Info [username], [email], [role], [avatar] Personalization, member areas
Conditional [if_logged_in], [if_role], [if_page] Role-based content, A/B testing
Site Info [site_name], [site_url], [admin_email] Avoid hardcoding, multi-site
Content [recent_posts], [word_count], [read_time] Dynamic listings, post metadata

Instead of writing dozens of functions: Essential Shortcodes Pro includes 50+ shortcodes covering dates, user info, conditional display, site information, and content queries. All with a visual dashboard.

One-time payment. No subscriptions. Lifetime updates.

Get Essential Shortcodes Pro - $29

Summary

Shortcodes remain a powerful way to add dynamic content to WordPress without Gutenberg blocks. Whether you're creating custom shortcodes in functions.php or using a plugin for pre-built functionality, understanding how shortcodes work helps you build more flexible WordPress sites.

H

Haohunter

WordPress developer building lightweight plugins that solve real problems. No bloat, no subscriptions, just tools that work.