# Context API ## Context Class Defined in `app/context.php`. Stores request state and plugin data. ### Constructor Properties (readonly) | Property | Type | Access | Description | |---|---|---|---| | `contentDir` | string | `$ctx->contentDir` | Absolute path to content root | | `templates` | Templates | `$ctx->templates` | Resolved template paths | | `requestPath` | string | `$ctx->requestPath` | URL path with leading/trailing slashes removed | | `hasTrailingSlash` | bool | `$ctx->hasTrailingSlash` | Whether original request had trailing slash | These use PHP 8.4 `private(set)` — readable but not writable from outside the class. **Exception:** The language plugin modifies `requestPath` via reflection to strip the language prefix. This is an intentional framework-level operation. ### Computed Properties | Property | Type | Description | |---|---|---| | `navigation` | array | `buildNavigation($this)` — lazy-computed on access | | `homeLabel` | string | From root `metadata.ini` `slug` field, default `"Home"`. Note: reads `slug`, not `title` — typically set to a short label like "Home" or "Hjem" | ### Plugin Data Store ```php $ctx->set(string $key, mixed $value): void $ctx->get(string $key, mixed $default = null): mixed $ctx->has(string $key): bool ``` Also supports magic property access: `$ctx->foo = 'bar'` / `$val = $ctx->foo`. ### Built-in Context Keys (set by language plugin) | Key | Type | Set By | Description | |---|---|---|---| | `currentLang` | string | languages.php | Active language code (e.g., `"en"`) | | `defaultLang` | string | languages.php | Default language from config | | `availableLangs` | array | languages.php | All configured language codes | | `langPrefix` | string | languages.php | URL prefix: `""` for default, `"/no"` for others | | `translations` | array | languages.php | Merged translation strings for current language | ### Built-in Context Keys (set by router.php for list pages) These are set in the list case so that `renderTemplate()` can pass them to `base.php`: | Key | Type | Description | |---|---|---| | `pageTitle` | ?string | Page title from metadata (for `` tag) | | `metaDescription` | ?string | SEO description | | `pageCssUrl` | ?string | Page-specific CSS URL | | `pageCssHash` | ?string | CSS cache-bust hash | | `feedUrl` | ?string | Atom feed URL (set when `feed = true` in metadata) | ## Templates Class Defined in `app/context.php`. Readonly value object. ```php readonly class Templates { public function __construct( public string $base, # Path to base.php public string $page, # Path to page.php public string $list # Path to list.php ) {} } ``` Resolved by `resolveTemplate()` — see `06-templates.md` "Template Resolution (canonical reference)" for the full lookup chain. The list template can be overridden per-directory via `page_template` in metadata — this is resolved at render time in `router.php`, not stored in the Templates object. ## Global Access Context is stored in `$GLOBALS['ctx']` after creation. Plugins that need context outside hook callbacks access it via: ```php $ctx = $GLOBALS['ctx']; ```