How to Create Your Own WordPress Shortcodes

Could you do a (or do you know of any existing) tutorial on shortcodes? I know that my theme supports some, and I know of some plugins that let you create them, but I’m not totally sure how they work.

Specifically, I have a page for one category of posts aside from the category page, so I could add an ‘about’ section and subscribe form (for reference, http://www.bookbumblings.com/blogging-tips).

Right now, I’m manually adding each post’s link, but I’m pretty sure this is something shortcodes could do. I’d love to do this with each category that has its own newsletter, but it’s not feasible when doing it manually.

Thanks!

Brittany Berger

Hi Brittany! First I’m going to talk about what a shortcode actually is, then we’ll go over how to create it.

What is a WordPress shortcode?

A shortcode is basically when you enter in a placeholder into your post, like this: [signature]. Then, this placeholder bit of text triggers a PHP command that actually generates the output.

So, for example, in the Ultimate Book Blogger Plugin we have shortcodes for review indexes. You can enter [index-title] and that automatically displays an archive of your book reviews, sorted by title. But how does this actually work?

That [index-title] snippet corresponds to a block of PHP code. When you type in [index-title] it triggers that PHP code, which I coded to generate the review archive.

So, in short, in order to create a custom shortcode you do have to code your own custom PHP.

Make your own simple shortcode to insert HTML snippets

Just because you have to use PHP doesn’t mean it always has to be complicated. You can use shortcodes to insert snippets of HTML or images that you include often (like a post signature). To do that, simply edit your functions.php file and paste in this code:

function my_custom_shortcode() {
	return '<img src="SIGNATURE URL" alt="Ashley">';
}
add_shortcode('signature', 'my_custom_shortcode');

Here, all we’re doing is creating a shortcode called [signature] and when you use that, it triggers the my_custom_shortcode() function. That function outputs this HTML:

<img src="SIGNATURE URL" alt="Ashley">

Obviously you’d enter your image URL in the image tags.

But everything you want to output needs to be inside quotes after return. So if you just wanted to output text instead, you could do it like this:

function my_custom_shortcode() {
	return 'Sincerely, Ashley';
}
add_shortcode('signature', 'my_custom_shortcode');

Notice how the code is exactly the same, but I just changed what was inside return 'HTML AND TEXT HERE';

Naming your shortcode

Let’s take a look at this line really quickly:

add_shortcode('signature', 'my_custom_shortcode');

The add_shortcode() function accepts two parameters:

  1. The name of the shortcode. This is what you’ll use inside brackets in the post.
  2. The name of the function.

The name of the shortcode can be whatever you want, but it should be inside quotes. I named mine 'signature'. That means I type [signature] inside the post to trigger the shortcode.

The name of the function can also be whatever you want, but there are some restrictions. You cannot use spaces, but you can use underscores. Secondly, whatever you enter there must match what you enter after function in the first line. So, see how these two match:

function my_custom_shortcode()

And:

add_shortcode('signature', 'my_custom_shortcode');

We use my_custom_shortcode in both places. You can change that, but you must change them in both cases.

What can you use this for?

You can use this simple text/HTML method for a variety of things. Here are a few ideas:

  • Your subscribe via email form. Just insert the code from Feedburner/MailChimp/etc. Then you can create a shortcode like [email-subscribe] to insert your email subscription form.
  • Post signature image (as shown in the example).
  • Star rating graphics.
  • Your FTC disclaimer message (if you don’t have UBB to do it for you!).

Automatically display posts from a category

So we’ve covered how to use a shortcode to display simple HTML and text. Let’s build on that to display posts from a category of your choosing. In the end, you’ll enter something like [posts-in category="blogging-tips"] (where “blogging-tips” is the category slug) and that will output an unordered list of posts in that category.

Here’s the code:

function get_posts_by_category($atts) {
	$output = '';

	// Get the shortcode parameters
	extract(shortcode_atts(array(
		'category'    =>    null
	), $atts));
	
	// Build the query
	$cat_posts = array(
		'category_name'    =>	$category,
		'posts_per_page'   =>	-1,
		'order'            =>	'DESC', // You can change this to 'ASC'
		'orderby'          =>	'post_date', // You can change to 'title' to order by post title
	);
	
	// Check to make sure we have posts
	if ($cat_posts) {
		$output .= '<ul>';
		foreach ($cat_posts as $cat_post) {
			$output .= '<li><a href="' . get_permalink($cat_post) . '">' . get_the_title($cat_post) . '</a></li>';
		}
		$output .= '</ul>';
	}
	
	// Return the output
	return $output;
}
add_shortcode('posts-in', 'get_posts_by_category');

See how this is a lot more complicated?

First, in this case we’re adding attributes to the shortcode. This is the category="blogging-tips" bit I mentioned before. Because we’re using attributes, you can use this same shortcode for any category you want! You could do category="reviews" or category="stacking-the-shelves" — any category slug you have.

So inside the function declaration, we have to include a parameter for the attributes, like this:

<pre>function get_posts_by_category($atts) {

Then inside the function itself, we have to extract those attributes into variables we can use later on in the code:

// Get the shortcode parameters
extract(shortcode_atts(array(
	'category'    =>    null
), $atts));

Now we have a variable called $category, which is set to null by default. But it will be populated with whatever you enter in the shortcode parameter ([posts-in category="blogging-tips"] so $category now equals ‘blogging-tips’).

Then we have to build a custom WordPress query to fetch out the posts from the database. But we limit the posts to be only ones in the category we specified:

// Build the query
$cat_posts = array(
	'category_name'     =>	$category,
	'posts_per_page'    =>	-1,
	'order'             =>	'DESC', // You can change this to 'ASC'
	'orderby'           =>	'post_date', // You can change to 'title' to order by post title
);

You can see in the comments that you can change a couple of the variables if you want the values to be different. Also, by using 'posts_per_page' => -1 we tell WordPress to pull out EVERY post in that category. If you wanted to limit it to only 10 you could enter 'posts_per_page' => 10 instead.

Then, if we have results, we cycle through them and add them to an unordered list. For each post, we pull out the URL to the post and the post name.

// Check to make sure we have posts
if ($cat_posts) {
	$output .= '<ul>';
	foreach ($cat_posts as $cat_post) {
		$output .= '<li><a href="' . get_permalink($cat_post) . '">' . get_the_title($cat_post) . '</a></li>';
	}
	$output .= '</ul>';
}

Then, finally, we return all of our results to be used in the post itself:

return $output;
Photo of Ashley
I'm a 27 year old California girl living in England (I fell in love with a Brit!). I like to inject a little #girlpower into the WordPress development community by teaching women how to be coding badasses. more »

Don't miss my next post!

Sign up to get my blog posts sent directly to your inbox (plus exclusive store discounts!).

You might like these

Leave a Reply

(Enter your URL then click here to include a link to one of your blog posts.)

This site uses Akismet to reduce spam. Learn how your comment data is processed.

22 comments

    1. My pleasure! 🙂 And it will be a lot more simple and lightweight to just add these in yourself. If you use a plugin to do it, it will probably have an admin panel, interface, and a ton more code than what you actually need.

      Simple = better.

      1. So to prevent these shortcodes from being overwritten when a theme updates, I should do these as part of a child theme? Still looking for a way to add a comments tag at the end of the post in addition to the meta information at the top of my post. Yes I realize this is redundant. I think short codes would be the perfect solution. I also love the idea of being able to do a signature in all my new posts (but not old posts since that would produce duplicates).

        Trish recently posted: Fall Fun and the Girls Right Now
          1. I tried a signature plug-in but it wanted to attach the signature to all of my old posts as well. I didn’t really want to go back and edit 1000 posts to remove the duplicate signatures.

  1. Now, a tutorial on option panels and I’m set! (Kidding, mostly haha) Thanks for this tutorial though! This will actually probably make things much easier on the few random sites I decide to continue to do development on (or you know… my own!) 😀

    Anna recently posted: Development? No, Thank You.
    1. You can add this to your theme’s functions.php file. You can find that in Appearance > Editor, then select the “Theme Functions” file on the right-hand side.

      But you need to be extremely careful while editing this file. If you enter anything incorrectly, you could crash your whole site and it can become inaccessible until you fix it.

Recent Posts

    Random Posts