Answers.Body: <p>You can create a <a href="https://docs.craftcms.com/v3/routing.html#advanced-routing-with-url-rules" rel="nofollow noreferrer">route with a URL rule</a> for these individual pages:</p>
  
  <pre><code>'brands/&lt;firstLetter:\w{1}&gt;' =&gt; ['template' =&gt; 'brands/index'],
  </code></pre>
  
  <p>Assuming you URL is something like <code>example.com/brands/a</code> and your template is located at <code>brands/index.twig</code>. This will also pass a <code>firstLetter</code> variable from the URL to the template.</p>
  
  <p>You can use <a href="https://docs.craftcms.com/v3/dev/element-queries/entry-queries.html#parameters" rel="nofollow noreferrer">Craft's search parameter</a> to only search the title field starting with a letter like this:</p>
  
  <p><code>craft.entries.search('title::a*')</code></p>
  
  <p>You can read more about <a href="https://docs.craftcms.com/v3/searching.html" rel="nofollow noreferrer">Craft's search syntax</a> here.</p>
  
  <p>For the number 0-9, combine search queries with an <code>OR</code> string like <code>title::0* OR title::1* OR title::2* OR</code>... etc.</p>
  
  <p>You can't use a URL like <code>example.com/brands/#</code> to show numbers, so I'm just going to use the default <code>example.com/brands</code> to show numbered entries (no <code>firstLetter</code> in the URL).</p>
  
  <p>Putting it all together, we get something like this:</p>
  
  <pre><code>{% if firstLetter is defined %}
    {% set searchQuery = 'title::' ~ firstLetter ~ '*' %}
  {% else %}
    {% set searchQuery = '' %}
    {% for num in 0..9 %}
      {% set searchQuery = searchQuery ~ 'title::' ~ num ~ '*' ~ (not loop.last ? ' OR ') %}
    {% endfor %}
  {% endif %}
  
  {% for entry in craft.entries.section('brands')
      .search(searchQuery)
      .orderBy('title')
      .all() %}
    {{ entry.title }}
  {% endfor %}
  </code></pre>
  
  <p>Here's a simple navigation for these pages.</p>
  
  <pre><code>&lt;p&gt;
    &lt;a href="{{ url('brands') }}"&gt;#&lt;/a&gt;
    {% for letter in 'a'..'z' %}
      &lt;a href="{{ url('brands/' ~ letter) }}"&gt;{{ letter|upper }}&lt;/a&gt;
    {% endfor %}
  &lt;/p&gt;
  </code></pre>
  
  <p>To filter out letters from that list that don't have any entries would be trickier to pull off tho. You could try something like this, but it might not be the most performant.</p>
  
  <pre><code>{% for letter in 'a'..'z' 
      if craft.entries.section('brands')
      .search('title::' ~ letter ~ '*')
      .exists() %}
  </code></pre>
  
  <p>Another possible option would be to create a plugin for finding distinct first letter entries like this person did:
  <a href="https://craftcms.stackexchange.com/a/10957/273">https://craftcms.stackexchange.com/a/10957/273</a></p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-09-19T09:32:10.047Z
Answers.Text: The pages are not setup with that at the moment, so it's a channel with all of them listed, would this work still? https://www.vouchertoday.uk/stores as you can see these need to be split into different pages.
Answers.UserDisplayName: JMKelley
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-09-19T17:09:10.253Z
Answers.Text: Yes, the code above is written to pull all the entries from a "brands" channel. You wouldn't need to split your entries up separately in the Craft control panel. 
  
  For each URL/route like `/brands/a` or `/brands/b` it will only display entries where the titles start with the letter in the URLs last segment.
Answers.UserDisplayName: Alex Roper
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-09-19T19:28:59.403Z
Answers.Text: Sorry Alex, How do you go about splitting up entries in the CP?
Answers.UserDisplayName: JMKelley
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-09-19T22:17:06.873Z
Answers.Text: You would NOT have to split them up in the control panel. Do you want to split them up in the control panel for some reason? I thought your question was asking how to display entries from a single channel split up over multiple pages on the front end of the site.
Answers.UserDisplayName: Alex Roper
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-09-23T10:29:43.303Z
Answers.Text: Just tried your method, I'm getting '404 Page not found' on the character URL's e.g. `/brands/m` is there a template I'm needing to create?
Answers.UserDisplayName: JMKelley
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-09-23T18:18:04.817Z
Answers.Text: Yes, you'll need a template file that corresponds to your URL rule in the config/routes.php file. In the example above ('template' => 'brands/index') that would be templates/brands/index.twig (or .html).
Answers.UserDisplayName: Alex Roper
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-02-04T09:57:48.227Z
Answers.Text: Is it possible to use this approach together with sprig (https://putyourlightson.com/plugins/sprig), to load the content on runtime?
Answers.UserDisplayName: buckdanny
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-02-04T21:07:48.410Z
Answers.Text: Yes, I think it's possible to use with Sprig. You could probably move the craft.entries for loop into a Spring component and pass `firstLetter` as a component variable.
Answers.UserDisplayName: Alex Roper
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-09-18T21:44:57.273Z
Answers.LastActivityDate: 2018-09-18T21:44:57.273Z
Answers.UserDisplayName: Alex Roper
Answers.Body: <p>You could use <a href="https://docs.craftcms.com/v2/templating/eager-loading-elements.html" rel="nofollow noreferrer">eager loading</a> to speed up things as it is now in your template.</p>
  
  <pre><code>{% set entries = craft.entries({
    section: 'brands',
    with:    ['brandLogo']
  }.all() %}
  </code></pre>
  
  <p>Another alternative I can think of is using a structure instead of a channel, with 0-9 and A-Z as top level entries and your brands already sorted per character underneath. Than you can just call up the correct letter/branch in your template. Switching from channel to structure won't erase your data either if I'm correct. And the eager loading trick will speed up things too here.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-09-17T14:08:15.853Z
Answers.LastActivityDate: 2018-09-17T14:15:50.110Z
Answers.LastEditDate: 2018-09-17T14:15:50.110Z
Answers.UserDisplayName: Tom De Smet
Body: <p>I've built a page listing all entries by Character 0-9/A-Z. But unfortunately it's extremely slow loading due to the amount of entries the site has. I'm wondering if I can break out the letters into seperate pages.</p>
  
  <p>Currently everything is on</p>
  
  <pre><code>.../brands/
  </code></pre>
  
  <p>What I'm looking to do is create</p>
  
  <pre><code>.../brands/a
  .../brands/b
  .../brands/c
  </code></pre>
  
  <p>I'm unsure if it's code running to create this or something more in the backend of Craft and how I've created the section. The code currently running the A-Z</p>
  
  <pre><code>{% set entries = craft.entries.section('brands') %}
        {% set entriesGrouped = entries|group('title|slice(0, 1)|upper|replace("/[^A-Z]/", "0-9")') %}
  
        {% for letter, entriesInGroup in entriesGrouped %}
            &lt;h3&gt;{{ letter }}&lt;/h3&gt;
            &lt;ul class="store-list"&gt;
            {% for entry in entriesInGroup %}
              &lt;li&gt;
                {% for asset in entry.brandLogo.all() %}
                  &lt;a href="{{ entry.url }}"&gt;
                    &lt;div class="retailer-logo"&gt;
                      &lt;img src="{{ asset.geturl }}" class="img-fluid" alt="{{ entry.title }} Discount Codes &amp; Vouchers"/&gt;
                    &lt;/div&gt;
                  &lt;/a&gt;
                {% endfor %}
                &lt;a href="{{ entry.url }}" title="{{ entry.title }} Coupon Codes"&gt;{{ entry.title }} Coupons&lt;/a&gt;
                {% endfor %}
                &lt;/li&gt;
            &lt;/ul&gt;
            &lt;hr&gt;
  {% endfor %}
  </code></pre>
  
Tags: <templating><entries><sections>
Title: A-Z Separate Pages
ThreadText: # A-Z Separate Pages
  
  (Asked by: username_0 on 2018-09-08)
  
  I've built a page listing all entries by Character 0-9/A-Z. But unfortunately it's extremely slow loading due to the amount of entries the site has. I'm wondering if I can break out the letters into seperate pages.
  
  Currently everything is on
  
  ```
  .../brands/
  
  ```
  
  What I'm looking to do is create
  
  ```
  .../brands/a
  .../brands/b
  .../brands/c
  
  ```
  
  I'm unsure if it's code running to create this or something more in the backend of Craft and how I've created the section. The code currently running the A-Z
  
  ```
  {% set entries = craft.entries.section('brands') %}
        {% set entriesGrouped = entries|group('title|slice(0, 1)|upper|replace("/[^A-Z]/", "0-9")') %}
  
        {% for letter, entriesInGroup in entriesGrouped %}
            <h3>{{ letter }}</h3>
            <ul class="store-list">
            {% for entry in entriesInGroup %}
              <li>
                {% for asset in entry.brandLogo.all() %}
                  <a href="{{ entry.url }}">
                    <div class="retailer-logo">
                      <img src="{{ asset.geturl }}" class="img-fluid" alt="{{ entry.title }} Discount Codes & Vouchers"/>
                    </div>
                  </a>
                {% endfor %}
                <a href="{{ entry.url }}" title="{{ entry.title }} Coupon Codes">{{ entry.title }} Coupons</a>
                {% endfor %}
                </li>
            </ul>
            <hr>
  {% endfor %}
  
  ```
  
  **Tags:** templating, entries, sections
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2018-09-18. Score: 2 | Accepted answer
  
  You can create a [route with a URL rule](https://docs.craftcms.com/v3/routing.html#advanced-routing-with-url-rules) for these individual pages:
  
  ```
  'brands/<firstLetter:\w{1}>' => ['template' => 'brands/index'],
  
  ```
  
  Assuming you URL is something like `example.com/brands/a` and your template is located at `brands/index.twig`. This will also pass a `firstLetter` variable from the URL to the template.
  
  You can use [Craft's search parameter](https://docs.craftcms.com/v3/dev/element-queries/entry-queries.html#parameters) to only search the title field starting with a letter like this:
  
  `craft.entries.search('title::a*')`
  
  You can read more about [Craft's search syntax](https://docs.craftcms.com/v3/searching.html) here.
  
  For the number 0-9, combine search queries with an `OR` string like `title::0* OR title::1* OR title::2* OR`... etc.
  
  You can't use a URL like `example.com/brands/#` to show numbers, so I'm just going to use the default `example.com/brands` to show numbered entries (no `firstLetter` in the URL).
  
  Putting it all together, we get something like this:
  
  ```
  {% if firstLetter is defined %}
    {% set searchQuery = 'title::' ~ firstLetter ~ '*' %}
  {% else %}
    {% set searchQuery = '' %}
    {% for num in 0..9 %}
      {% set searchQuery = searchQuery ~ 'title::' ~ num ~ '*' ~ (not loop.last ? ' OR ') %}
    {% endfor %}
  {% endif %}
  
  {% for entry in craft.entries.section('brands')
      .search(searchQuery)
      .orderBy('title')
      .all() %}
    {{ entry.title }}
  {% endfor %}
  
  ```
  
  Here's a simple navigation for these pages.
  
  ```
  <p>
    <a href="{{ url('brands') }}">#</a>
    {% for letter in 'a'..'z' %}
      <a href="{{ url('brands/' ~ letter) }}">{{ letter|upper }}</a>
    {% endfor %}
  </p>
  
  ```
  
  To filter out letters from that list that don't have any entries would be trickier to pull off tho. You could try something like this, but it might not be the most performant.
  
  ```
  {% for letter in 'a'..'z' 
      if craft.entries.section('brands')
      .search('title::' ~ letter ~ '*')
      .exists() %}
  
  ```
  
  Another possible option would be to create a plugin for finding distinct first letter entries like this person did:
  <https://craftcms.stackexchange.com/a/10957/273>
  
  > **Comments:**
  > **username_0**: The pages are not setup with that at the moment, so it's a channel with all of them listed, would this work still? https://www.vouchertoday.uk/stores as you can see these need to be split into different pages.  
  > **username_1**: Yes, the code above is written to pull all the entries from a "brands" channel. You wouldn't need to split your entries up separately in the Craft control panel.   For each URL/route like `/brands/a` or `/brands/b` it will only display entries where the titles start with the letter in the URLs last segment.  
  > **username_0**: Sorry username_1, How do you go about splitting up entries in the CP?  
  > **username_1**: You would NOT have to split them up in the control panel. Do you want to split them up in the control panel for some reason? I thought your question was asking how to display entries from a single channel split up over multiple pages on the front end of the site.  
  > **username_0**: Just tried your method, I'm getting '404 Page not found' on the character URL's e.g. `/brands/m` is there a template I'm needing to create?  
  > **username_1**: Yes, you'll need a template file that corresponds to your URL rule in the config/routes.php file. In the example above ('template' => 'brands/index') that would be templates/brands/index.twig (or .html).  
  > **username_2**: Is it possible to use this approach together with sprig (https://putyourlightson.com/plugins/sprig), to load the content on runtime?  
  > **username_1**: Yes, I think it's possible to use with Sprig. You could probably move the craft.entries for loop into a Spring component and pass `firstLetter` as a component variable.  
  
  ---
  
  ### Answer by username_3 on 2018-09-17. Score: 2
  
  You could use [eager loading](https://docs.craftcms.com/v2/templating/eager-loading-elements.html) to speed up things as it is now in your template.
  
  ```
  {% set entries = craft.entries({
    section: 'brands',
    with:    ['brandLogo']
  }.all() %}
  
  ```
  
  Another alternative I can think of is using a structure instead of a channel, with 0-9 and A-Z as top level entries and your brands already sorted per character underneath. Than you can just call up the correct letter/branch in your template. Switching from channel to structure won't erase your data either if I'm correct. And the eager loading trick will speed up things too here.
  
  
  ---
  
  