5.2 KiB
Forstå malsystemet
PnP bruker et enkelt, men kraftig malsystem basert på PHP-inkluderinger.
Filosofien
Tradisjonelle templating-systemer introduserer nye språk og syntaks som må læres. PnP tar en annen tilnærming: bruk PHP som det er.
Dette designvalget gir:
- Ingen læringskurve: Hvis du kan PHP, kan du lage maler
- Full kraft: Tilgang til alle PHP-funksjoner
- Null overhead: Ingen kompilering eller parsing
- Lett feilsøking: Standard PHP-feilmeldinger
Malhierarki
PnP har tre hovednivåer av maler:
1. Basismal (base.php)
Inneholder den overordnede HTML-strukturen:
<!DOCTYPE html>
<html lang="<?= $currentLang ?>">
<head>
<meta charset="UTF-8">
<title><?= $pageTitle ?? 'Min side' ?></title>
</head>
<body>
<nav><!-- Navigasjon --></nav>
<?= $content ?>
<footer><!-- Footer --></footer>
</body>
</html>
2. Sidemal (page.php)
Pakker inn enkeltinnhold:
<article>
<?= $content ?>
</article>
3. Listemal (list.php)
Viser samlinger av innhold:
<article>
<?php foreach ($items as $item): ?>
<div>
<h2><a href="<?= $item['url'] ?>"><?= $item['title'] ?></a></h2>
</div>
<?php endforeach; ?>
</article>
Dataflyt
Når en forespørsel kommer inn, flyter data gjennom systemet slik:
Request → Router → Content → Page Template → Base Template → Response
- Router: Finner riktig innhold
- Content: Konverterer markdown/HTML til HTML
- Page Template: Pakker innholdet i
$content - Base Template: Pakker alt i full HTML-struktur
Fallback-kjede
PnP følger en fallback-kjede for maler:
custom/templates/base.php
↓ (hvis ikke funnet)
default/templates/base.php
Dette betyr:
- Egendefinerte maler overstyrer standardmaler
- Du trenger bare å lage egendefinerte maler for det du vil endre
- Standardmaler fungerer som fallback
Tilgjengelige variabler
I base.php
| Variabel | Type | Beskrivelse |
|---|---|---|
$content |
string | Det rendrede innholdet |
$navigation |
array | Navigasjonselementer |
$currentLang |
string | Nåværende språk |
$defaultLang |
string | Standardspråk |
$homeLabel |
string | Label for hjem-lenken |
$translations |
array | Oversettelser fra språkfiler |
$pageTitle |
string | Sidens tittel |
I page.php
| Variabel | Type | Beskrivelse |
|---|---|---|
$content |
string | Innholdet som skal vises |
$metadata |
array | Metadata for siden |
$pageTitle |
string | Sidens tittel |
I list.php
| Variabel | Type | Beskrivelse |
|---|---|---|
$items |
array | Listeelementer |
$metadata |
array | Metadata for mappen |
$pageContent |
string | Valgfritt innhold fra page.md |
Items-struktur
I list.php er hvert element i $items et array med:
[
'title' => 'Innleggstittel',
'date' => '15. januar 2025',
'url' => '/blogg/2025-01-15-innlegg',
'cover' => '/blogg/2025-01-15-innlegg/cover.jpg', // eller null
'summary' => 'Kort beskrivelse' // eller null
]
Sikkerhet i maler
Escape output
Bruk alltid htmlspecialchars() for brukerdata:
<h1><?= htmlspecialchars($item['title']) ?></h1>
Ikke escape HTML-innhold
$content inneholder allerede HTML og skal ikke escapes:
<?= $content ?> <!-- RIKTIG -->
<?= htmlspecialchars($content) ?> <!-- FEIL -->
Beste praksis
Bruk korte echo-tags
<?= $variable ?> <!-- Bra -->
<?php echo $variable; ?> <!-- Fungerer, men mer verbose -->
Sjekk for eksistens
<?php if (isset($metadata['summary'])): ?>
<p><?= htmlspecialchars($metadata['summary']) ?></p>
<?php endif; ?>
Bruk ternary for fallbacks
<title><?= $pageTitle ?? 'Standard tittel' ?></title>
Hold logikk utenfor maler
Forbered data i ruteren eller i egne funksjoner, ikke i malene:
<!-- DÅRLIG -->
<?php
$processedItems = array_filter($items, function($item) {
return strlen($item['title']) > 10;
});
?>
<!-- BRA -->
<!-- Gjør dette i ruteren eller i en egen funksjon -->
Egendefinerte maler
For å lage egendefinerte maler:
- Kopier standardmalen fra
/app/default/templates/ - Lim den inn i
/app/custom/templates/ - Endre etter behov
Eksempel:
cp app/default/templates/base.php app/custom/templates/base.php
# Rediger app/custom/templates/base.php
Spesialiserte maler
Du kan lage spesialiserte maler for spesifikke formål:
list-grid.php
En alternativ listevisning med grid-layout:
<article class="grid">
<?php foreach ($items as $item): ?>
<div class="card">
<!-- Grid-basert layout -->
</div>
<?php endforeach; ?>
</article>
PnP vil automatisk foretrekke list-grid.php over list.php hvis den eksisterer.
Hvorfor dette systemet?
Dette malsystemet vil fungere i flere tiår fordi:
- Ingen proprietære templating-språk som kan bli utdaterte
- Basert på standard PHP-funksjoner
- Ingen kompilering eller cache-generering
- Lett å debugge med standard PHP-verktøy
- Ingen dependencies som kan bryte
- Fullt SEO-vennlig (server-side rendering)