# Content API PHP content files (`.php`) run inside the CMS and have access to a safe, read-only API via the `$api` variable. The output of such a file is automatically placed into the active Twig layout at the `{{ content }}` spot. ## How to pass content to the Twig template There are **two ways** to send content from a `.php` file to the Twig template. The CMS picks the right one automatically: 1. **Echo / print** — everything you echo (or that sits outside `` tags) is captured and placed as `{{ content }}` in the layout. 2. **Return** — if you `return` a string, that string is used as `{{ content }}` (any echoed output is then ignored). Example with echo: ```php --- layout: full_content ---
Welcome to my page.
``` Example with return: ```php --- layout: full_content --- Hello ' . htmlspecialchars($api->getSiteTitle()) . ''; ``` > The frontmatter (`---` block) is stripped by the CMS before the PHP code > runs. The layout key determines which Twig template surrounds the content. ## What you cannot do - You **cannot** set your own Twig variables from a `.php` file. PHP content only feeds the `{{ content }}` placeholder. Other template variables (`menu`, `breadcrumb`, `page_title`, etc.) are set by the CMS based on frontmatter and config — not by your PHP code. - You **cannot** call a ContentAPI from the outside; the class is only instantiated inside `parsePHP()` and is never reachable via a URL. ## Available variables in your PHP file The following variables are available inside a `.php` content file: | Variable | Type | Description | |----------|------|-------------| | `$api` | `ContentAPI` | Read-only access to CMS data | | `$pageMetadata` | `array` | The frontmatter metadata of this file | ## ContentAPI methods ### Pages - `getAllPages(): array` — All content entries (folders + files) as a list of `['path' => ..., 'title' => ..., 'type' => ...]`. `type` is `md`/`php`/`html` for files, `folder` for directories. - `getPage(string $path): ?array` — A specific page; returns `title`, `content`, `path`, `layout`, `metadata`. `$path` may include an extension. - `pageExists(string $path): bool` — Check whether a page exists - `getCurrentPageTitle(): string` — Title of the current page - `getCurrentPagePath(): string` — Path of the current page - `isHomepage(): bool` — Whether the current page is the homepage ### Menu & navigation - `getMenu(): array` — Hierarchical menu structure with `title`, `path`, `children`, `active` - `buildUrl(string $page = 'index', ?string $lang = null, array $params = []): string` — Build a URL ### Configuration - `getConfig(string $key, mixed $default = null): mixed` — Config value via dot notation (e.g. `'features.search_enabled'`) - `getSiteTitle(): string` — Site title from config ### Language - `getCurrentLanguage(): string` — Current language code (e.g. `'nl'`) - `getAvailableLanguages(): array` — Available languages - `t(string $key): string` — Translate a language key ### Search - `getSearchResults(): array` — Search results (empty if not searching) - `isSearching(): bool` — Whether a search is currently active ### Author - `getPageAuthor(): array` — Author metadata from frontmatter (`author_name`, `author_email`, `created`) ## Examples ### Show recent pages ```php --- layout: full_content --- getAllPages(); $currentLang = $api->getCurrentLanguage(); ?> ``` ### Use a config value ```php --- layout: full_content --- getConfig('features.search_enabled', false)): ?> ``` ### Dynamic greeting based on language ```php --- layout: full_content --- getCurrentLanguage(); $greeting = $lang === 'nl' ? 'Welkom' : 'Welcome'; ?>