static-sitetemplate-toolkit

Pagination with Qgoda


I have migrating a blog from Jekyll to Qgoda and now I want to paginate listing pages, so that only a fixed number of posts appear on the page. I also want to create these listings for categories, tags and years (for an archive). And only posts in the same language as that of the listing pages should appear.

How do I create additional pages? Do I need a markdown file for each of them?

How can I create the links to these pages?

I know that it must be possible because I have seen it in a presentation but the documentation does not seem to explain it.


Solution

  • Pagination is not yet documented. Try this:

    [% USE q = Qgoda %]
    [% posts = q.list('date.year'=2018 lingua=asset.lingua type='post').nsortBy('date').reverse() %]
    [% start = asset.start || 0 %]
    [% asset.start = 0 %]
    [% p = q.paginate(start = start total = posts.size per_page = 10) %]
    [%- FOREACH post IN posts.splice(p.start, p.per_page) -%]
      <a href="[% post.permalink %]">[% post.title | html %]</a><br />
    [%- END -%]
    <a href="[% p.previous_link %]">Newer</a>
    <a href="[% p.next_link %]">Older</a>
    [%- IF p.next_start -%]
      [% q.clone(location = p.next_location start = p.next_start) %]
    [%- END -%]
    [% USE Dumper %]<pre>[% Dumper.dump(p) %]</pre>
    

    In line 2 you pass the desired combination of filters to the template method q.list(). In this case you get assets from 2018 that have the same language as the listing itself and are of type "post". You always have to sort them (in this case by date) and probably reverse them to list most recent posts first.

    The method q.paginate() is a helper method. Its named arguments are start for the start page and total for the total number of documents in the collection. The result is a hash with all precomputed values that you need.

    In the FOREACH loop you iterate over posts but cut out the desired window with the standard Template Toolkit vmethod splice().

    For the targets of the "newer" and "older" links you use the precomputed values produced by q.paginate() above.

    Finally, if there are more pages to come (p.next_start) you clone the current page with q.clone(). That method creates an exact copy of the current document but overwrites those properties that you pass as arguments. You always have to overwrite the clone's location, and here also the start page which will be 10, 20, 30, ...

    The last line spits out the complete result of q.paginate() with Dumper.dump(). This is just for debugging so that you can see what other values are precomputed.

    You can simplify the way you collect the documents:

    [% posts = q.list('date.year'=2018 lingua=asset.lingua type='post') %]
    [% posts = q.llist('date.year'=2018 type='post') %]
    [% posts = q.llistPosts('date.year'=2018) %]
    

    These three calls produce exactly the same result but with decreasing verbosity.

    You can find real world examples (with the necessary IFs and more features) at https://github.com/gflohr/qgoda-multilang/blob/master/_views/components/listing.html or https://github.com/gflohr/qgoda-site/blob/master/_views/components/listing.html.