Twig templates
Gebruik van Twig voor feature info
De templates in Onemap zijn in de opmaaktaal Twig geschreven. Dit is een PHP taal waar ook een Javascript port van is gemaakt. https://twig.symfony.com/doc/3.x/templates.html
De viewer gebruikt de javascriptversie van Twig, genaamd TwigJS (of twig.js). De javascriptversie probeert zo compatibel mogelijk te zijn met de PHP-versie, maar het kan zijn dat niet alle mogelijkheden uit de PHP-Twig-documentatie ook in de viewer werken. Hier kom je pas achter als je het probeert.
Voorbeelden feature info
Bepalen welke velden aanwezig zijn in een kaartlaag
Het komt soms voor dat de velden van een WMS-kaartlaag niet bekend zijn in Onemap. Dit komt doordat er geen WFS-tegenhanger van de kaartlaag bekend is in Onemap, of dat het om een rasterbestand (o.a. AHN) gaat. Het ophalen van feature info werkt wel gewoon, maar je moet dan de veldnamen kennen om ze te kunnen gebruiken in twig.
Gebruik deze Twig template om alle velden van een aangeklikte feature op te sommen.
{% for key,value in _context %}
{% if key != '_params' %}
<div><strong> {{ key }} </strong> : {{ value }} </div>
{% endif %}
{% endfor %}Splitsen van strings
Een use case voor splitsen van strings is bijvoorbeeld een lijst met url’s die is opgeslagen bij een object. Als dit een string is met meerdere url’s die met puntkomma gescheiden zijn, wil je deze eigenlijk als losse links weergeven in feature info. Gebruik hiervoor een split filter.
{% set urls_array = urlstring | split(';') %}
{% for url in urls_array %}
<p>Link: <a href="{{url}}" target="_blank">Linktekst</a></p>
{% endfor %}Laatste deel van url tonen
Een variatie op het splitsen van strings is het laatste deel van een url tonen. Dit kan door te splitten op '/' en dan het laatste deel te tonen.
{{url | split('/') | last}}Dit kan handig zijn om een link op te maken die alleen een bestandsnaam toont in de feature info, maar wel linkt naar het volledige pad.
<a href="{{url}}" target="_blank">{{url | split('/') | last}}</a>Lookup tables
Als een veld een numerieke of stringwaarde bevat met een betekenis, wil je in deze in feature info vertalen naar een voor de gebruiker begrijpelijke tekst. Een handige manier om dit te doen is door javascript objects te definiëren waar de keys de waardes zijn en de values de vertalingen.
Zie hieronder een voorbeeld waarbij de waarde van een veld 'type' wordt vertaald naar een label dat ook een type-afhankelijke kleur krijgt.
{% set labels = {
1: 'Een',
2: 'Twee',
3: 'Veel'
} %}
{# Gebruik enkele quotes als de keys strings zijn #}
{% set colors = {
'#FF0000': 'red',
'#008800': 'darkgreen',
'#0000FF': 'blue'
} %}
{# Gebruik ?? om defaults op te geven als het attribuut leeg is #}
{% set typeLabel = labels[type] ?? 'Type onbekend' %}
{# of maak gebruik van de default() functie #}
{% set typeColor = colors[type] | default('#ccc') %}
<h3>Type</h3>
<p style="color:{{typeColor}};">{{typeLabel}}</p>Datum opmaken
Het is mogeljik om een datum volgens een opgegeven format op te maken.
{{ datumveld | date('d-m-Y') }} {# opgemaakt als (dag-maand-jaar(4 cijfers) #}Zie voor opmaakopties hier: https://arigato.docs.bonify.io/article/281-formatting-dates-in-twig
Noot: de opties hierboven zijn voor de php-versie van twig. Het kan zijn dat sommige formats niet werken in de viewer. De optionele timezone parameter in die documentatie wordt niet ondersteund in Onemap.
Alleen gevulde velden opmaken
Het voorbeeld hierboven heeft een mogelijk onverwacht nadeel. Als een datumveld leeg is, wordt die opgemaakt als de huidige datum. Als je lege datumvelden leeg wil laten, kan je dit als volgt doen:
{% if datumveld %}{{ datumveld | date('d-m-Y') }}{% else %}Onbekend{% endif %}Een kortere manier om dit te doen is met de ?: operators.
{{ datumveld ? (datumveld | date('d-m-Y')) : 'Onbekend' }}Of om het veld gewoon leeg te laten als het niet is gevuld:
{{ datumveld ? (datumveld | date('d-m-Y')) }}
Vervang een attribuutwaarde en toon een alternatieve tekst
Soms wil je niet de waarde van een attribuut tonen in de Feature informatie. Je kan de inhoud van het attribuut vervangen met een tekst naar keuze. In dit voorbeeld wordt de waarde van het veld TYPE vervangen door een tekst die in de kaart beter tot zijn recht komt.
In het onderstaande voorbeeld worden twee mogelijke waarde vervangen door een alternatieve tekst. Textielcontainer wordt vervangem door Textiel en Luiercontainer wordt vervangen door Luiers.
{{ TYPE|replace({'Textielcontainer' : "Textiel", "Luiercontainer" : "Luiers"}) }}
Geneste gegevens uitklapbaar maken
Geneste gegevens en arrays kunnen in/uit-klapbaar worden getoond voor gebruik te maken van de Html elementen :
<details> en <summary>Deze elementen kunnen in loops worden opgenomen zoals toegepast in bijgevoegd voorbeeld. Hieronder wordt een voorbeeld getoond met uitklapbare verblijfsobjecten per pand.
ps: Deze presentatie is nog wat speelser gemaakt door Unicode emoji characters op te nemen.
<span style="font-size: 1.2em;">🏠</span>wordt dan getoond als:
<span style="font-size: 1.2em;">🏠</span>
{% block body %}
<h1>Verblijfsobjecten<span style="font-size: 2.5em;">🏢</span></h1>
{% set features = _context.features ?? [] %}
{% if features is empty %}
<p>Geen verblijfsobjecten gevonden.</p>
{% else %}
{% for feature in features %}
{% set props = feature.properties ?? {} %}
{% set geometry = feature.geometry ?? {} %}
{% set bbox = feature.bbox ?? [] %}
<details style="margin-bottom: 1rem; border: 1px solid #ccc; border-radius: 8px; padding: 0.5rem;">
<summary style="font-weight: bold; cursor: pointer;">
<span style="font-size: 1.2em;">🏠</span>
Verblijfsobject {{ props.identificatie ?? 'onbekend' }}
</summary>
<div style="margin-left: 1rem; margin-top: 0.5rem;">
{% if props is not empty %}
<details>
<summary><strong>Properties</strong></summary>
<ul style="list-style-type: none; padding-left: 1em;">
{% for key, value in props %}
<li><strong>{{ key }}:</strong>
{% if value matches '/^http?:\\/\\//i' %}
<a href="{{ value }}" target="_blank">{{ value }}</a>
{% else %}
{{ value }}
{% endif %}
</li>
{% endfor %}
</ul>
</details>
{% endif %}
{% if bbox is not empty %}
<details>
<summary><strong>BBOX</strong></summary>
<pre>
[
{% for coord in bbox %}
{{ coord }}{% if not loop.last %},{% endif %}
{% endfor %}
]
</pre>
</details>
{% endif %}
</div>
</details>
{% endfor %}
{% endif %}
<hr>
<nav>
{% if data.numberMatched is defined %}
<p>Aantal verblijfsobjecten: {{ data.numberMatched }}</p>
{% endif %}
</nav>
{% endblock %}Dit voorbeeld is gebaseerd op de BAG WFS services . Onderstaande link is opgenomen als basis api configuratie.
https://service.pdok.nl/lv/bag/wfs/v2_0
De gewenste API aanroep voor verblijfsobjecten vanuit de featureinfo van panden laag, wordt vervolgens ingericht als:
?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&outputFormat=application/json&TYPENAMES=bag:verblijfsobject&FILTER=<Filter><PropertyIsEqualTo><PropertyName>pandidentificatie</PropertyName><Literal>{identificatie}</Literal></PropertyIsEqualTo></Filter>
Ook in featureinfo kunnen de <Details><Summary> tags worden gebruikt om attributen 'uitklapbaar' te presenteren.
voorbeeld:
Wordt opgebouwd als:
<div style="margin-left: 1rem; margin-top: 0.5rem;"><span style="font-size:2.5em">🚮</span>
<details><summary><strong>Gebruik</strong></summary>
<ul style="list-style-type: none; padding-left: 1em;">
<li><strong>Afvalstroom : </strong>{{ afvalstroo }}</li>
<li><strong>Pasje : </strong>{{ pasje }}</li>
</ul>
</details>
<details><summary><strong>Soort</strong></summary>
<ul style="list-style-type: none; padding-left: 1em;">
<li><strong>Soort : </strong>{{ soort_cont }}</li>
<li><strong>Type : </strong>{{ type_conta }}</li>
<li><strong>Merk : </strong>{{ merk_conta }}</li>
</ul>
</details>
<details><summary><strong>Overig</strong></summary>
<ul style="list-style-type: none; padding-left: 1em;">
<li><strong>Ophaalsyst : </strong>{{ ophaalsyst }}</li>
<li><strong>Gebruiksjaar : </strong>{{ jaar_in_ge }}</li>
<li><strong>Geinvesteerd : </strong>{{ investeerd }}</li>
<li><strong>Aantal : </strong>{{ aantal }}</li>
<li><strong>Inhoud : </strong>{{ inhoud }}</li>
<li><strong>Straat : </strong>{{ straat }}</li>
<li><strong>Opmerking : </strong>{{ opmerking }}</li>
</ul>
</details>
</div>