# Templates ## Template Hierarchy Three levels, rendered inside-out: ``` Content (Markdown/HTML/PHP rendered to HTML string) → page.php or list-*.php (wraps content in semantic markup) → base.php (HTML scaffold: doctype, head, header, nav, main, footer) ``` ## Template Resolution (canonical reference) **`resolveTemplate(string $name): string`** — in `helpers.php`. This is the single resolution function used throughout the framework. 1. Check `custom/templates/{name}.php` 2. Fall back to `app/default/templates/{name}.php` The three core templates (`base`, `page`, `list`) are resolved at context creation and stored in `$ctx->templates`. Other docs reference this section for resolution behavior. ### List Template Override In `metadata.ini`: ```ini [settings] page_template = "list-grid" ``` Resolution for list template override (in `router.php`, at render time): 1. `custom/templates/{page_template}.php` 2. `app/default/templates/{page_template}.php` 3. Fall back to `$ctx->templates->list` (the default resolved at context creation) ### Default Templates Provided | Template | Purpose | |---|---| | `base.php` | HTML document scaffold | | `page.php` | Single page wrapper (`
`) | | `list.php` | Default list with cover images, dates, summaries | | `list-compact.php` | Minimal list variant | | `list-grid.php` | Card grid layout | ## Template Variables Variables are injected via `extract()` — each array key becomes a local variable. ### base.php Variables | Variable | Type | Always Set | Description | |---|---|---|---| | `$content` | string (HTML) | yes | Rendered output from page.php or list template | | `$pageTitle` | ?string | yes | Page title (null if unset) | | `$metaDescription` | ?string | no | SEO description | | `$socialImageUrl` | ?string | no | Cover image URL for og:image | | `$navigation` | array | yes | Menu items: `['title','url','order']` | | `$homeLabel` | string | yes | Home link text | | `$pageCssUrl` | ?string | no | Page-specific CSS URL | | `$pageCssHash` | ?string | no | CSS cache-bust hash | | `$feedUrl` | ?string | no | Atom feed URL (only on lists with `feed = true`) | | `$currentLang` | string | plugin | Language code (from languages plugin) | | `$langPrefix` | string | plugin | URL language prefix | | `$languageUrls` | array | plugin | `[lang => url]` for language switcher | | `$translations` | array | plugin | UI strings for current language | ### page.php Variables All base.php variables plus: | Variable | Type | Description | |---|---|---| | `$content` | string (HTML) | Rendered page content | | `$metadata` | ?array | Page metadata from `metadata.ini` | ### list-*.php Variables All base.php variables plus: | Variable | Type | Description | |---|---|---| | `$items` | array | List items (see schema below) | | `$pageContent` | ?string (HTML) | Rendered content from the list directory itself | | `$metadata` | ?array | List directory metadata | ## List Item Schema Each entry in `$items`: | Key | Type | Always | Description | |---|---|---|---| | `title` | string | yes | From metadata, first heading, or folder name | | `url` | string | yes | Full URL path with trailing slash and lang prefix | | `date` | ?string | no | Formatted date string (plugin-processed) | | `rawDate` | ?string | no | ISO `YYYY-MM-DD` date (for feeds, `