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:
- The name of the shortcode. This is what you’ll use inside brackets in the post.
- 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;
Thanks so much, Ashley, I was just looking for something like this! You always make things really easy to follow. 🙂
You’re welcome. 🙂
Thanks so much for this Ashley, it came at exactly the right moment! I’ve been looking for a plugin that I could add a few shortcodes with but I could never really understand it and ended up getting frustrated and moved out and NOW YOU DID THIS <3 A million times thank you 🙂
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.
I love this! So excited to try it out.
Correct me if I am wrong but if WordPress updates is functions.php file going to be overwritten?
Not if WordPress updates. Only if your theme updates.
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).
A child theme or a plugin. (I’d suggest a plugin.)
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.
And to prevent this from happening the better way would be to create custom plugin with my shortcodes (instead of changing fuctions.php)? I think you once told me that was better practice.
Yep you can definitely do that. 🙂
Great. Thanks for help. 🙂
And awesome shortcodes tutorial. I forgot to say that. 🙂
Great tutorial! Very clear and very useful! I needed it just… right now 🙂
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!) 😀
where the heck do you insert this code stuff at to create category archive page? I’ve been search the web and should have known to just come to your website first.
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.
Gread
If I want display text in those posts not just display link. How to do that?