Creating Custom Shortcodes in WordPress
Basic Approach
A shortcode is a WordPress-specific code that lets you add content anywhere using square brackets like [my_shortcode]
. Here's how to create one:
- Register your shortcode using
add_shortcode()
- Create a callback function that returns the content
- Place the code in your theme's
functions.php
or in a custom plugin
Basic Implementation
Simple shortcode that returns static text:
function my_first_shortcode() {
return '<div class="custom-content">Hello from my shortcode!</div>';
}
add_shortcode('my_greeting', 'my_first_shortcode');
Usage: [my_greeting]
Shortcode with Attributes
Shortcode that accepts and processes parameters:
function custom_button_shortcode($atts) {
$attributes = shortcode_atts(array(
'text' => 'Click Me',
'url' => '#',
'color' => 'blue'
), $atts);
return sprintf(
'<a href="%s" class="button" style="background-color: %s">%s</a>',
esc_url($attributes['url']),
esc_attr($attributes['color']),
esc_html($attributes['text'])
);
}
add_shortcode('custom_button', 'custom_button_shortcode');
Usage: [custom_button text="Learn More" url="https://example.com" color="red"]
Shortcode with Content
Shortcode that wraps content between opening and closing tags:
function custom_box_shortcode($atts, $content = null) {
$attributes = shortcode_atts(array(
'type' => 'info'
), $atts);
return sprintf(
'<div class="custom-box %s">%s</div>',
esc_attr($attributes['type']),
do_shortcode($content)
);
}
add_shortcode('box', 'custom_box_shortcode');
Usage: [box type="warning"]Your content here[/box]
Security Best Practices
-
Always sanitize inputs:
- Use
esc_attr()
for attributes
- Use
esc_url()
for URLs
- Use
esc_html()
for text output
- Use
wp_kses()
for HTML content
-
Validate parameters:
function secure_shortcode($atts) {
$attributes = shortcode_atts(array(
'type' => 'default'
), $atts);
$allowed_types = array('default', 'primary', 'secondary');
if (!in_array($attributes['type'], $allowed_types)) {
$attributes['type'] = 'default';
}
return '<div class="' . esc_attr($attributes['type']) . '">Content</div>';
}
add_shortcode('secure', 'secure_shortcode');
Common Pitfalls to Avoid
- Don't echo content, return it
- Don't forget to escape output
- Avoid naming conflicts with existing shortcodes
- Don't process heavy operations without caching
- Remember shortcodes are case-insensitive
Helpful Plugins
-
Shortcoder
-
Generate Shortcodes
Advanced Tips
- Add shortcode preview in the editor:
function register_shortcode_preview() {
if (current_user_can('edit_posts')) {
wp_enqueue_script('shortcode-preview', 'path/to/script.js');
}
}
add_action('admin_enqueue_scripts', 'register_shortcode_preview');
- Cache intensive shortcode outputs:
function cached_shortcode() {
$cache_key = 'my_shortcode_cache';
$output = get_transient($cache_key);
if (false === $output) {
$output = 'Processed content';
set_transient($cache_key, $output, HOUR_IN_SECONDS);
}
return $output;
}
add_shortcode('cached', 'cached_shortcode');
Remember to test your shortcodes thoroughly in different contexts and with various content combinations before deploying to production.