8.3 Calling Shortcodes: Self-Closing and Paired
Now, let’s talk about actually calling these shortcodes. You’ve got your shortcode name, and you’re ready to plaster it all over your posts. There are two ways to do this, and WordPress, in its infinite wisdom, decided to make them look exactly like HTML tags. This is either a moment of pure genius or a recipe for confusion, depending on how much coffee you’ve had. I lean towards genius, because it’s immediately familiar.
The first type is the self-closing shortcode. This is for when your shortcode is a lone wolf—it doesn’t need to wrap any content to do its job. Think of it like an <img> or <br> tag. You’re just dropping a little package of functionality right into the page.
[my_awesome_gallery]
That’s it. No fuss, no muss. WordPress sees that, finds the corresponding my_awesome_gallery function, runs it, and replaces the bracket nonsense with whatever glorious HTML you told it to spit out. You’ll use this for things like embedding a contact form, displaying a random quote, or outputting a server-side date—things that exist independently of the surrounding text.
But what if you need to wrap something? What if the point of the shortcode is to transform content you give it? Enter the enclosing (or paired) shortcode. This is for when your shortcode is more of a decorator. You give it content, it does something to that content, and gives it back, fancier.
The syntax uses an opening tag and a closing tag, just like a proper HTML element.
[highlight color="yellow"]This is some very important text you should definitely read.[/highlight]
See how that works? The content in the middle—This is very important text...—is the $content variable that gets passed to your shortcode function. Your function’s job is to take that string, do something with it (like wrap it in a <span> with a yellow background), and return it.
Here’s the critical part, and where everyone messes up at least once: The closing tag is non-negotiable. Forget the closing [/shortcode]? WordPress will keep looking for it until the end of time, or the end of the post, whichever comes first. It will consume all the content that follows the opening tag, expecting it to be the $content, and your page will look utterly broken. It’s a rite of passage. You’ll do it, I’ve done it, we’ve all done it. Just be glad it’s not a while (true) loop.
The Weird Hybrid: Combining Attributes and Content
You can, of course, combine attributes and enclosed content. This is where shortcodes get their real power. The attributes define how the transformation happens, and the content defines what gets transformed.
[format type="code" language="php"]
function is_this_great() {
return 'Yes, absolutely.';
}
[/format]
In this case, the shortcode function would receive both an array of attributes (['type' => 'code', 'language' => 'php']) and the string of content (the PHP code). It could then use a syntax highlighter library to make that code block look beautiful.
The Parser’s Greedy, Hungry Nature
I need to be direct with you about a quirk: the WordPress shortcode parser is, to put it mildly, a bit greedy. It will try to find the very first closing tag it can. This becomes a massive headache if you try to nest shortcodes of the same name. Just don’t do it.
This will fail spectacularly:
[quote]He said: [quote]Nested things![/quote] and it was profound.[/quote]
The parser will see the first [/quote] and assume it’s closing the first [quote], leaving and it was profound.[/quote] just sitting there as plain text, utterly confusing the visitor. The solution? Either use different shortcode names for nested levels or find another way to structure your content. The designers made a choice for simplicity over complexity here, and it’s a trade-off you just have to code around.
The best practice? Keep it simple. Use self-closing for independent functions and enclosing shortcodes for content transformation. And for the love of all that is good, always remember your closing tag. Your sanity depends on it.