• Some more tips for Grav and Twig

    4 Years ago I already blogged some tips for using Grav. Here are now some more tips for using Grav and Twig. Of course you also should make sure to have a look at the official Grav Documentation which is very helpful!

    Get all pages from a certain date range

    One of the default values you typically set on a page is the date. If you need to count all the pages within a certain date range, here is an example counting all documents within subfolder ‘live’ from today:

    {% set startdate = "today"|date("m/d/Y") %}
    {% set enddate = "today"|date_modify("+1 day")|date("m/d/Y") %}
    {% set currentmatches = page.find('/live').children.dateRange(startdate, enddate) %}
    <p>{{ currentmatches|length }} pages found</p>

    Get all pages with custom page header

    As you could define custom page headers, you could of course also use them for filtering. Here’s the example. The page header within subdirectory ‘live’ looks like this:

    title: 'My Page Title'
    date: '15:30 10/29/2019'
    mycustomdata:
    	category: test
    

    Within my .html.twig I could then use

    {% set result = page.find('/live').children|filter(v => v.header.mycustomdata.category=='test') %}

    If necessary, you could combine multiple filters using ‘and’ or ‘or’:

    {% set result = page.find('/live').children|filter(v => v.header.mycustomdata.category=='test' or v.header.mycustomdata.categoryalternate=='test') %}

    Looping through arrays

    In your .md file you could define arrays like this:

    ---
    title: My Page
    mycustomdata:
    	data: ["Germany","France","Japan"]
    	subdata: ["Europe","Europe","Asia"]
    ---

    If you want to output the list, you could use this for loop in your .html.twig:

    {% set countries = page.header.mycustomdata.data  %}
    {% set continents =  page.header.mycustomdata.subdata  %}
    	
    {% for c in countries %}
       {% if loop.index0 is even %}
           do some stuff 
       {% else %}
           do some other stuff 
       {% endif %}
       Country {{ c }} is located on continent {{ continents[loop.index0] }}
    {% endfor %}

    You see that with the for look you get a loop.index0 which holds the current integer counter. So you could do some extra stuff like ‘is even’ if you e.g. want different colors on alternate rows. But the most important stuff is the continents[loop.index0] which will return the value from the continents array.

    Setup arrays in Twig

    Typically you setup an array as described in Twig documentation:

    {% set tage = {0:'sonntag', 1:'montag', 2:'dienstag', 3:'mittwoch', 4:'donnerstag', 5:'freitag', 6:'samstag', 7:'sonntag'} %}

    But sometimes it might be necessary to merge the data like this:

    {% set tage = [] %}
    {% set tage = tage|merge(['sunday']) %}
    {% set tage = tage|merge(['monday']) %}
    {% set tage = tage|merge(['tuesday']) %}

    Localized date

    With these arrays we could display a localized date output easily. This block will e.g. show:

    Sonntag, 27. Oktober 2019 – 9:03 Uhr

    For other formats, see PHP Date documentation.

    {% set tage = {0:'Sonntag', 1:'Montag', 2:'Dienstag', 3:'Mittwoch', 4:'Donnerstag', 5:'Freitag', 6:'Samstag', 7:'Sonntag'} %}
    	{% set monate = {1:'Januar', 2:'Februar', 3:'März', 4:'April', 5:'Mai', 6:'Juni', 7:'Juli', 8:'August', 9:'September', 10:'Oktober', 11:'November', 12:'Dezember'} %}
    
    {{ tage[page.header.date|date("N")] }}, {{ page.header.date|date('d') }}. {{ monate[page.header.date|date('n')] }} {{ page.header.date|date('Y') }} - {{ page.header.date|date('G:i') }} Uhr

Leave a comment

If you want to share your opinion, leave a comment.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>