How to create links to Previous and Next posts

On a post singular page, I want to show links to the next post and the previous post.

The singular page is not in a loop, but I could create a loop there and use route to determine which post I’m looking at.

Is there any magic code that could let me create a link to the next and previous posts?

Cheers, Richard

Hi RichardC:)
I am not sure what exactly you are trying to aim in your post but are you looking for something like this?

But you just wanna pull out the singular page of the post and not the entire post loop?

1 Like

Here’s the magic code!

<Note>Save our query so that it only runs once.</Note>
<Set query=postQuery type=post orderby=date order=desc  />

<Note>Save the current post ID</Note>
<Set currentID><Field id /></Set>

<Note>Create a list of each post ID. This way each post ID is associated with an index</Note>
<List postIDs>
  <Loop query=postQuery>
    <Item>
      <Field id />
    </Item>
  </Loop>
</List>

<Note>Loop through our list of post IDs. When we find the current post in the list, we calculate the relative index of the previous and next post ID</Note>
<Loop list=postIDs>
  <If check="{Field}" value="{Get currentID}">
    <Set prevIndex><Math>
      <Get loop=count /> - 1
      </Math></Set>
    <Set nextIndex><Math>
      <Get loop=count /> + 1
      </Math></Set>
  </If>
</Loop>

<Note>Now we use the saved indexs to get the post IDs from the list and save them as variables</Note>
<Set prevID><Field list=postIDs item="{Get prevIndex}" /></Set>
<Set nextID><Field list=postIDs item="{Get nextIndex}" /></Set>

<Note>Finally, we run through our saved post query once more and display the items which match our saved previous and next post IDs</Note>
<div style="display: flex;">
  <Loop query=postQuery>
    <If check="{Field id}" value="{Get prevID}">
      <div class="previous">
        <a href="{Field url}"><Field title /></a>
      </div>
    </If>
    <If check="{Field id}" value="{Get nextID}">
      <div class="next" style="margin-left: auto;">
        <a href="{Field url}"><Field title /></a>
      </div>
    </If>
  </Loop>
</div>

Let me know if this works for you! Use it for any post type by modifying the query variable at the top :slight_smile:

2 Likes

@julia Brilliant!

I haven’t tested it yet but I’ve never been disappointed by anything you post.

Also, your use of <Note> is enlightening. I’ll be using that, and will update my progress

Thanks, Richard

1 Like

Yes, that’s what I want. I don’t understand your second question, but I think Julia has solved it. Thanks.

Question about loop efficiency:

At the end, you run through the entire loop to display two posts. Since the entire loop could consist of hundreds of posts or more, could it be more efficient to simply create new loops for each of the two posts like this?

<Loop type=post id="{Get prevID}">
  ...display stuff ...
</Loop>
<Loop type=post id="{Get nextID}">
  ...display stuff ...
</Loop>

It’s always good to see people who are efficiency-minded in L&L, so great question! Because there’s an id parameter that’s specified, those loops aren’t looping through all the posts, they’re only looping through the one post whose ID is written in the value, so it’s just about as efficient as it could be.

Sorry I wasn’t clear. Julia’s final loop is

<Loop query=postQuery>

And postQuery is

<Set query=postQuery type=post orderby=date order=desc />

Which does loop through all the posts. The loops I showed that specify the post ID would be my alternative.

Hold up, I misspoke! I got confused between your suggestion and the markup that Julia had written. In Julia’s example, she’s looping through a query variable, which is basically a loop that’s already been saved and so it requires very little work to loop through it as many times as you’d like. You could test the two approaches yourself with the Timer tag to confirm which is most efficient, but looping through a query variable is way more efficient than looping through the original query itself.

1 Like

If the work is already done with the original loop, that’s what I needed to know. Thanks.

1 Like

Did anyone try this out? I’m having difficulty getting it to work.

the <If check="{Field}" value="{Get currentID}"> condition doesn’t seem to eval as true. Does it need an ‘is’ in there, or are the values different types (string, num)?

Thx, DB

@julia @benjamin I ended up going with a pagination module in Beaver Builder to accomplish this, but I’m curious if the code has a bug or if I’m just misunderstanding it.

@gingersoul I hadn’t tested Julia’s template myself initially, but I just tested it and realized you were right that this didn’t seem to be working. After way too much tinkering, I finally figured out the issue and it’s annoyingly simple. You’ll notice that when the list variable is being set, the opening and closing Item tags are on different lines, like this:

<List postIDs>
  <Loop query=postQuery>
    <Item>
      <Field id />
    </Item>
  </Loop>
</List>

What happens here is that, just like in regular HTML, when you add a line break between your opening and closing tags, it adds a space on the front end. This isn’t a unique feature of L&L, it’s just how HTML works. The result is that each number in the postIDs list ends up including spaces instead of being a number by itself, like " 1234 " instead of “1234”. That breaks the comparison further down on the template. Luckily, the solution is super simple: bring those Item tags onto the same line and then the whole template works:

<List postIDs>
  <Loop query=postQuery>
    <Item><Field id /></Item>
  </Loop>
</List>

Tada! :magic_wand:

Nice find! Thank you so much for checking on that. I was ‘logging’ out the values myself but never noticed the spaces between.

Is a ‘front-and-back’ trimming operation in order for items like this? Or would that close other doors that need to stay open?

DB

Same haha, I tried displaying the saved variables each step of the way and it took me two passes before realizing that there were sneaky little blank spaces being displayed.

I’m not sure what you mean by this. This behaviour where line breaks in the code are interpreted as a space is the standard way that HTML works and L&L is an extension of HTML.

I think that’s my answer. I was noodling on a way to prevent this from happening in other situations. Only thing I can think of is some kind of debug mode that might flag this kind of thing.

Or just keep it in your toolkit :slight_smile:

1 Like

You’re right that this would be the ideal way of improving this. We don’t want to mess with the core way that HTML code is evaluated, but it would be good to be able to catch issues like this. In this thread, the issue happens when the <Item></Item> tags were on different lines, but I’m assuming we’d want this warning to pop up whenever any variable-setting tag had its open and closing tags on different lines, like <Set></Set> and maybe others. When other tags are on separate lines and a space is added it’s fine because a space just gets rendered on the front end and nothing really breaks. It’s only when that space gets unintentionally saved into a variable that this is an issue. There aren’t currently any code validations/suggestions built into the code editor beyond standard HTML code validation but I know the team is working on building a foundation that will allow us to add more robust L&L-specific validation like this. I’ve made a note of this feature request so I’ll update this thread if/when that gets added.

Good enough for me. Thanks for the attention to this.

1 Like