Skip to content
Grav 2.0 is officially stable. Read the announcement →

Community guidelines

Please keep discussions civil and on-topic. Repeated violations may lead to a temporary ban.

General

Order collection by 'custom' or 'manual' in Twig

Solved by pamtbaau View solution

Started by Markus 4 years ago · 9 replies · 762 views
4 years ago

Hi folks,

to create and show a page collection via

TWIG
{% set options = { items: {'@page.children': '/myfolder'}, 'order': {'by': 'title', 'dir': 'desc'} } %}
{% set my_collection = page.collection(options) %}
<ul>
  {% for p in my_collection %}
    <li>{{ p.title|e }}</li>
  {% endfor %}
</ul>

within a myfile.html.twig works fine. The structure of folders and files (and titles) is this:

04.myfolder ()
--01.subfolder_a (default.md - title 'lorem')
--02.subfolder_b (default.md - title 'ipsum')
--03.subfolder_c (default.md - title 'dolor')

I'd like to know how I can affect the ordering by using manual or custom. After one and a half hour of searching the learning section ( Page Collections | Grav Documentation (getgrav.org)) and several forum entries I ended up with no success at all. I tried this e.g.:

TWIG
{% set options = { items: {'@page.children': '/footer'}, 'order': {'by': 'custom', 'custom': '01.subfolder_a|03.subfolder_c|02.subfolder_b'} } %}
{% set my_collection = page.collection(options) %}

with and without the numbers, using , instead of | and many other firings into the blue containing added frontmatter information in variable ways.

So, any help is appreciated. Thank you!

Greetings,

Markus

4 years ago Solution

@Markus, You're close, but 'custom' expects an array like in the yaml example in the docs...

Try:

TWIG
{% set options = { 
    items: {
        '@page.children': '/footer'
        }, 
    order: {
        custom: [
            'subfolder_a', 
            'subfolder_c', 
            'subfolder_b',
            ]
        }
    } 
%}
4 years ago

Thank you @paamtbau. Yes, close... your code works - but I am wondering, that your code is working although there is a comma after the last element subfolder_b ... this often throws an error.

Is there a difference between custom and manual? I just replaced custom

{% set options = { items: {'@page.children': '/footer'}, order: {custom: ['subfolder_a','subfolder_c','subfolder_b']} } %}

with manual

{% set options = { items: {'@page.children': '/footer'}, order: {manual: ['subfolder_a','subfolder_c','subfolder_b']} } %}

but this does not work and I have not found anything yet about order_manual, like it is said in the learning-section. Perhaps I have overlooked something?

Greetings,

Markus

4 years ago

@Markus, The order_manual refers to the variable in the frontmatter of the page:

YAML
---
content:
    items: s[email protected]

order_manual:
    - subfolder_a
    - subfolder_c
    - subfolder_b
---

From the docs:

manual The order is based on the order_manual variable
custom The order is based on the content.order.custom variable

4 years ago

Hi @Paamtbau,

maybe I am dumb, but the docs are - in my opinion - not sufficient enough to get the point how to use that. It might be as easy as cooking water, but I am missing an example.

So, my case is the following: I would like to show and order several links within the footer to some pages. The classic imprint, data protection, contact and so on. These pages are located within the folder "footer". I collect them, loop thru them and they appear in frontend - or not.

To understand all of the possibilities of grav, I try every option given.

The simple ones are really simple to understand, all fine, like this one:
{% set options = { items: {'@page.children': '/footer'}, order: {by: 'date', dir: 'asc'}} %}

Even ordering by header.x was no problem:
{% set options = { items: {'@page.children': '/footer'}, order: {by: 'header .footer_id', dir: 'asc'} } %}

Using custom works too, thanks to your input. Using manual, for me, seems to be a possibility to order those pages within the collection depending on the frontmatter on each page which is currently shown.

For example, if I configure this in frontmatter of the page "home"

YAML
order_manual:
  - imprint
  - dataprotection
  - contact

I assumed, that the order within the footer would be imprint, dataprotection, contact, when showing the page "home".

And if I configure this in frontmatter of the page "test"

YAML
order_manual:
  - contact
  - dataprotection
  - imprint

I assumed that the order within the footer would be contact, dataprotection, imprint when showing the page "test".

Based on your comment, I declare this within footer.html.twig
{% set options = { items: {'[email protected]': '/'}, order: {by: 'header .order_manual'} } %}
or
{% set options = { items: {'[email protected]': ''}, order: {by: 'header .order_manual'} } %}
or
{% set options = { items: {'[email protected]': '/'}, order: {by: 'manual'} } %}
or
{% set options = { items: {'[email protected]': '/footer'}, order: {'manual': ''} } %}
...
to be considered by
{% set my_collection = page.collection(options) %}

Nothing works and I do not find any example of using order_manual. The sole and general description "this depends on that" of the docs might be sufficient enough for those who are familiar with grav - but, for me, I am sorry for missing a "living example".

So, may some wisdom fall down on me... 😉

Greetings,

Markus

4 years ago

@Markus, Here is an example for using 'manual':

Folder structure /pages

TXT
user/pages
├── 01.home
├── 02.typography
└── footer
    ├── default.md
    ├── x
    │   └── default.md
    ├── y
    │   └── default.md
    └── z
        └── default.md

/footer/default.md

YAML
---
order_manual:
    - z
    - y
    - x
---

/user/themes/quark/templates/default.html.twig

TWIG
{% set options = { 
    items: {
        '@page.children': '/footer'
        }, 
    }
%}
{% set my_collection = page.collection(options) %}

The resulting ordering will be according the pages listed in order_manual in page /footer/default.md.

Notes:

  • Variable order_manual must be defined in the frontmatter of the page at hand. In this case, there must be a page defined in the root of /footer, with the proper frontmatter.
  • The manual ordering cannot be defined in the collection definition.
  • There should be no 'order' defined in the collections definition in Twig. Not even order: { by: 'manual '}
  • If no order is defined, the value of order_manual will be taken as default.

Yes, above notes may seem 'unexpected', but that might be because I have difficulty understanding the use-case of manual and its added value over custom.

I've created an issue to ask for a proper use-case for this option and asked for some samples. Maybe that will clear the 'unexpectedness'.

last edited 01/07/22 by pamtbaau
4 years ago

Hi @Paamtbau,
thanks a lot for your comment! That was exactly what I needed and ordering by manual/order_manual works fine. 😀

the use-case of manual and its added value over custom .

I might have the solution for that or at least one advantage. 🙂

When you set the order for custom within the footer.html.twig, it is hardcoded. If a folder is renamed, the ordering should not work anymore and you can not alter the file via the admin panel. Using manual avoids this problem, because the information about the order is not contained within the twig-file and reachable via admin-panel.

So, again thanks for your support and for posting an issue about the use of manual.

See ya,

Markus

4 years ago

@Markus, Yes, I got the 'hardcoded' and Admin part, but if that is all there is, it could also be achieved, even simpler, as follows:

  • Same folder structure as above.
  • /pages/footer/default.md
    YAML
    ---
    content:
      items: '[email protected]'
      order:
          custom:
              - y
              - z
              - x
    ---
    
  • Twig: /user/themes/quark/templates/default.html.twig
    TWIG
    {% for child in pages.find('/footer').collection %}
      {{ child.title }}
    {% endfor %}
    

There is now even less hardcoded in Twig because everything is defined in the page's frontmatter.

last edited 01/07/22 by pamtbaau
4 years ago

@Markus, Have had a discussion with the dev team: manual should not be used.

[...], after some investigation, it looks like the order_manual is leftover from backward compatibility and should never be used. It just messes up collections, especially if you want to use multiple collections.

4 years ago

Hi @pamtbaau,

thank you for your further investigations. Well, it seems there has to be an additional comment within the learning-section then.... - Ah, wanted to paste a link in here and recognizing, there is an added "deprecated"...

Thumbs up!

Markus

Suggested topics

Topic Participants Replies Views Activity
General · by Jerry Hunt, 4 days ago
2 80 10 hours ago
General · by pamtbaau, 15 hours ago
1 51 15 hours ago
General · by Andy Miller, 1 day ago
0 45 1 day ago
General · by Marcel, 12 months ago
6 346 5 days ago
General · by Duc , 5 days ago
3 40 5 days ago