How to Create WordPress Shortcodes, and Why I Love Them

wordpress shortcode love

Before we look at how to register WordPress custom shortcodes, let’s be clear: If there’s one thing Gutenberg is about to kill, it’s the use of WordPress shortcodes in content creation.

The Gutenberg team use the disgusting but accurate term “mystery meat” for the exact kind of user experience shortcodes give. Quick, what does the following code, in your post editing screen, look like on the front end of your site?

No idea. (That’s an actual shortcode here on WPShout, by the way.) When Gutenberg’s live-previewing Blocks land in WordPress Core, they’ll immediately make shortcodes feel like the horrible choice for post editing that they actually are.

Shortcodes are massively useful. What matters is what you use them for.

So am I planning to stop using shortcodes in my work as a WordPress developer? Heck no! I’ve written new shortcodes on client projects maybe 5 times this week so far, and I don’t plan on slowing down.

Shortcodes are massively useful. What matters is what you use them for.

Silly End User, Shortcodes are For Developers

Shortcodes are an awful experience for users. But for developers, they’re among the easiest and most useful testing tools in WordPress.

The problem with shortcodes, again, is that they’re an awful experience for users. But for developers, they’re just about the most useful testing tool there is, because they help you get your code on the page with an absolute minimum of effort.

In this article, we’ll make sure you know how to use add_shortcode() to register custom WordPress shortcodes, with passed-in arguments and content if necessary. Then we’ll dive into some examples that show how WordPress shortcodes are massively useful for all kinds of WordPress development needs.

One quick thing before we dive in. If you’re looking to learn WordPress development, we’ve written the best guide to it out there:

The Best Way to Learn WordPress Development

Get Up and Running Today

Up and Running is our complete “learn WordPress development” course. Now in its updated and expanded Third Edition, it’s helped hundreds of happy buyers learn WordPress development the fast, smart, and thorough way.

Here’s what they have to say:

“I think anyone interested in learning WordPress development NEEDS this course. Watching the videos was like a bunch of lights being turned on.” -Jason, WordPress developer

“Other courses I’ve tried nearly always lack clear explanations for why WordPress does things a certain way, or how things work together. Up and Running does all of this, and everything is explained clearly and in easy-to-understand language.” -Caroline, WordPress freelancer

How to Create WordPress Shortcodes

The first step in using shortcodes effectively as a WordPress developer is knowing how to register your own custom shortcodes. This section walks you through that process.

Registering a Custom Shortcode: the Most Basic Example

David recorded a great video Quick Guide covering the most basic possible use of add_shortcode() to register a custom shortcode. That tutorial also covers how to register a plugin to hold the custom shortcode itself (which is better than using your theme’s functions.php). Without that plugin boilerplate at the top, the code example looks like this:

add_shortcode( 'wpshout_sample_shortcode', 'wpshout_sample_shortcode' );
function wpshout_sample_shortcode() {
    return 'hi!';

Notice a few things:

  • You use add_shortcode() to register a new shortcode.
  • You name your shortcode whatever you want using the first argument of add_shortcode(). You’d put the shortcode we just registered onto the page with [wpshout_sample_shortcode].
  • With the second argument of add_shortcode(), you name a shortcode handler function. This function will be used to “handle” the shortcode: what that means is that it will return a text string that WordPress will then output onto the page. In this case, the function wpshout_sample_shortcode() simply returns “hi!”—which is what will appear on the page anytime[wpshout_sample_shortcode] is called.

This very simple shortcode setup is most of what we’ll be using in the examples below, but for completeness it’s also important to show you how to create shortcodes with content, and shortcodes that take passed-in arguments.

Creating a Custom Shortcode with Content and Passed-in Attributes

It’s also good to know how to create WordPress shortcodes that accept user-specified data. Here’s a shortcode with two new elements: a user-definable align attribute, and user-defined content inside the shortcode itself.

[pullquote_shortcode align="left"]This is the text that should 
go inside my pullquote[/pullquote_shortcode] 

What do we “do with” this new data? By default, the shortcode handler function can take two arguments:

  1. An array of attributes
  2. The text content inside the shortcode.

Adding these to our handler function lets us work with them, as in this example:

// $attributes is an array of passed-in attributes. It would look like
// [ 'align' => 'left' ].
// $content is a string of passed-in shortcode content. It would look like
// 'This is the text that should go inside my pullquote'.
function pqsc_process_shortcode( $attributes, $content = null ) {
	// Save each attribute's value to its own variable.
	// This creates a variable $align with a value of 'left'.
	extract( shortcode_atts( array(
		'align' => ''
	), $attributes ) ); 
	// Return a string to display on the page
	return '<blockquote class="pullquote align' . $align . '">' . $content . '</blockquote>';

The trickiest thing here is the combination of PHP’s default extract function extract() and WordPress’s shortcode_atts() PHP function.


shortcode_atts() is a WordPress-provided function that combines an array of defaults with the array of attributes passed into the function itself. So by itself, it says that the align attribute has a default value of '', an empty string—and that that default can be overwritten by whatever is actually the value for the align element in the passed-in $attributes array. For us, that value is 'left'.


extract() is a PHP function which takes each element of an array and makes a similarly-named variable out of it. So in the example above, we end up with $align now being a variable of type string with a value of 'left'. If we had other passed-in attributes, they’d become variables too.

Use extract() with care because of the danger of duplicate variable names.

By the way, make sure your extract() function doesn’t let multiple variables take the same name! So don’t name one of your shortcode arguments, say, post if you plan to use extract(). Because of these potential confusions, extract() isn’t the most secure PHP function overall, but boy is it convenient in this case. So fair warning.

That’s a Fancy Shortcode

That’s about as intricate as shortcodes get, so if you understand the example above, you’re pretty much set on the tech side for registering your own custom shortcodes. Now, what can we, as WordPress developers, do with WordPress shortcodes?

Why Shortcodes Are So Handy for a WordPress Developer (with Demos)

Shortcodes let me get anything I’m doing in PHP directly onto the page.

I love shortcodes for one reason: because they let me get anything I’m doing in PHP directly onto the page. They’re great for testing code, understanding what a function or variable is doing, and all kinds of other getting-visibility jobs. And once you’re used to registering and using them they take perhaps less setup than any other sensible way of displaying your code.

Below are some examples to make the point. Note that in these examples, I’m using PHP output buffering: see David’s excellent article on why output buffering is so handy for shortcodes.

Example: Using a Shortcode to Test a WP_Query

Let’s say I’m writing a WP_Query and I want to know what it’s outputting:

add_shortcode( 'dump_query', 'dump_query' );
function dump_query() {
	// Write query
	$args = array(
		'posts_per_page' => 1
	$query = new WP_Query( $args );

	// Return output
	var_dump( $query );
	return ob_get_clean();

Then I just write [dump_query] anywhere, in any sample post or page on my site:

And I get something—an error, an array, or whatever—right in the page content:

shortcode query test

Example: Searching Comment Text

Let’s say I want to do a word search through the site’s ten most recent approved comments:

add_shortcode( 'try_markup', 'try_markup' );
function try_markup() {
	$args = array(
		'status' => 'approve',
		'number' => '10'
	$comments = get_comments($args);
	foreach($comments as $comment) :
		echo $comment->comment_content . '<hr>';
	return ob_get_clean();

With [try_markup] on the page, that gives us:
recent comments shortcode

Example: Display All Recent Medium-Sized Images

Wait, I need to look through (and maybe save into a folder) the “medium” image size of each of my last 50 image uploads:

add_shortcode( 'rec_images_medium', 'rec_images_medium' );
function rec_images_medium() {
	$query_images_args = array(
		'post_type'      => 'attachment',
		'post_mime_type' => 'image',
		'post_status'    => 'inherit',
		'posts_per_page' => 50,
	$query_images = new WP_Query( $query_images_args );

		foreach( $query_images->posts as $image ) :
			echo wp_get_attachment_image( $image->ID, 'medium' );
			echo '<hr>';
	return ob_get_clean();

The result with [rec_images_medium] on the page:

The Pattern Here: Getting Stuff Onto the Page

Shortcodes are one of the easiest and lightest-weight ways to get stuff to display onto the page.

Do you see what I like about shortcodes? These use cases are the type of random need that can come up on the PHP side of any WordPress project, and in each case registering a shortcode was a very simple, easy way to turn my PHP code into something visual I could work with and get feedback from. In general, shortcodes are one of the easiest and lightweight-iest ways for a WordPress developer to get stuff—any stuff—to display onto the page, so you can use it, debug it, test it, tweak it, and what have you. And you know exactly where to expect it on the page, because you’ve placed the shortcode yourself.

So if you don’t know how to get your code onto the page, don’t reach for custom page templates, the_content filters, or anything else. Reach for a shortcode.

Still Good for Individual Client Use

I’ll still be using shortcodes for private client projects where they’ll only have one or a few users.

I’ll put in one more plug for shortcodes: Gutenberg or no, I’ll still be using shortcodes for individual client projects until registering a Gutenblock is way easier than registering a shortcode. I’m guessing that day may never come.

As an example, I’ve got a client right now who needs to be able to insert an HTML quiz in his post content. I’m happy to train him, individually, in using the ugly UI of a shortcode, because wrapping HTML into a shortcode is so easy (as we’ve seen) and registering a whole Gutenblock will probably be overkill even when Gutenberg actually arrives.

It’s just for commercially released products, or products that will be used on one team but by large numbers of people, that shortcodes are nearing a dead end.

WordPress Shortcodes: Good For What They’re Good For

Shortcodes are not great for users, but man do I find them handy as a developer. I hope you better understand how to create custom WordPress shortcodes—with or without user-defined data—and why and when to use them in your WordPress development work.

Anything I missed? We’d love to hear from you in the comments below.

6 Responses


  • Gagan says:

    Quite informative, there are short code plugins out there which make my work bit easier.

  • thanks, came here for something different, but loved the article. still, i am courious, what you think is a better way for clients / users. GUI and everything, that is not rechable through a GUI they should not touch? Hand them a page-builder and watch them messing up? or do you think there is no “one for all”?

    I always struggle a bit with client expectations, that wordpress means, the now can “change _everything_ on the site” themselves…

    • Fred Meyer Fred Meyer says:

      Good question! I actually have had success training users in page builders (I use Beaver Builder), so I’d say that’s my closest thing to a recommendation. (Most good page builders will render shortcodes, by the way, so your users can at least live-preview shortcodes you write yourself.)

      Beyond that, I agree that it’s important to manage expectations around complex layout/data/functionality/etc. changes being a completely hands-off thing in WordPress.

      • Thanks for your answer. Most pagebuilders I found quite overload and in the end not suitable for customers, but if you can recommand beaver, I will have a look at it.

        In the end, I always ask the customers, how skilled and patient they are with.. let’s say styling a word document? Based on the answer I can judge, if they will be able or not. ^^

  • Diego says:

    Hello, thanks for post ! I have a function with html+css+js for a calendar with some math things. And i want to convert it into a shortcode, to not copy/paste code in differentes places. Is it posible have a example of a plugin using static content with a shortcode function.


  • Stevan says:

    Instead of result I get actual shortcode on my post, like this [rec_images_medium].