Filter and Paginate

When listing content entries in a page, you might want to filter entries or create a pagination system. Here's how to do that.

🚧

We consider that you have created an event content type

as described here.

Add a category field to the event content type

In your app/content_types/events.yml, add a block:

- category:
    label: Category
    type: string
    required: true

Edit data/events.yml and add a field category for each entry.

- "Sample 1":
    description: "Quam repellat repudiandae harum impedit natus. Quos vel rem vitae error qui culpa est. Eveniet reprehenderit sed ipsum quibusdam eos ab nihil."
    event_date: 2013/21/19 # YYYY/MM/DD
    category: "foo"

Filter the entries on "foo" category

You will use `with_scope liquid tag to filter the entries.

In a page, type:

<ul>
{% with_scope category: 'foo' %}
{% for event in contents.events %}
  <li>{{ event.title }}</li>
{% endfor %}
{% endwith_scope %}
</ul>

Listing another content type inside the with_scope tag

More often that not, you will probably want to relate your filtered content type to another related content type.

Building up on the previous exemple, let's say that you have defined the events content type and the speakers content type and that each event has many speakers. Check here for more details on how to create such a relationship between two content types.

<ul>
{% with_scope category: 'foo' %}
{% for event in contents.events %}
  <li>
    <h1>{{ event.title }}</h1>
    <p>Event speakers:</p>
    <ul>
      {% for speaker in event.speakers %}
      <li>{{ speaker }}</li>
    </ul>
  </li>
{% endfor %}
{% endwith_scope %}
</ul>

❗️

Previous versions of Locomotive

Please note that for the code proposed in this section to work, you need to have a version of steam above version with commit dfa638b38d7579ab0193341e20a4ef3345846e51 installed.

Reverse the entries

Add the reversed option to the for tag:

<ul>
{% for event in contents.events reversed %}
  <li>{{ event.title }}</li>
{% endfor %}
</ul>

Pagination

You can easily create a navigation with page number, and previous or next button.

{% paginate contents.events by 2 %}
<ul>
{% for event in paginate.collection %}
  <li>{{ event.title }}</li>
{% endfor %}
</ul>
<div class="pagination">
  {% if paginate.previous_page %}<a href="?page={{paginate.previous_page}}">Previous</a>{% endif %}
  {% if paginate.next %}<a href="?page={{ paginate.next_page }}">Next</a>{% endif %}
</div>
{% endpaginate %}

You also can use the paginate filter instead of the pagination div:

{{ paginate | default_pagination }}

Learn more:

πŸ“˜

with_scope and pagination

When using both with_scope and pagination the pagination must be included within the with_scope tag, not the other way around.