Add documentation for content system, newsletter plugin, petition

system, and templates

Add content system documentation

Add newsletter plugin documentation

Add petition system documentation

Add templates documentation
This commit is contained in:
Ruben 2026-02-06 19:15:29 +01:00
parent 2f024e28be
commit a142b0562f
4 changed files with 521 additions and 0 deletions

125
docs/templates.md Normal file
View file

@ -0,0 +1,125 @@
# 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 |
| `$pageMetadata` | 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