Use tags within pagination

Hi all,

I am using a custom pagination template defined in the pagination.hbs file. In this file I am trying to access tags like -

{{#page}}{{#has tag="#en"}}
     Page {{page}} of {{pages}}
{{else}}
     Seite {{page}} von {{pages}}
{{/has}}{{/page}}

But I see that I am not able to access tags here at all. Any help is appreciated! :smiley:

(Ghost version: 5.69.0)

@RyanF This is a follow up on {{#has}}-helpers not working in pagination. Do you have any suggestions for a fix on this?

Your help would be really helpful! :smiley:

Like before, this is likely a case of making sure you’re in the right context or that you have access to the data. Using {{log this}} will help tell you which data is available in the current context.

The pagination data isn’t available in the page context, so I wouldn’t expect the code block you posted to work as expected.

One way to get around this would be to pass data via a partial: Ghost Handlebars Theme Helpers: partials

  • I tried using logging, and here is what gets printed when I use {{log this}} from within pagination.hbs :
{
    settings: {
      ...
    },
    version: '5.70.2',
    safeVersion: '5.70',
    relativeUrl: '/blog/',
    _templateOptions: undefined,
    context: [ 'blog', 'page' ],
    posts: [
      {
       ...
      }
    ],
    pagination: { page: 1, limit: 10, pages: 15, total: 150, next: 2, prev: null },
    page: {
      slug: 'blog',
      id: 'xyz',
      uuid: 'xyz',
      ...
      authors: [ [Object] ],
      tags: [ [Object], [Object], [Object], [Object] ],
      tiers: [ [Object], [Object] ],
      primary_author: {
       ...
      },

So I see tags as an array of objects here. How can I access this?

  • I tried to use the pagination.hbs as a partial by introducing it in the parent file as :
{{> "pagination"}}

This did not render the template as expected. Am I overlooking something here?

Let’s take a step back. What are you trying to accomplish?

Generally, it wouldn’t make sense to use the pagination helper on a page because pages don’t have indexed content (there’s no page of pages or collection of posts). That’s probably why mixing these bits of data is proving to be difficult.

So what I am trying to do is have two pages -

  • Blogs (english)

  • Blogs (german)

On each of these pages, I am adding pagination so that I can view the 10 latest posts in the respective language, with navigation to the other pages. Since I need custom text for the pagination (custom for each language), I tag these blog pages with #en and #de.

This is a condensed version of my routes.yaml file :

routes:
  /blog/:
      data: page.blog
      controller: channel
      filter: tag:-hash-en
      template: blog
    /blog-en/:
      data: page.blog-en
      controller: channel
      filter: tag:hash-en
      template: blog
collections:
  /blog/:
    permalink: /blog/de/{year}/{month}/{slug}/
    template: post
    filter: tag:-hash-en
  /blog/en/:
    permalink: /blog/en/{year}/{month}/{slug}/
    template: post
    filter: tag:hash-en

I am unable to figure out how to access the tags (#en and #de) from within the pagination context. :thinking:

I don’t think that routing is going to get what you want.

I think an easier route would be just to use collections with your index template. Then, within there, you can do whatever logic you need to do.

You can just create a separate index template for each language or use the is helper to check context (en vs just blog).

Can you please give an example of what that would look like?

Here is what I want to implement (just to describe my situation more clearly):

  • I have a couple of static pages, and in one these pages I want to display the list of all posts.

  • Each of these pages should be available in both english and german. With the implementation I have now, I check for internal tags like #en to display english pages and otherwise display them in german. All the pages work fine except the page to display posts with pagination.

  • The check for tags #en does not work from within the pagination context.

Are the static pages just one for en and one for de? Or are there several?

There are several static pages - and each page will have an english and a german version. So the total no. of pages = no. of pages * 2 (en/de)

Also, each post will need to be available in english and german. So again two copies (en/de) for each post.

The other parameter here is also the nature of the collections.

Are the only places these posts going to show up like this?

     route-1-de
     route-2-en
     route-3-de

I’m asking because collections are exclusive. If there are posts on route-1-en, for example, then they can’t show up on the homepage (default route), for example.

I would want it to be something like this -

route-1-de
route-1-en
route-2-de
route-2-en

The above routes would be applicable to both pages and posts is what I am assuming.

The posts will be displayed only on one page - lets say /blogposts and they do not need to be available on the homepage.

I’m not sure I follow exactly, but this is what I’d do:

Routes

collections:
  /blog/:
    permalink: /blog/de/{year}/{month}/{slug}/
    template: blog-de
    filter: tag:-hash-en
  /blog/en/:
    permalink: /blog/en/{year}/{month}/{slug}/
    template: blog-en
    filter: tag:hash-en

Then create each template: blog-de and blog-en.

In those templates, you can pass data to a custom pagination helper using a partial property:

{{pagination lang="de"}}

That way you can have the various multilingual pages, custom routes, and custom pagination.

Hi Ryan,

  1. When I try using partial helpers they don’t seem to work as expected. I created two template files - blog and blog-en. In each of these files I try to use the corresponding partial helper as-

{{> "pagination" lang="de"}} or {{> "pagination" lang="en"}}

Inside the pagination when I print {{log lang}} it always prints de.

  1. So I tried to separate out the pagination files also into english and german. Even then it seems to pick up only the german pagination (after explicitly using {{> "pagination-en"}} with the corresponding english file).

It seems to me that I do not correctly understand how pagination works… Can you suggest what else I can try to get this working?

It seems like your code should be working…

Is your theme code in a public repo?

Unfortunately its a private repo. I think I need to take a step back and figure the language issue later. For now lets just consider plain pagination.

I think what might be causing the issue is that I do not clearly understand how the context changes when I use {{pagination}}.

I tried two things:

  1. {{pagination}}
    Inside the pagination.hbs file, I used {{log this}} and then I get output as below (condensed version):
{
  version: '5.70.2',
  context: [ 'blog-en', 'page' ],
  ...
  pagination: { page: 1, limit: 10, pages: 10, total: 100, next: 2, prev: null },
  page: 1,
  ...
  isSecondary: false,
  limit: 10,
  pages: 10,
  total: 100,
  next: 2,
  prev: null
}

Pagination helpers like {{page_url prev}} and {{page_url next}} work inside pagination.hbs.

  1. {{> "pagination"}}
    On using {{log this}} in this case I see:
{
  version: '5.70.2',
  context: [ 'blog-en', 'page' ],
  ...
  pagination: { page: 1, limit: 10, pages: 10, total: 100, next: 2, prev: null },
  page: {
    slug: 'blog-en',
    id: 'xxx',
    uuid: 'yyy,
    title: 'Blog',
    ...
    tags: [ [Object], [Object], [Object], [Object], [Object] ],
    ...
    isSecondary: false
}

Pagination helpers like {{page_url prev}} and {{page_url next}} do not work inside pagination.hbs.

I had thought that the above two approaches were not different since I am still using the same template hbs file. Can you please help me understand how the context changes? I read through the Ghost Docs about partials and pagination but your help would be great! :smiley:

1 Like

Thanks for all the comments. I feel like we’re closer to getting you sorted!

I’ve just spun up a site to test out everything below to confirm it works.

Routes.yaml

routes:

collections:
  /de/:
    permalink: /de/{slug}/
    template: index
    filter: tags:hash-de+tags:-hash-en
  /en/:
    permalink: /en/{slug}/
    template: index
    filter: tags:hash-en+tags:-hash-de

taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

index.hbs

{{!< default}}

{{#foreach posts}}
    <p>{{title}}</p>
{{/foreach}}

{{pagination}}

pagination.hbs

<p>{{#is "en"}}Page:{{else is "de"}}Seite:{{/is}}</p> {{! Check if we are on de or en }}
<p>{{page_url next}}</p> {{! Check whether this works }}
<p>{{page}} of {{pages}}</p>

This approach uses the is helper to determine the language context and output the different languages as a result.

1 Like

That solved it! Thanks a ton for all the help, after a lot of debugging the pagination finally worked :smiley:

What’s interesting for me to know is that I thought the is helper only worked with certain pre-defined contexts and not with new custom ones. So its good to know that the collections’ route (en/de) can also be used as the context!

I have a follow-up question to understand the concept of contexts. In your example if there is some more code after {{pagination}} in the index.hbs file, I understand that it will inherit the context from the parent. So it will have either the context of en or de in addition to index.

{{!< default}}

{{#foreach posts}}
    <p>{{title}}</p>
{{/foreach}}

{{pagination}}

{{> "custom-page"}}

I want to access the page tags in custom-page.hbs like {{#has tag="xyz"}}. But I noticed this does not work. Why is this the case? Is there any way to access these page tags here?

On the index page, you’re in an index context. When you bring in your custom-page template, you’re still in the index template (not a page context), so there’s no associated tag information available.

The index is a list of posts, not any particular post. You’ll likely need to employ a different strategy for adding additional data/content in the index page (like using the is helper).

  1. I am using internal tags like #example for the index template. Can I not access this tag using the has helper? If so, why can’t I access them?

  2. Why should I use the is helper instead? I understand that the is helper is used only to check context and not for checking tags.