Handleidingen

Wat een route teruggeeft

De standaardpagina, je eigen HTML, JSON, XML, tekst, CSV, bestanden en PDF, en hoe je elk maakt.

Elke route is een leeg canvas. Een route is een map met een index.tpl, en wat die template maakt, is het antwoord, verder niets. Nimbly voegt geen eigen layout, omhulling of formaat toe.

  • Wil je de standaardpagina, met de head, de assets en inline bewerken, eindig de template dan met [#html#].
  • Wil je je eigen HTML-document, schrijf het dan.
  • Wil je JSON, XML, platte tekst, CSV, een bestand of een PDF, maak dat dan.

Ze gebruiken allemaal dezelfde shortcodes, data, templates, libraries en rechten. Een site kan ze vrij combineren: een publieke site met de standaardshell, een landingspagina met een eigen document, een JSON-feed, een sitemap en een download voor alleen leden, naast elkaar.

De route geeft terug Hoe
De standaardpagina [#html#] aan het eind van index.tpl
Je eigen HTML-document Schrijf het document in index.tpl; zie Je eigen HTML
JSON [#http-header json#] en de JSON
XML, een feed [#http-header xml#] en de XML
Platte tekst [#http-header txt#] en de tekst
CSV [#http-header csv#] en de rijen
Een bestand Een library die de headers en inhoud van het bestand stuurt
Een PDF De PDF-module, vanuit een HTML-template
Een redirect [#redirect url#]
Een statuscode [#http-header 404#], 403 of 500

Het adres

Een routemap mag een punt bevatten, dus het adres kan een extensie hebben:

ext/uri/projects.json/index.tpl     /projects.json
ext/uri/feed.xml/index.tpl          /feed.xml
ext/uri/export/projects.csv/        /export/projects.csv

Een dynamische route werkt op dezelfde manier, bijvoorbeeld ext/uri/api/projects/(slug)/ die JSON geeft voor één project. Zie Routing.

Het contenttype

[#http-header type#] aan het begin van een template zet het Content-Type:

Type Content-Type
json application/json
xml application/xml; charset=UTF-8
txt text/plain; charset=UTF-8
csv application/csv; charset=UTF-8
css text/css
js application/javascript

Gebruik voor elk ander type, of voor extra headers, een library met de PHP-functie header(), zoals hieronder.

JSON

ext/uri/projects.json/index.tpl:

[#http-header json#]
[#data projects filter=published:1 sort=year|numeric|desc#]
[#fmt var=data.projects empty={} type=json#]

[#fmt ... type=json#] codeert een variabele; [#get project.title json#] codeert één waarde, met aanhalingstekens en escaping. De regeleinden tussen de shortcodes kunnen geen kwaad: JSON staat witruimte toe.

Schrijf voor een eigen vorm de JSON in de template:

[#http-header json#][#data .config.site#]{"site": [#get data.config.site.name json#], "projects": [#data-count projects#]}

Heeft het antwoord logica nodig, bouw het dan in een library:

<?php
// ext/lib/project-stats.php

function project_stats_sc($params)
{
    load_library('data');
    $projects = data_read('projects') ?: [];
    header('Content-Type: application/json');
    return json_encode([
        'total' => count($projects),
        'per_sector' => array_count_values(array_column($projects, 'sector')),
    ]);
}

ext/uri/stats.json/index.tpl bevat één regel: [#project-stats#].

XML en feeds

ext/uri/feed.xml/index.tpl:

[#http-header xml#]<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Fieldwork projects</title>
    [#data projects filter=published:1 sort=year|numeric|desc limit=20#]
    [#repeat data.projects tpl=feed-item#]
  </channel>
</rss>

met een template per item, ext/uri/feed.xml/feed-item.tpl:

<item>
  <title>[#fmt var=item.title type=plain#]</title>
  <link>[#base-url#]/projects/[#item.title_slug#]</link>
  <description>[#fmt var=item.description type=plain#]</description>
</item>

Elke site antwoordt al op sitemap.xml en robots.txt. Een resource voegt zijn records toe aan de sitemap met een instelling sitemap in zijn .meta.

Platte tekst

[#http-header txt#][#data .config.site#][#get data.config.site.name#]
Projects: [#data-count projects#]

CSV

[#http-header csv#]title,sector,year
[#data projects filter=published:1#][#repeat data.projects tpl=csv-row#]

met csv-row.tpl dat één regel per record bevat. De admin exporteert ook elke resource voor gebruikers met export-<resource>.

Bestanden

Bestanden die naar de mediabibliotheek zijn geüpload, worden geleverd op /download/<uuid>, met hun opgeslagen type en naam.

Om een bestand te leveren volgens je eigen regels, zoals een document voor alleen leden of een bestand dat op verzoek wordt gemaakt, laat je een library het sturen:

<?php
// ext/lib/member-document.php

function member_document_sc($params)
{
    load_library('access');
    if (!access_by_feature('view-member-documents')) {
        http_response_code(403);
        exit();
    }
    $path = $GLOBALS['SYSTEM']['file_base'] . 'ext/data/.member-files/handbook.pdf';
    header('Content-Type: application/pdf');
    header('Content-Disposition: attachment; filename="Member handbook.pdf"');
    header('Content-Length: ' . filesize($path));
    readfile($path);
    exit();
}

ext/uri/members/handbook.pdf/index.tpl bevat [#member-document#]. Met hetzelfde patroon stuur je een ZIP, een afbeelding die ter plekke wordt gemaakt of een agendabestand: de headers en de bytes zijn van jou.

PDF-documenten

De PDF-module maakt van HTML uit je eigen templates een PDF, cachet het resultaat en stuurt het als download:

./nimbly module:install pdf
load_library('pdf');
$pdf = pdf_render_cached_document([
    'paper_size' => 'a4',
    'orientation' => 'portrait',
    'pages' => [$html],
]);
pdf_send_download($pdf, 'Project-overview.pdf');
exit();

De cachesleutel omvat het document en de renderer, dus een gewijzigde tekst of template levert vanzelf een nieuwe PDF op.

Afbeeldingen

Geüploade afbeeldingen worden geleverd op /img/<uuid>/<size>, in het formaat dat het adres vraagt en als WebP: 800w voor een breedte, 400x400c voor een uitsnede. In templates schrijft [#get-img-html#] de responsieve markup. Zie Media en inline bewerken.

Redirects en statuscodes

[#redirect [#base-url#]/en/#]
[#http-header 404#][#http-header json#]{"error": "not found"}

Een dynamische route die een request niet accepteert, valt door naar de 404-pagina van de site, die ext/uri/errors/404/ kan vervangen.

De REST API

Elke resource antwoordt ook op /api/v1/<resource> met JSON, om te tonen, lezen, maken, wijzigen en verwijderen, met de rechten van de aanroeper. Gebruik die voor apps en integraties, en schrijf eigen routes voor wat de API niet dekt. Zie de naslag van de REST API.

Bekijk deze pagina als Markdown