1

I have a blog post page where I'm using the category as a hardcoded parameter in url.

The url is like

url = "/category1/:slug"

I'm using blogPost component in this layout. I can get the nextPost and prevPost link using the following code in template

{% set nextPost = blogPost.post.nextPost %}
{% set prevPost = blogPost.post.previousPost %}

But I want to constraint nextPost and prevPost to be from same category as blogPost.post i.e. category1

blogPost.post belogs to only one category

I've checked that the Post model has a method scopeFilterCategories but I'm not sure how to use it or if it serves the same purpose.

Code

This is the configuration part

title = "Category1 post"
url = "/category1/:slug"
layout = "default"
is_hidden = 0
robot_index = "index"
robot_follow = "follow"

[blogPost]
slug = "{{ :slug }}"
categoryPage = "category1"
Akash K.
  • 627
  • 1
  • 14
  • 27

1 Answers1

2

It seems Thye are not Providing that Out of the box

I have created snippets which can do that work.

In you page's code block add this code snippet [ next previous works based on published_at field (Published on in form) ]

public function nextPost($post) {

    // get current cats
    $postCats = $post->categories->pluck('id')->toArray();

    // Here you need to pass it as we are 
    // hardcoding category slug in URL so we have no data of category

    // IF YOU DONT WANT CAT COME FROM POST
    // YOU CAN HARD CODE THEM $postCats = ['2'] 
    // here 2 is id of category

    // use this cats to scope 
    $nextPost = $post->isPublished()->applySibling(-1)
                   ->FilterCategories($postCats)->first();

    // check if next is not availabe then return false
    if(!$nextPost) {        
        return false;
    }

    // create page link here same page
    $postPage = $this->page->getBaseFileName();

    // set URl so we can direct access .url
    $nextPost->setUrl($postPage, $this->controller);

    // set Cat URl so we can use it directly if needed
    $nextPost->categories->each(function($category) {
        $category->setUrl($this->categoryPage, $this->controller);
    });

    return $nextPost;

}

public function previousPost($post) {

    // get current cats
    $postCats = $post->categories->pluck('id')->toArray();

    // IF YOU DONT WANT CAT COME FROM POST
    // YOU CAN HARD CODE THEM $postCats = ['2'] 
    // here 2 is id of category

    // use this cats to scope 
    $prevPost = $post->isPublished()->applySibling(1)
                   ->FilterCategories($postCats)->first();

    // check if nprevious ext is not availabe then return false
    if(!$prevPost) {        
        return false;
    }

    // create page link here same page
    $postPage = $this->page->getBaseFileName();

    // set URl so we can direct access .url
    $prevPost->setUrl($postPage, $this->controller);

    // set Cat URl so we can use it directly if needed
    $prevPost->categories->each(function($category) {
        $category->setUrl($this->categoryPage, $this->controller);
    });

    return $prevPost;

}

In Markup area you can add this code.

{% component 'blogPost' %}

{% set nextPostRecord = this.controller.pageObject.nextPost(blogPost.post) %}
{% set previousPostRecord = this.controller.pageObject.previousPost(blogPost.post) %}

{% if previousPostRecord %}
    <a href="{{ previousPostRecord.url }}"> Previous </a>    
{% endif %}

{% if nextPostRecord %}
    <a href="{{ nextPostRecord.url }}"> Next </a>    
{% endif %}

This will respect category and show only that category posts

If any doubt please comment.

Hardik Satasiya
  • 9,547
  • 3
  • 22
  • 40
  • I'm getting an error "Trying to get property of non-object" on template rendering part on line `{% set nextPostRecord = this.controller.pageObject.nextPost(blogPost.post) %}`. When I dump `this.controller` it doesnt show any `pageObject` named method or variable – Akash K. Jun 13 '18 at 14:38
  • ok I figured that out. I changed the statements to be like `{% set pageObject = this.controller.getPageObject() %} {% set nextPostRecord = pageObject.nextPost(blogPost.post) %} {% set previousPostRecord = pageObject.previousPost(blogPost.post) %}` – Akash K. Jun 13 '18 at 14:44
  • There's one other issue though. When navigation using these links, at a certain point they can only navigate between two posts. Pressing prev on post "M" goes to post "N" and pressing prev on post "N" goest to post "M" and keeps repeating. What could be the reason behind that. This issue was there when I used the default nextPost and prevPost methods too. Any chances you know why this is happening? BTW thanks for the snippets though :) – Akash K. Jun 13 '18 at 14:46
  • It seems like the `published_at` is messed up when multiple posts are posted on same date. – Akash K. Jun 13 '18 at 14:52
  • yes i forgot to mention inner logic works for different dates only, i faced same issue too but when i changed dates its workjng fine.... i guess you just extract logic from post model and write in code section. your own corrected logic and it should work – Hardik Satasiya Jun 13 '18 at 15:49