Displaying Related Posts from Specific Category in Winter Blog Plugin #959
-
Hello, I am currently working with the Winter Blog plugin and I'm encountering difficulties in achieving a specific functionality. What I'm trying to accomplish is to display random related posts from a particular category within the Winter Blog plugin. More precisely, I would like to include a section that showcases random related posts from the same category as the current post. For example 3 posts. Here's the relevant part of my template of a current post: <section class="blog-section">
<div class="blog-warp">
<div class="col">
<div class="content">{{ post.content_html|raw }}</div>
{% for category in post.categories %}
{% if category.name != 'Video' %}
{% if post.featured_images.count %}
<div class="container">
<div class="row">
<div class="row">
{% for image in post.featured_images %}
<div class="col-lg-3">
<a class="thumbnail"></a>
</div>
{% endfor %}
</div>
<div class="modal fade">
<div class="modal-dialog modal-lg">
...
</div>
</div>
</div>
</div>
{% endif %}
{% endif %}
{% endfor %}
</div>
</div>
</section>
{% partial 'related_posts' %} In the partial related_posts, I want to dynamically retrieve and display random related posts from the same category as the current post. Unfortunately, my attempts so far have been unsuccessful, and I'm struggling to correctly implement this feature. related_posts.htm {% set relatedCategory = post.categories.first() %}
{% if relatedCategory %}
{% set relatedPosts = relatedCategory.posts.toArray() %}
{% set randomRelatedPosts = relatedPosts|random_posts(post, 3) %}
<section class="related-posts">
<div class="container">
<div class="row">
<div class="col">
<h2>Related Posts</h2>
<div class="row">
{% for relatedPost in randomRelatedPosts %}
<div class="col-lg-4 col-md-6">
<div class="related-post">
<a href="{{ relatedPost.slug }}">
<img src="{{ relatedPost.feature_images[0].path | resize(300, 200) }}" alt="{{ relatedPost.title }}">
</a>
<h3><a href="{{ relatedPost.slug }}">{{ relatedPost.title }}</a></h3>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</section>
{% endif %} random_posts is a filter: public function randomPosts($posts, $currentPost, $count = 3)
{
$filteredPosts = array_filter($posts, function ($post) use ($currentPost) {
return $post['id'] !== $currentPost->id;
});
shuffle($filteredPosts);
return array_slice($filteredPosts, 0, $count);
} But it does not contain If anyone could provide me with a clear step-by-step solution or code snippets on how to achieve this, I would greatly appreciate it. Thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 1 reply
-
Do this instead: PHP Code Section: function onStart()
{
// Add the method to the page object so that Twig can access it
$this->page->addDynamicMethod('getRelatedPosts', [$this, 'getRelatedPosts']);
}
function getRelatedPosts(\Winter\Blog\Models\Post $post, int $limit = 3): iterable
{
// Get a category to pull related posts from
$category = $post->categories->first();
if (!$category) {
return [];
}
// Return the requested number of random published posts
// from that category and eager load the featured_images
return $category->posts()
->with(['featured_images'])
->where('id', '!=', $post->id)
->isPublished()
->inRandomOrder()
->limit($limit)
->get();
} Twig Content Section: {% set relatedPosts = this.page.getRelatedPosts(post) %} This will move the heavy lifting to the database instead, including the eager loading of the featured images which should reduce the total number of queries you're using and the amount of memory required from an infinitely growing amount based on how many blog posts are present in the DB down to a fixed number no matter how many blog posts you have. I highly recommend checking out Eloquent Performance Patterns, it's a very approachable mini video course that's well worth the investment and will have a lasting impact on your career as a developer. |
Beta Was this translation helpful? Give feedback.
-
@01Kuzma it could also be this line: <img src="{{ relatedPost.feature_images[0].path | resize(300, 200) }}" alt="{{ relatedPost.title }}"> That should be |
Beta Was this translation helpful? Give feedback.
-
@LukeTowers, thank you for the response.
But it doesn't even trigger... @bennothommo , ah, yes , it was a typo, but |
Beta Was this translation helpful? Give feedback.
-
@01Kuzma Add this as well: function onStart()
{
$this->page->addDynamicMethod('getRelatedPosts', [$this, 'getRelatedPosts']);
} and then call it with {{ this.page.getRelatedPosts(post, 3) }} |
Beta Was this translation helpful? Give feedback.
-
Brilliant! Thank you! |
Beta Was this translation helpful? Give feedback.
Do this instead:
PHP Code Section: