Make a custom WordPress shortcode that will allow you to show a list of pages or posts , show an excerpt and/or post image and access the wp_query and loop custom results with flexibility

In WordPress, you can do a lot with shortcodes, the problem is, some work fine then one day they just break.  It’s best to stick with ones that work reliably, even when you upgrade.  I’m showing parts of a function I wrote for a custom shortcode that should get you started in looking at ways to expand the flexibility of WordPress without bogging your site down with needless plug-ins.  Some plug-ins are great but they include too much and inevitably, they conflict with each other.

I always build shortcodes and encapsulate them in objects to avoid clashing with the system and plug-ins, however, sometimes you need to write a shortcode to do something simple.  I find it ironic that WordPress does not have built in more useful and common functions as shortcodes.  I mean, embedding a page or excerpt of a list of category posts isn’t so common it should be built in?!

//ini_set("display_errors",true); error_reporting(E_ALL);

// Prevent recursion
global $outerPost;
if ($outerPost)
return '';

// Parse parameters
extract(shortcode_atts(array('query' => 'post_type=post','show'=>'','show_excerpt'=>'','show_title'=>'','first_img'=>'N','cols'=>'1','no_msg'=>'N'), $atts));

$query = html_entity_decode($query);  // The flexibility to add any query that wp_query() will accept -- this is the real power and flexibility behind this shortcode
$show_title= html_entity_decode($show_title);  // This will make sure ONLY the title gets shown with the permalink
$show=html_entity_decode($show);  // Show excerpt,title, first_img, or "content"?

// You will need to call on another function that will find the first image of a function and return that image -- not included here

// Allow multiple columns in results
if ($cols>1) {$class="cols$cols-1col";} else {$class='';}

$no_msg=html_entity_decode($no_msg);  // If empty, what should it say?

// This only includes an extra class that extracts the first image of a post if it is specified in the shortcode by the user to do so
if ($first_img=="Y") {include($_SERVER['DOCUMENT_ROOT'].'/library/functions/image.php');}

// Create new post loop
// Example use: [list_custom query="author_name=fred"]
// More sample query vars: &category_name=news-articles&offset=3
// &posts_per_page=3

global $post;
$outerPost = $post;
$my_query = new WP_Query($query);

while ($my_query->have_posts()) {


$my_query->the_post(); setup_postdata($my_query->post);

        if ($show_title!="hide" && $show!="title"){

$the_title=get_the_title(); echo ''$the_title'';


//  You will need to use the "catch_that_image()" function -- Google it if ($first_img=="Y"){ echo $wpImage->catch_that_image();}

if ($show=='excerpt' || $show_excerpt=="yes"){



if ($show=="title"){


echo "<a href='".get_permalink()."'>$content."</a>"; continue;


if ($show==""){



if ($content=='') {continue;} if (stristr($content,'id="more-')){ $content=substr($content,0,stripos($content,'<span id="more-'));

// See if need to close a tag first: $cnt_p=substr_count($content,"<p"); $cnt_p_close=substr_count($content,"");



for($i=0;$i<$num_closers;$i++){ $content.=''</p>"; }


if($cols>1) { if ($cnt%$cols==0) {echo ''<div class='cols$cols-1col'>$content</div>"} } else {

echo str_ireplace("\r\n",'',$content);


} if($no_msg=="Y" && $cnt<1){

echo "Sorry, no articles or content were found matching that criteria.";

} $post = $outerPost; $outerPost = null; setup_postdata($post);

About Author:

Senior Cloud Software Engineer and 25+ years experienced video production, video editing and 3D animation services for a variety of global clients including local video production here in Jacksonville, Florida.

Leave a Comment

Your email address will not be published. Required fields are marked *