Whether it’s compulsively reading the next chapter, binge-watching a show, or impatiently waiting for the sequel — when something’s good, it’s hard to wait. Your readers feel the same way about your content, so why not give them more by suggesting what to read next?
In this tutorial, learn how to build and customize a read-next section for your Ghost theme. This feature can take various forms, and you’ll learn how to build four of the most useful versions:
A read-next section that suggests the latest three posts
A read-next section that suggests the latest three posts by the same author
A read-next section that suggests the latest posts related by tag
A read-next section that dynamically suggests content based on member status
No matter which version you build, a read-next section means your audience will never be without their next read
In step #4, I think your two ‘get’ statements are reversed? You should need to go up a context level in the INNER one, not the outer one, right?
I just did a related posts block for a client this week who has 10k posts, and about 10k tags! Some tags have 8k posts, and some have one. Selecting posts that matched post.tags turned out to be basically useless, because it’d pick up the common tag, never the rare and specific tag.
I wrote two solutions. The first one used handlebars, sorted tags, and used the rarest tags. It was clunky but worked on my demo site (which has only a couple hundred posts). We deployed it, and it didn’t work on the client site on Ghost Pro. No clue why, without access to the logs, and his export doesn’t want to import on my demo site (10k posts, ugh).
I rewrote in javascript. Works great, gets the most specific matches.
Here’s a snippet:
let taglist =[]
let threeposts = []
let postid = '{{id}}'
let nodupeslist=[]
for (let el of ['{{tags.[0].slug}}','{{tags.[1].slug}}', '{{tags.[2].slug}}','{{tags.[3].slug}}','{{tags.[4].slug}}','{{tags.[5].slug}}','{{tags.[6].slug}}','{{tags.[11].slug}}','{{tags.[7].slug}}','{{tags.[8].slug}}','{{tags.[9].slug}}','{{tags.[10].slug}}','{{tags.[12].slug}}'] ) {
if (el && el[0] != "#") {taglist.push(el)}
}
// pretty sure there's a better way to do that, but not sure what it is.
async function getRelated() {
let data = await fetch(`${apistring}ghost/api/content/tags/?key=${apikey}&filter=slug:[${taglist}]&include=count.posts&order=count.posts%20ASC`)
let tags = await data.json()
let filterstring=""
for (let onetag of tags.tags) {
if (nodupeslist.length > 0 ) {filterstring=`%2Btags:-[${nodupeslist}]`}
if (threeposts.length < 3) {
let posts = await fetch(`${apistring}ghost/api/content/posts/?key=${apikey}&filter=id:-[${postid}]%2Btags:[${onetag.slug}]${filterstring}&limit=3`)
let dataposts = await posts.json()
for (let onepost of dataposts.posts) {
if (threeposts.length < 3 ) {
threeposts.push(onepost)
nodupeslist.push(onetag.slug)
}
}
}
}
drawPosts(threeposts)
}
Is this happening within the posts context? If you put a TAGS {{post.tags}} END just before your ‘get’ statement, do you see a list of tags, or is it blank? I’m guessing blank. Depending on how you’re calling it, you might need {{tags}} instead. I see that your working example is using {{id}}, not {{post.id}}…
Hmm. And you’re positive that your post that you’re testing with actually has a tag that’s also on another post, right? :) Sorry if that’s a silly question, but I’ve definitely made that mistake!
@Cathy_Sarisky pointed you in the right direction here. You either need to move the related posts block outside the post context or change the code.
To change the code, you’d need to use this:
{{#get "posts" filter="id:-{{id}}+tags:[{{tags.[*].slug}}]" limit="3" as |more_posts|}}
This tells Ghost to output the slug for each tag.
Figuring this out can be tricky. This is a case where starting Ghost in logging mode can be a huge help because it’ll let you know if your filter has issues. So, instead of starting Ghost locally with ghost start, you’d use:
Is there any way to tell it to show the 3 articles following the Post where it is shown? Not the last 3 articles. Since in all articles with that Tag, the same ones are shown. am I understood?
For example: The post with ID 2222222, that in the Read Next section show the 3 articles that follow that ID.
Too, It would be nice, to show 3 random articles, but I have read in other threads, that this is not possible.
I know it does no good to whine about “but in Wordpress …” – but I’ll whine a bit anyway.
I had a WP plugin that, instead of doing related posts off tags, allowed you to choose the related posts you wanted through a search. I’d enter any word in the title of the post(s) I wanted, and once found, just check the ones I wanted listed. Resulting code was very nice-looking, and even better, was actually relevant to the story I placed them in. AND, it linked the current article back to those articles as well, if I told it to.
This is one of those times that I wish there was some way to post WP plugins to Ghost – or to reverse-engineer them into a site. But, I know that’s not possible – and not the direction the Ghost staff wants to go.
Okay, whine over. I’ll get some cheese to go with it. ;-)
You could add a date filter here to say something like “show me related posts that were published after this one.” There are a lot of different filter options:
Ghost also has a previous/next post helper, which is even simpler to use:
Finally, you’re right that random posts aren’t possible at the theme level. However, you could do it with JS and the Content API. It’d be a bit more complex but doable!