# Routing

Mappen als adressen, dynamische routes, talen en subdomeinen.

De mappenstructuur van `ext/uri/` is de URL-structuur van de site. Een map is een adres; de `index.tpl` ervan beantwoordt het.

Elke route is een leeg canvas: wat de template maakt, is het antwoord. Dat kan de standaardpagina via `[#html#]` zijn, een eigen HTML-document, JSON, XML, een bestand of iets anders. Zie [Wat een route teruggeeft](/nl/docs/guides/responses/).

## Statische routes

```text
ext/uri/index.tpl                 /
ext/uri/about/index.tpl           /about
ext/uri/en/contact/index.tpl      /en/contact
ext/uri/feed.xml/index.tpl        /feed.xml
```

Een statische route heeft verder niets nodig: geen registratie en geen `route.inc`. De mapnaam mag een punt bevatten, dus een route kan antwoorden op een adres zoals `/feed.xml` of `/llms.txt`.

Een routemap bevat meestal:

| Bestand | Rol |
|---|---|
| `index.tpl` | Draait als eerste. Zet paginavariabelen en maakt het antwoord, meestal met `[#html#]` |
| `main.tpl` | De body van de pagina binnen de shell |
| `header.tpl`, `footer.tpl` | Header en footer binnen de shell |
| `index.js` | Script voor alleen deze route, geladen door de shell |
| andere `.tpl`-bestanden | Templates die alleen deze route gebruikt, zoals een kaart |

Een submap is altijd een nieuwe route. Een los `.tpl`-bestand naast `index.tpl` is een template voor alleen die route, aan te roepen bij zijn naam.

## Dynamische routes

Een mapnaam tussen haakjes past op elk afzonderlijk segment:

```text
ext/uri/projects/(slug)/index.tpl     /projects/harbour-atlas
ext/uri/(lang)/news/(slug)/           /en/news/opening-day
```

Een dynamische route heeft een `route.inc` die bepaalt of het request bij hem hoort:

```php
<?php
$parts = router_match(__FILE__);
if ($parts === false) return;

$slug = $parts[0];
if (!preg_match('/^[a-z0-9-]{1,120}$/', $slug)) return;

load_library('data');
load_library('util');
$records = data_read_index('projects', 'title_slug', md5_uuid($slug));
if (empty($records)) return;

set_variable_dot('project', reset($records));
router_accept();
```

| Functie | Doet |
|---|---|
| `router_match(__FILE__)` | Geeft de waarden van de dynamische segmenten, of `false` als het adres niet past |
| `router_accept()` | Accepteert het request; de `index.tpl` van de route draait |
| `router_deny()` | Weigert; de volgende route wordt geprobeerd. Teruggaan zonder te accepteren doet hetzelfde |

Vertrouw geen enkele waarde uit het adres. Controleer de exacte syntax die je accepteert, de lengte en het bereik voordat je hem gebruikt om iets op te zoeken, als bestandspad of in een berekening. Beperk `route.inc` tot matchen, controleren en een variabele of twee zetten; bedrijfslogica hoort in een [library](/nl/docs/concepts/libraries/).

Dynamische routes worden geregistreerd in de resource `.routes`, zodat de router weet welke mappen hij moet vragen. Draai na het toevoegen of hernoemen van een dynamische route:

```bash
./nimbly routes:sync
```

Een statische route heeft nooit een `route.inc`. Logica voor een statische pagina gaat in een shortcode die vanuit de `index.tpl` wordt aangeroepen.

## Talen in het adres

Een meertalige site geeft meestal elke taal een eigen voorvoegsel, `/en/` en `/nl/`, als mappen in `ext/uri/`. Elke taal kan een eigen structuur hebben, of templates delen. Om een pagina te koppelen aan dezelfde pagina in een andere taal, zet je een `i18n-url.json` naast de `index.tpl`:

```json
{
  "nl": "nl/projecten/[#get project.title_slug lang=nl#]/",
  "en": "en/projects/[#get project.title_slug lang=en#]/"
}
```

`[#language-switch#]` maakt met deze koppelingen links naar elke taal van de site. Zie [Meertalige content](/nl/docs/guides/languages/).

## Subdomeinen

Een subdomein hoort bij de site; het is geen aparte installatie. De routes ervan staan in een map met de naam van het subdomein:

```text
ext/uri/(subdomain-docs)/index.tpl          docs.example.com/
ext/uri/(subdomain-docs)/guide/index.tpl    docs.example.com/guide
```

Laat het subdomein naar dezelfde document root wijzen; verder hoeft er niets ingesteld te worden. Op een subdomein wordt eerst de eigen map doorzocht, en alles wat daar niet staat, zoals de admin, de API en de login, komt van de site. Templates, resources en gebruikers worden gedeeld, en de login ook. `[#subdomain-url docs#]` en `[#subdomain-url#]` linken tussen het subdomein en de hoofdsite. Lokaal bereikt `docs.localhost` dezelfde map. Een pagina van de hoofdsite die ook via het subdomein bereikbaar is, houdt de hoofdsite als canonical adres. Draait een site in een submap, zoals op een gedeelde staging-host, zet dan `SUBDOMAIN_HOST` in `.env`, zodat links naar het subdomein naar het echte subdomein gaan.

## Routescripts

Een `index.js` in de map van een route wordt door de pagina-shell alleen op die route geladen. Gebruik het voor het eigen gedrag van een pagina, zodat het buiten de gedeelde bundel blijft.
