4

I have a list of all my games using pagination. It works great: http://www.colorcomputergames.com/games

However, I'd like to add links at the top of the page like: A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z

And so I want to be able to click on any letter and display only entries starting with that letter.

I was was going to make a template for every page but that seems inefficient.

How should I tackle this?

11

First, you should create a dynamic route (something like "games/glossary/<slug>") and point it to a template. A dynamic route means you won't have to create a template for every letter. Note the use of the <slug> token, which – although not entirely semantic – should do nicely in this case.

In your template, you'll need to pull the letter from the URL. Note that it's also a good idea to test if the variable is a single character, and in the a-z range (i.e. a valid letter, and not some other entity).

{% set letter = slug is defined and slug|length == 1 and slug matches '/^[a-z]/i' ? slug %}

If there is no valid letter in the slug variable, it's a good idea to throw a 404:

{% if not letter %}
  {% exit 404 %}
{% endif %}

Next, you can actually use search syntax for the title parameter (specifically, a wildcard *), in order to pull all entries with a title starting with the relevant letter:

{% set entries = craft.entries.section('games').title(letter~'*').limit(null).order('title asc') %}

If you want to throw a 404 whenever there aren't any entries for any given letter, it's simply a matter of testing the length property for entries:

{% if not entries|length %}
    {% exit 404 %}
{% endif %}

If you need pagination in your template, it'll work out of the box as usual:

{% paginate craft.entries.section('games').title(letter~'*').limit(10).order('title asc') as pageInfo, pageEntries %}

{% if not pageEntries|length %}
    {% exit 404 %}
{% endif %}

{% for entry in pageEntries %}
    ...
  • That works like a charm!!!! – DevServe Dec 26 '16 at 14:59
  • Only thing not working is going to a letter without entries doesn't give me the 404. Need to ponder where to place your snippet as I also have pagination code in my template. – DevServe Dec 26 '16 at 15:01
  • If you're doing pagination, you'll probably need to use a named token in your dynamic route, because with pagination the page number will be the last segment in the URL, not the letter. For the 404 issue, it's simply a matter of testing the length of the returned entries. Updated my answer on both counts. – Mats Mikkel Rummelhoff Dec 26 '16 at 16:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.