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
- Click the + button to add a block
- Search for "Shortcode"
- 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:
- Check registration: Ensure add_shortcode() is called
- Check hooks: Code should run on init or earlier
- Check spelling: Shortcode names are case-sensitive
- Check conflicts: Another plugin might use the same name
- 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 - $29Summary
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.