My First WordPress Plugin: Generates a Bulleted List of Clickable Blog Post Titles

I recently helped with a redesign that involved building a website with an out-of-the-box WordPress theme. The theme met our needs for the most part, but we were looking for something to dynamically generate an FAQ page from blog posts tagged with "FAQ". After trying some third-party plugins which didn't quite work for us and attempting to modify the theme files directly, I decided it was time to build my first WordPress plugin.

Background

The primary goal behind the plugin was to grab all the blog posts related to the FAQ page. Each post would be marked with a category like "FAQ". The title of the posts would be the question and the body would contain the answer.

The plugin needed to generate a bulleted list of clickable post titles. That way you can click on any question to view the page with the answer.

While the plugin was originally planned for the FAQ page, there were additional possibilities like using it to display a course catalog. So I wanted to make it as easy as possible to incorporate the plugin into any page of the website. That's why I decided to utilize the Shortcode API in WordPress.

Solution

For a shortcode to work, it must be defined. Before we do that, however, the necessary header information needs to be added for WordPress to recognize the plugin. The documentation (Writing a Plugin) states that only the plugin name is required, but I added a few extra bits of information to help the website manager.

<?php
/*
Plugin Name: Simple Post List
Description: Displays a list of clickable blog post titles based on the specified category. To specify the category, a shortcode like <strong>[postlist cat="FAQ"]</strong> can be added to your page.
Author: Patrick Nichols
*/
?>

Now the add_shortcode() function is used to activate a shortcode I called "postlist". Of course, you can name it whatever you want.

<?php
/*
Plugin Name: Simple Post List
Description: Displays a list of clickable blog post titles based on the specified category. To specify the category, a shortcode like <strong>[postlist cat="FAQ"]</strong> can be added to your page.
Author: Patrick Nichols
*/
//ACTIVATE THE "postlist" SHORTCODE
add_shortcode('postlist', 'display_post_list');

?>

The second argument of add_shortcode() contains a call to a user-defined function named "display_post_list". Let's define that function next.

<?php
/*
Plugin Name: Simple Post List
Description: Displays a list of clickable blog post titles based on the specified category. To specify the category, a shortcode like <strong>[postlist cat="FAQ"]</strong> can be added to your page.
Author: Patrick Nichols
*/
function display_post_list($args){
     //...
}

 
//ACTIVATE THE "postlist" SHORTCODE
add_shortcode('postlist', 'display_post_list');
?>

Inside the function, a couple variables will be needed. One to hold the category passed through the shortcode and another for the resulting list of links.

<?php
//...
 
function display_post_list($args){
     //INITIALIZE VARIABLES
     $category  = (isset($args['cat'])) ? trim($args['cat']) : '';
     $postLinks = array();

}
 
//...
?>

Next, we'll run a quick test to make sure a category was passed. If it was, the plugin can get the posts for that category using the get_posts() function.

<?php
//...
 
function display_post_list($args){
     //INITIALIZE VARIABLES
     $category  = (isset($args['cat'])) ? trim($args['cat']) : '';
     $postLinks = array();
 
     //IF A CATEGORY WAS PASSED
     if($category != '') {
          //GET POSTS
          $get_posts_args                   = array();
          $get_posts_args['posts_per_page'] = -1;
          $get_posts_args['category_name']  = $category;
          $postsOfInterest                  = get_posts($get_posts_args);
     }

}
 
//...
?>

The plugin can now loop through the matching posts to create the blog post links.

<?php
//...
 
function display_post_list($args){
     //...
 
     //IF A CATEGORY WAS PASSED
     if($category != '') {
          //GET POSTS
          $get_posts_args                   = array();
          $get_posts_args['posts_per_page'] = -1;
          $get_posts_args['category_name']  = $category;
          $postsOfInterest                  = get_posts($get_posts_args);
 
          //PREPARE POST LINKS
          foreach($postsOfInterest as $currPost) {
               ob_start();
               print '<li><a href="' . get_permalink($currPost->ID) . '">';
               print $currPost->post_title;
               print '</a></li>';
               $postLinks[] = ob_get_contents();
               ob_end_clean();
          }

     }
}
 
//...
?>

Just in case there weren't any posts for the indicated category, let's inform the website manager and/or visitor.

<?php
//...
 
function display_post_list($args){
     //...
 
     //IF A CATEGORY WAS PASSED
     if($category != '') {
          //GET POSTS
          $get_posts_args                   = array();
          $get_posts_args['posts_per_page'] = -1;
          $get_posts_args['category_name']  = $category;
          $postsOfInterest                  = get_posts($get_posts_args);
 
          //PREPARE POST LINKS
          foreach($postsOfInterest as $currPost) {
               ob_start();
               print '<li><a href="' . get_permalink($currPost->ID) . '">';
               print $currPost->post_title;
               print '</a></li>';
               $postLinks[] = ob_get_contents();
               ob_end_clean();
          }
     }
 
     //IF NO POSTS FOUND
     if(empty($postLinks)) {
          $postLinks[] = '<li>There are currently no entries found</li>';
     }

}
 
//...
?>

All that's left to do is return the results.

<?php
//...
 
function display_post_list($args){
     //...
 
     //IF NO POSTS FOUND
     if(empty($postLinks)) {
          $postLinks[] = '<li>There are currently no entries found</li>';
     }
 
     //RETURN RESULT
     return '<ul>' . implode($postLinks) . '</ul>';

}
 
//...
?>

Final Code

To help give you a better sense on how the pieces fit together, here is the entire script:

<?php
/*
Plugin Name: Simple Post List
Description: Displays a list of clickable blog post titles based on the specified category. To specify the category, a shortcode like <strong>[postlist cat="FAQ"]</strong> can be added to your page.
Author: Patrick Nichols
*/
function display_post_list($args){
     //INITIALIZE VARIABLES
     $category  = (isset($args['cat'])) ? trim($args['cat']) : '';
     $postLinks = array();
 
     //IF A CATEGORY WAS PASSED
     if($category != '') {
          //GET POSTS
          $get_posts_args                   = array();
          $get_posts_args['posts_per_page'] = -1;
          $get_posts_args['category_name']  = $category;
          $postsOfInterest                  = get_posts($get_posts_args);
 
          //PREPARE POST LINKS
          foreach($postsOfInterest as $currPost) {
               ob_start();
               print '<li><a href="' . get_permalink($currPost->ID) . '">';
               print $currPost->post_title;
               print '</a></li>';
               $postLinks[] = ob_get_contents();
               ob_end_clean();
          }
     }
 
     //IF NO POSTS FOUND
     if(empty($postLinks)) {
          $postLinks[] = '<li>There are currently no entries found</li>';
     }
 
     //RETURN RESULT
     return '<ul>' . implode($postLinks) . '</ul>';
}
 
//ACTIVATE THE "postlist" SHORTCODE
add_shortcode('postlist', 'display_post_list');
?>

Upload and Activate the Plugin

Once the plugin script is ready to go, you can

  1. Zip the file
  2. Log into WordPress
  3. Click Plugins
  4. Click Add New
  5. Click Upload Plugin
  6. Click Choose File
  7. Locate the .zip plugin file and click Install Now
  8. Click Activate Plugin

You should now be able to use the plugin by adding a shortcode, like the following, to any page or post:

[postlist cat="FAQ"]

Note that "FAQ" can be any category used within your WordPress website.

Final Thoughts

While the above plugin is sufficient for the goal stated earlier, there is plenty of room for improvement. Some of the advancements I've made since developing the original script include the following:

  • Provide system errors to those logged in with an admin account. The plugin, for example, now lets admins know when the category is left blank.
  • Allow post lists to be broken down by sub-category. That way questions on the FAQ page, for example, can be grouped into different categories such as enrollment questions, program questions, etc.
  • Allow post lists to be filtered by WordPress tags. In addition to choosing posts within a certain category, the plugin can now narrow those posts down by tag. If we have a category called "Courses", for example, the shortcode can be set up to only show courses tagged as "Spring 2015".

Related Posts

2 Comments

  • #1 brb on 04.05.16 at 5:45 am

    Interesting article but the plugin assumes a new site. If one needs to generate a list of post titles in an existing site, it would mean going back into dozens or hundreds of posts and entering short code for each.

  • #2 Patrick Nichols on 04.05.16 at 5:52 pm

    @brb – The shortcode is only entered on the page where you want the link list to appear. It then uses the category that you pass to the shortcode to generate the links. So as long as you have been flagging your posts with the category you want to use for the link list, the plugin will work for an existing site.

Leave a Comment