Blog Post Icon
Blog
10/29/2014

Make your own custom WordPress shortcode for pulling category posts

Hello!

WordPress is a great entry level CMS that has a vibrant and extensive development community with many free plugins and offerings to help extend your web installation significantly.

Once in a while , either with a significant WordPress update or for other reasons, the default plugins wont cut it. Sometimes when you seemingly want to do something simple, the options that a free plugin may offer either don’t work as advertised or don’t do enough.

With wordpress, creating your own shortcode that does its own query for posts is quite easy. Why would you do this when there are so many plugins out there? Well if you create your own custom post type in WordPress and are integrating other plugins or perhaps tieing all those plugins together or even further to that perhaps you want to take the custom post type and pull specific content from that post type and display it in a specific way in your home page or in a widget.

Sometimes doing this yourself instead of finding a plugin allows you much more control. The method of doing this, as I’m about to demonstrate, will show that really minimal effort is required to accomplish this feat. So why not do it yourself?

WordPress custom functions.php : make your custom shortcode

This is where all of your changes will go. In the WordPress theme directory (wp-content/themes/theme-name/functions.php) this file is located. This file allows you to make custom functions, modifications, filters and other modifications to manipulate or extend the wordpress system to suit your needs.

To create your own shortcode, its painfully simple. The shortcode wont do anything at first, obviously.

add_shortcode( 'my-shortcode', 'shortcodefunction' );

The shortcode we have created will respond as [my-shortcode] in WordPress. Calling that shortcode will call the function shortcodefunction , which we haven’t declared yet.

So what do we want this shortcode to do? How about we simply pull WordPress posts that are assigned to a particular category and display the post title and excerpt? That sounds great! Well how about we take it one step further and allow you to specify the category and the number of posts to display as shortcode options? That would make the shortcode much more dynamic and you could use it on many other sites potentially as well as in this one scenario.

Creating your custom function for the shortcode

This is where it gets fun! If you have beginner to moderate experience with PHP, I dont think you’ll have much trouble here. So lets declare our function and lets allow attributes or shortcode options to be passed to the function. I will be accepting two options in the shortcode : “length” and “category”. So an example shortcode declaration in WordPress would be something like this :

[my-shortcode legnth="4" category="MyWordpressCategory"]

So lets make our function!

function displaylistings ( $atts ) {
        $error = FALSE;
        $output = NULL;
        // create shortcode option array and assign default values
        $a = shortcode_atts( array(
                'length' => '4',
                'category' => 'DefaultCategory',
        ), $atts );
        // Make sure length field is an actual integer, otherwise exit
        if ( ctype_digit( $a['length'] ) ) {
                $length = (int)$a['length'];
        } else {
                $output = "Length isn't a valid integer!";
                return $output;
        }

        // make sure category field actually exists, otherwise exit
        if ( term_exists( $a['category'] ) == NULL ) {
                $output = 'Sorry that category doesnt exist!';
                return $output;
        }
        // build a custom wp query argument list
        $custom_query_args = array(
                'post_type' => 'post',
                'post_status' => 'publish',
                'posts_per_page' => $a['length'],
                'category_name' => $a['category']
        );

        // Get current page and append to custom query parameters array
        $custom_query_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;

        // Instantiate custom query
        $custom_query = new WP_Query( $custom_query_args );

        // Pagination fix
        $temp_query = $wp_query;
        $wp_query   = NULL;
        $wp_query   = $custom_query;

        if ( $custom_query->have_posts() ) {
                while ( $custom_query->have_posts() ) : $custom_query->the_post();
                        $output .= '

‘ . get_the_title() . ‘

‘; endwhile; } return $output; }

I’ll give a brief high level overview of what all this code does. There is comments in the code that gives some indication of what some of the code is doing.

        $error = FALSE;
        $output = NULL;

You’ll see this declared at the top of the function. This sets two variables that are declared (seemingly) multiple times throughout the function. We want to declare these and set default values so they’re not empty. $error is intended for some simple error checking and $output is the output variable that the function will spit out when the shortcode is called.

        $a = shortcode_atts( array(
                'length' => '4',
                'category' => 'OtherListings',
        ), $atts );

This is an array that will parse two options that the shortcode can use. Anything else will be ignored. We are looking for length (number of posts to spit out) and which category to look for. You’ll see default variables set here. I should note that the function currently isn’t using the length variable yet, but it could easily be incorporated into the while loop in the function to loop X times until length is met. I’m sure you could figure it out šŸ˜‰

        // Make sure length field is an actual integer, otherwise exit
        if ( ctype_digit( $a['length'] ) ) {
                $length = (int)$a['length'];
        } else {
                $output = "Length isn't a valid integer!";
                return $output;
        }

        // make sure category field actually exists, otherwise exit
        if ( term_exists( $a['category'] ) == NULL ) {
                $output = 'Sorry that category doesnt exist!';
                return $output;
        }

These two if-statements are what the $error variable is being used for. I want to make sure that a) the category specified as an option actually exists and the length variable specified is actually an integer. If any of those two conditions are not met, an error will be spit out when the shortcode is called for the user to easily identify that “oh I passed an invalid option in the shortcode”. Making things visible and identifiable and catching any common errors is a good best practice.

        // build a custom wp query argument list
        $custom_query_args = array(
                'post_type' => 'post',
                'post_status' => 'publish',
                'posts_per_page' => $a['length'],
                'category_name' => $a['category']
        );

        // Get current page and append to custom query parameters array
        $custom_query_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;

        // Instantiate custom query
        $custom_query = new WP_Query( $custom_query_args );

        // Pagination fix
        $temp_query = $wp_query;
        $wp_query   = NULL;
        $wp_query   = $custom_query;

        if ( $custom_query->have_posts() ) {
                while ( $custom_query->have_posts() ) : $custom_query->the_post();
                        $output .= '

‘ . get_the_title() . ‘

‘;

The rest of the function above does a standard custom query / loop to pull posts of the specified category. Length is specified in the WordPress query itself in the context of pagination but you could modify all this to do whatever you want basically. Add as many options as you want!

This is intended to give you an overview and to show you how easy it is to create your own function. Its best for you to use this as such (a guide) and create the function yourself and play around with what you can do with calling functions with shortcode, pulling data and manipulating said data with wordpress. WordPress has many built in functions / calls that you could inherently use with custom functions like this. The sky’s the limit! If your shortcode is good enough, you could always create a plugin and share it with everyone šŸ˜‰

At Shift8, we cater to all sorts of businesses in and around Toronto from small, medium, large and enterprise projects. We are comfortable adapting to your existing processes and try our best to compliment communication and collaboration to the point where every step of the way is as efficient as possible.

Our projects are typically broken into 5 or 6 key “milestones” which focus heavily on the design collaboration in the early stages. We mock-up any interactive or unique page within your new website so that you get a clear picture of exactly how your design vision will be translated into a functional website.

Using tools like Basecamp and Redpen, we try to make the process simple yet fun and effective. We will revise your vision as many times as necessary until you are 100% happy, before moving to the functional, content integration and development phases of the project.

For the projects that are more development heavy, we make sure a considerable amount of effort is spent in the preliminary stages of project planning. We strongly believe that full transparency with a project development plan ensures that expectations are met on both sides between us and the client. We want to ensure that the project is broken into intelligent phases with accurate budgetary and timeline breakdowns.

Approved design mock-ups get translated into a browse-ready project site where we revise again and again until you are satisfied. Client satisfaction is our lifeblood and main motivation. We aren’t happy until you are.

Need Web Design?

Fill out the form to get a free consultation.

shift8 web toronto – 416-479-0685
203A-116 geary ave. toronto, on M6H 4H1, Canada
Ā© 2023. All Rights Reserved by Star Dot Hosting Inc.

contact us
phone: 416-479-0685
toll free: 1-866-932-9083 (press 1)
email: sales@shift8web.com

Shift8 Logo