innhold/docs/templates.md

126 lines
4.6 KiB
Markdown
Raw Normal View History

# Templates Reference
For LLM agents working on this site's templates. Read when modifying any template file.
## Template Hierarchy
Content renders inside-out: content file -> page/list template -> base.php
```
content file (md/html/php) -> rendered as $content
-> page.php or list-*.php (wraps content)
-> base.php (HTML document shell)
```
## File Locations
All in `custom/templates/`. These override `app/default/templates/`.
| Template | Purpose | Used When |
|---|---|---|
| `base.php` | HTML document wrapper (head, nav, footer) | Always |
| `page.php` | Single page/article | Directory has no subdirectories (or `hide_list=true`) |
| `list.php` | Default list layout | Directory has subdirectories (default) |
| `list-card-grid.php` | Card grid layout | `page_template = list-card-grid` in metadata |
| `list-faq.php` | FAQ accordion layout | `page_template = list-faq` in metadata |
| `list-grid.php` | Brochure grid layout | `page_template = list-grid` in metadata |
## Template Selection
List template is chosen by `page_template` field in the directory's `metadata.ini`:
```ini
page_template = list-faq
```
If not set, defaults to `list.php`.
## Variables Available in All Templates
These are extracted via `extract()` so they're direct PHP variables:
| Variable | Type | Description |
|---|---|---|
| `$content` | string | Pre-rendered HTML content (in base.php) |
| `$pageTitle` | ?string | Page title from metadata |
| `$metaDescription` | ?string | Meta description |
| `$socialImageUrl` | ?string | Social media image URL |
| `$navigation` | array | Menu items `[['title'=>..., 'url'=>...], ...]` |
| `$homeLabel` | string | Home link text |
| `$currentLang` | string | Current language code (`no` or `en`) |
| `$langPrefix` | string | URL language prefix (empty for default, `/en` for English) |
| `$languageUrls` | array | `['no'=>'/path/', 'en'=>'/en/path/']` |
| `$translations` | array | Translation strings from language .ini files |
| `$availableLangs` | array | `['no', 'en']` |
| `$pageCssUrl` | ?string | Page-specific CSS URL |
| `$pageCssHash` | ?string | CSS cache-bust hash |
| `$pageJsUrl` | ?string | Page-specific JS URL |
| `$pageJsHash` | ?string | JS cache-bust hash |
| `$feedUrl` | ?string | Atom feed URL (only on list pages with `feed=true`) |
## Additional Variables in page.php
| Variable | Type | Description |
|---|---|---|
| `$content` | string | Rendered page content HTML |
2026-05-10 22:02:48 +02:00
| `$metadata` | array | Full metadata array from `metadata.ini` |
## Additional Variables in list-*.php Templates
| Variable | Type | Description |
|---|---|---|
| `$pageContent` | ?string | Rendered intro content from list directory's own content files |
| `$items` | array | List items (see schema below) |
| `$metadata` | array | List directory's metadata |
## List Item Schema
Each item in `$items`:
```php
[
'title' => string, // Item title
'url' => string, // Relative URL with lang prefix
'date' => string, // Formatted date (localized)
'rawDate' => string, // ISO date (YYYY-MM-DD)
'summary' => ?string, // Summary text
'cover' => ?string, // Cover image URL
'pdf' => ?string, // PDF file URL
'redirect' => ?string, // External redirect URL
'dirPath' => string, // Filesystem path to item directory
]
```
## base.php Key Sections
1. **Head**: Meta tags, social OG tags, Twitter cards, stylesheets, feed link, favicon
2. **Header**: Logo, navigation menu, language switcher
3. **Main**: `$content` (wrapped content from inner template)
4. **Footer**: Social links, page generation time, language links, GoatCounter analytics
### Critical: Feed Link in Head
```php
<?php if (!empty($feedUrl)): ?>
<link rel="alternate" type="application/atom+xml" title="<?= htmlspecialchars($pageTitle ?? 'Feed') ?>" href="<?= htmlspecialchars($feedUrl) ?>">
<?php endif; ?>
```
This MUST remain in `base.php`. It enables feed discovery for any section with `feed = true` in metadata.
### Critical: GoatCounter Analytics
```html
<img style="display:none" src="https://stopplidelsen.goatcounter.com/count?p=<?= htmlspecialchars($_SERVER['REQUEST_URI']) ?>">
```
This is the analytics tracker. Do not remove or modify the URL.
## Conventions
- Escape all user-generated content: `<?= htmlspecialchars($var) ?>`
- Pre-rendered HTML (from markdown) is safe: `<?= $content ?>`
- Use `$translations['key']` for i18n strings
- Use `$langPrefix` before all internal URLs
- Use CSS `<style>` blocks at the bottom of list templates for template-specific styles
- Use CSS nesting inside scoped selectors (e.g., `main > section { ... }`)
- Use `clamp()` for responsive sizing, avoid `@media` queries