Author Archives: admin

How To Create a Related Posts Slider / Carousel in WordPress

This is a very common task: to show related content under a given post. Surprisingly there is no such built-in function in WordPress so here are two ways to achieve it.

The Easy Way: With The Free Shortcode Revolution Plugin

See in this video:

The plugin can be downloaded from the official repository.

The DIY Way: Code

If you are here to just get the work done, use the plugin suggested above. If you are looking to learn and / or need a custom solution, let’s see the code. It’s pretty simple.

First, let’s figure out what would related mean? You don’t have to create a complicated AI. The related posts can be selected from posts from the same category and/or with the same tags.

Let’s dive in the code. You will need to create a function – it could be a function right in your theme, which will then be used in the single-post.php template, or (probably better) you can do it with a shortcode. I’ll leave this decision for you.

global $post; // this is the currently shown post on the page		
if(empty($post)) return ''; // just make sure you don't run this in the wrong place where $post may not exist

// let's prepare the WPQuery parameters
$query = [];	

// We will add both tags and category as criteria. Feel free to use only one of them
$tags = get_the_tags($post->ID);
if(empty($tags) or !is_array($tags)) $tags = [];
$tags_arr = [];
// we can't use $tags directly as they come from get_the_tags() because they are objects. So we are filling the new $tags_arr
foreach($tags as $tag) $tags_arr[] = $tag->name;						
$query['tag_slug__in'] = $tags_arr;

// similar for categories
$cats = get_the_category($post->ID);
$cats_arr = [];
foreach($cats as $cat) $cats_arr[] = $cat->term_id;
$query['category__in'] = $cats_arr;

// Let's say we want 5 random posts. We'll select 6 and then strip to 5 just to make sure the current post is not included.
// You could use the "post__not_in" attribute for this but it has some specific which make us prefer to clean the unnecessary post in PHP.
$query['posts_per_page'] = 6;
$query['orderby'] = 'rand';
$wp_query = new WP_Query($query);
$posts = $wp_query->posts;

// here we'll cleanup the current post with array_filter and a closure
$posts = array_filter($posts, function($p) use($post->ID) {				
    return ($p->ID != $post_id);					
});

if(5 < count($posts)) array_pop($posts);

That’s it. You’ll have the related posts in the $posts variable. If you want to learn more how WP_Query works, check here.

Watch out for some pitfalls if you’ll use $posts outside of the loop. Or just use WP_Query -> have_posts().

From then on, you can use any JS slider and prepare the required JS variables.

In Shortcode Revolution we preferred to build a vanilla JS slider using most of the code from this great guide.

Alternatively you can use aready jQuery carousel plguin like Slick.

 

Oddness in The WordPress Posts Loop and WP Query

While working on the new version of Shortcode Revolution we faced a couple of confusing behaviors of WordPress functions. I’ll document them here and will keep adding such information. Hopefully it can help other developers and save them a lot of time and frustration.

Excluding posts from WP Query (using post__not_in)

There is a good comment here explaining that post__not_in wouldn’t work when used with post__in in the same query. This is a good note but our query did not include post__in and post__not_in was still simply ignored. I did not dig deep into the code to see why this happens – the conclusion was simply not to use it.

Here is an example how we get 3 random related posts in Shortcode Revolution:

$query = [];
// we add 1 to the default number of posts which is 3 or to the user-passed number or posts
$query['posts_per_page'] = (empty($atts['num']) or !is_numeric($atts['num'])) ? 4 : intval($atts['num']) + 1;       
$query['orderby'] = 'rand';

// getting the posts here
$wp_query = new WP_Query($query);
$posts = $wp_query->posts;

// now because this is "related posts" query, we don't want the current post to be repeated below it. So let's filter it out
// $post_id is a variable we have defined earlier in the shortcode and it contains the current post ID
// we are using array_filter with a closure here. You can do it inside a loop with a counter but this solution is more elegant
$posts = array_filter($posts, function($p) use($post_id) {				
  return ($p->ID != $post_id);					
});

// if the current post was not there we have one more than needed
if($query['posts_per_page'] < count($posts)) array_pop($posts);

 

So that’s it – you just get more posts than you need and then remove the unwanted ones in PHP.

Showing the excerpt outside of the post loop – get_the_excerpt

If you look at the documentation it sounds like you can call get_the_excerpt with any post ID and receive the excerpt for that post id. Good luck! You may get the proper excerpt (sometimes!) but won’t get the automatically generated “read more” link properly. The first version of our code was this and it did not work:

foreach($posts as $p):
   $background_image =  has_post_thumbnail( $p->ID )  ?  get_the_post_thumbnail_url($p->ID) : ''; 
   $excerpt = get_the_excerpt($p->ID);
.....

I intentionally did not use $posts as $post to avoid overriding the global $post variable but apparently this was wrong. Fortunately this comment gave me the hint how to fix it:

foreach($posts as $p):
   // yes, do override the global!
   $post = $p;
   // and you need to setup_postdata($post)
   setup_postdata($post);
   $background_image =  has_post_thumbnail( $p->ID )  ?  get_the_post_thumbnail_url($p->ID) : ''; 
   $excerpt = get_the_excerpt($p->ID);
......
endforeach;

And after the end of the loop don’t forget to reset the post data:

wp_reset_postdata();

 

Zapier Webhooks in Namaste! LMS

From version 2.5.6 the WordPress learning management sytsem Namaste! LMS supports webhooks & Zapier integration.

You can learn more about Zapier’s implementation of webhooks here.

Currently Supported Actions

At the moment Namaste! LMS allows you to attach hooks to the following actions:

  • Student enrolls in a course. This happens for auto-approved enrollments or enrollments made by admin. It will also be fired when a pending enrollment is approved.
  • Student completes a course.

Webhooks can be used to connect your LMS to mailing list services, CRM, or any other web based services that support webhooks directly or through Zapier (or similar products).

To get to the webhooks interface click on the Webhooks / Zapier link in your Namaste! LMS menu. Here is the interface that you’ll see when adding a webhook:

A webhook form for Namaste LMS

With the above example you will have your webhook notified when someone successfully enrolls in the Free course. The hook will send username, email, and 3 fixed custom parameters. The data that will be sent to Pipedream (you can use it for testing and more) is this:

data sent to Pipedream

 

Pipedream lets you test your hooks and see the JSON message that you have sent to them. In real usage this data will be used by other apps to do all kind of things with it.

Stay tuned for more webhook events powered by the Namaste! Connect module soon.