Welcome to the fourth part of our plugin building series! So far on our journey, we’ve set ourselves up with structure in mind by using the WordPress Plugin Boilerplate, and created a separate place for our content to live in the back end by registering our own custom post type.
This time around, we’ll be giving our plugin users options for actually displaying quotes that are entered into the system. We’ll kick things off by building in some functionality to handle the random selection of quotes, and then move on to looking at creating our own shortcode options.
By the time we’re finished this instalment, we should be able to enter content via the admin to our heart’s content, and easily display it on the front end in a manner familiar from countless other plugins.
Let’s start by getting access to the data we’re interested in.
Accessing Our Quotes
Having gone to the trouble of using a custom post type to store our quotes, the first item to take care of is returning results from that set of data alone. A quick trip to the relevant part of the Plugin Handbook gives us a nice overview of how to do this, along with some handy illustrative code:
$args = array( 'post_type' => 'product', 'posts_per_page' => 10 ); $loop = new WP_Query( $args ); while ( $loop->have_posts() ) : $loop->the_post(); the_title(); echo '<div class="entry-content">'; the_content(); echo '</div>'; endwhile;
As you can see above, we’ll be using WP_Query() to fetch results, and passing in arguments defining the particular post type we’re after and the number of results per page to return. That looks fine and dandy in theory so far, but it raises two immediate issues:
- How do we quickly test that it works?
- Where do we slot this into our setup using the WordPress Plugin Boilerplate?
Let’s take those questions one at a time.
Testing We Can Return Random Quotes From the Database
As both the WP_Query() documentation and Rachel McCollin’s highly recommended Mastering WP_Query series point out, we need to be running inside The Loop to test things out.
We’ve got nothing fancy in our local test site at the moment, so we’re simply going to pop some exploratory code into the main page template of our default theme to quickly see if things are working. In our case, that’s located at /themes/twentysixteen/page.php. Our custom post type was previously defined as rdm-quote, so all we’re really doing below is retrieving those posts and sticking them in a list on screen.
$args = array( 'post_type' => 'rdm-quote' ); // Custom query. $query = new WP_Query( $args ); // Check that we have query results. if ( $query->have_posts() ) { echo '<ul>'; // Start looping over the query results. while ( $query->have_posts() ) { $query->the_post(); ?> <li> <a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"> <?php the_title(); ?> </a> </li> <?php } echo '</ul>'; } // Restore original post data. wp_reset_postdata();
We’ve already entered a bunch of solid quotes via our custom section in the admin:
Based on the code above, we’re expecting to see their titles listed as links at the bottom of any page we check out on the front end. Let’s take a quick trip to the sample page that ships with WordPress at http://www.randomquotes.dev/sample-page:
It looks like we’re potentially in business! Now we want to be certain we can limit the amount of quotes displayed, and make sure they’re random while we’re at it. Adding the following two arguments to our previous code should do the job:
$args = array( 'post_type' => 'rdm-quote', 'posts_per_page' => 4, 'orderby' => 'rand' );
A few more clicks on our sample page is all that’s required to make sure we’ve got the right number of results, and that they’re different each time:
Things are looking good! Now let’s work out where this functionality should live in our plugin.
Adding Random Quote Retrieval to Our Plugin
The main user display option we’ll be looking to sort out initially is the ability to simply add quotes via a shortcode. That sounds like an inherently public-facing thing, so we’ll be looking at the /public folder back in our plugin. As with our previous instalment, we’re taking several hints in terms of actual implementation from Chris Wilcoxson’s handy illustrative plugin on Github which is well worth poking around if you’re following along.
In our case, we’ll kick things off by adding a simple function to return random quotes into our main public class at /public/class-my-rdm-quotes-public.php:
/** * Returns a post object of random quotes * * @param array $params An array of optional parameters * quantity Number of quote posts to return * * @return object A post object */ public function get_rdm_quotes($params) { $return = ''; $args = array( 'post_type' => 'rdm-quote', 'posts_per_page' => $params, 'orderby' => 'rand' ); $query = new WP_Query( $args ); if ( is_wp_error( $query ) ) { $return = 'Oops!...No posts for you!'; } else { $return = $query->posts; } return $return; } // get_rdm_quotes()
All being well, this should return a posts object, and enable us to specify how many results we’re looking for as a parameter. Now let’s look at making use of that via a shortcode.
Enabling Shortcodes in Our Plugin
A quick look at the Plugin Handbook’s guide to registering shortcodes in a plugin shows that the basics of the operation are relatively straightforward. We need to hook shortcode registration onto init, and then point WordPress in the direction of the function we’ll be using to handle things.
In the case of our local setup, this means doing two things. First of all we add a simple line of code to our define_public_hooks() method back in /includes/class-my-rdm-quotes.php:
/** * Register all of the hooks related to the public-facing functionality * of the plugin. * * @since 1.0.0 * @access private */ private function define_public_hooks() { $plugin_public = new My_Rdm_Quotes_Public( $this->get_plugin_name(), $this->get_version() ); $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' ); $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' ); $this->loader->add_action( 'init', $plugin_public, 'register_shortcodes' ); }
Now we’ll actually step into the main public class at /public/class-my-rdm-quotes-public.php to make the connection with the specific shortcode we want to set up:
/** * Registers all shortcodes at once * * @return [type] [description] */ public function register_shortcodes() { add_shortcode( 'randomquote', array( $this, 'list_quotes' ) ); } // register_shortcodes()
As the docs show us, this basically involves telling WordPress the name of the shortcode and the specific function we’ll be using to execute it. Let’s move on to that now.
Displaying Shortcode Content on the Screen
Ok, let’s get finally get some results on the page by filling in our list_quotes() function:
/** * Processes shortcode randomquote * * @param array $atts The attributes from the shortcode * * * @return mixed $output Output of the buffer */ public function list_quotes( $atts = array() ) { ob_start(); $args = shortcode_atts( array( 'num-quotes' => 5, 'quotes-title' => 'Words of Wisdom',), $atts ); $items = $this->get_rdm_quotes($args['num-quotes']); //var_dump($items); if ( is_array( $items ) || is_object( $items ) ) { echo('<h4>' . $args['quotes-title'] . '</h4><ul>'); foreach ( $items as $item ) { echo('<li><b>' . $item->post_title . ' | </b>' . $item->post_content . '</li>'); } // foreach echo ('</ul>'); } else { echo $items; } $output = ob_get_contents(); ob_end_clean(); return $output; } // get_rdm_quotes()
We won’t be winning any awards for code quality here, but a number of key boxes are being ticked above:
- We can retrieve shortcode attributes via the shortcode_atts() function, and have set defaults there for the number of posts and title.
- There’s a quick and dirty var_dump() call left in there if we need to quickly examine the data we’re actually dealing with.
- We’re concatenating data with basic HTML layout to display on the page, and using output buffering to avoid potential display hassles on the front end.
There’s admittedly plenty of room for improvement here, but let’s see if we can get some results first. We’ll start by calling our basic shortcode in a standard post:
Looking at the live version of the post, we see the defaults kicking in nicely:
Now let’s add in some of our own attributes to see if that’s working as well:
A quick page refresh and we can see that the attributes are working fine and dandy:
There are a number of things we could tidy up here, but we’ll start closing things out at this point before getting too bogged down in detail. We’ll quickly look at templating out some of that nasty looking HTML content in a more organized fashion next time around. Again, if you’re interested in exploring a substantially more fully fleshed-out version of some of the concepts introduced above, a good root around Chris Wilcoxson’s more fully fleshed-out plugin on Github is a great way to explore further on your own in the meantime.
Conclusion
We closed an important loop in this instalment of the series and were able to see the fruits of our labor on the screen. At this stage, our minimum viable plugin is up and running. We can enter custom content via the back end, and use shortcodes with parameters to display that content at will throughout our site.
As with previous stages, we’ve taken a bare bones approach and left plenty of room for improvement down the line, but we’ve come a long way since the start of the series. In the next piece, we’ll tidy up some loose threads from this time around, and also create some user settings for the plugin in the back end.
As always, we’re keen for comments and questions. If you’ve got any questions about our journey through the series so far, get in touch via the comments below and share your thoughts!
Featured image: bella67
2 Comments