How to Create Nested Shortcodes in WordPress

By Craig Buckler
We teamed up with SiteGround
To bring you up to 65% off web hosting, plus free access to the entire SitePoint Premium library (worth $99). Get SiteGround + SitePoint Premium Now

When an editor adds a WordPress [shortcode] to a post or page, it’s replaced by the returned output of a handler function within a plug-in or the theme’s functions.php file. Let’s create a simple example:


// create a styled button
function ContactButton($params, $content = null) {

	extract(shortcode_atts(array(
		'url' => '/contact-us',
		'type' => 'style1'
	), $params));

	return
		'<a href="' . $url . '" class="button ' . $type. '">' . ucwords($content) . '</a>';

}
add_shortcode('button','ContactButton');

When the following code is encountered in page or post:


[button]contact us today[/button]

it’ll be translated to:


<a href="/contact-us" class="button style1">Contact Us Today</a>

The editor’s job is made far easier and they don’t need to worry about learning HTML. Let’s look at another example which creates a simple callout box:


// callout box
function CalloutBox($params, $content = null) {

	extract(shortcode_atts(array(
		'type' => 'style1'
	), $params));
	
	return
		'<aside class="callout ' . $type . '">' . $content . '</aside>';

}
add_shortcode('callout','CalloutBox');

But what if our editor wants to insert a button inside their callout box?…


[callout]For more information [button]contact us today[/button][/callout]

As it stands, the current code will fail. The CalloutBox function is called first but the inner [button] will not be translated accordingly.

The key function for fixing the problem is do_shortcode() — it applies WordPress’s shortcode filter to any content. In this case, we want to allow the editor to add a [button] within our [callout] so we’d change modify the return statement of CalloutBox accordingly:


return
	'<aside class="callout ' . $type . '">' . 
	do_shortcode($content) . 
	'</aside>';

The nested code above will now work as expected. However, the editor wouldn’t be permitted to nest a [callout] inside a [button]. It’s flexibility such as this which makes WordPress a joy to use — version 3.3 is available now.

The most important and interesting stories in tech. Straight to your inbox, daily. Get Versioning.
We teamed up with SiteGround
To bring you up to 65% off web hosting, plus free access to the entire SitePoint Premium library (worth $99). Get SiteGround + SitePoint Premium Now
Login or Create Account to Comment
Login Create Account