# Template Reference
Complete reference for all templates and available variables in FolderWeb.
## Template System Overview
FolderWeb uses a fallback template system:
1. Check `/custom/templates/{name}.php`
2. Fall back to `/app/default/templates/{name}.php`
Templates are plain PHP files with access to specific variables and the context object.
## Core Templates
### base.php
**Purpose**: HTML wrapper for all pages (header, navigation, footer)
**Used**: On every page render
**Customizable**: Yes
**Available Variables**:
| Variable | Type | Description |
|----------|------|-------------|
| `$content` | string | Rendered page content (HTML) |
| `$ctx` | Context | Full context object |
| `$currentLang` | string | Current language code (e.g., "en", "no") |
| `$navigation` | array | Navigation menu items |
| `$homeLabel` | string | Site title |
| `$translations` | array | UI translation strings |
| `$pageTitle` | string | Current page title |
| `$dirName` | string | Parent directory name |
| `$pageName` | string | Current page filename |
**Example**:
```php
= htmlspecialchars($pageTitle) ?> | = htmlspecialchars($homeLabel) ?>
= $content ?>
```
### page.php
**Purpose**: Wrapper for single pages and articles
**Used**: For file and multi-file pages
**Customizable**: Yes
**Available Variables**:
| Variable | Type | Description |
|----------|------|-------------|
| `$content` | string | Rendered content (HTML) |
| `$pageMetadata` | array | Page metadata from metadata.ini |
| `$translations` | array | UI translation strings |
**Example**:
```php
= $content ?>
```
## List Templates
### list.php
**Purpose**: Simple list view (default)
**Used**: Directories with subdirectories
**Customizable**: Yes
**Available Variables**:
| Variable | Type | Description |
|----------|------|-------------|
| `$items` | array | Array of subdirectory items |
| `$metadata` | array | Directory metadata |
| `$pageContent` | string | Optional intro content (HTML) |
| `$translations` | array | UI translation strings |
**Item Structure**:
Each item in `$items` has:
```php
[
'title' => 'Item Title', // From metadata or H1
'date' => '2. november 2025', // Formatted date
'url' => '/blog/post-slug/', // Full URL with language prefix
'cover' => '/path/to/cover.jpg', // Cover image path or null
'summary' => 'Brief description', // From metadata or null
'pdf' => '/path/to/file.pdf', // PDF file path or null
'redirect' => 'https://...', // External URL or null
]
```
**Example**:
```php
= $pageContent ?>
= htmlspecialchars($item['summary']) ?>
```
### list-grid.php
**Purpose**: Grid layout with cover images
**Used**: Visual blog/portfolio listings
**Customizable**: Yes
**Same variables as list.php**
Features:
- Grid layout
- Cover images
- PDF download links
- "Read more" buttons
**Example**:
```php
= htmlspecialchars($item['summary']) ?>
```
### list-card-grid.php
**Purpose**: Card-style grid with external link support
**Used**: Portfolios, resource lists
**Customizable**: Yes
**Same variables as list.php**
Features:
- Card-style layout
- PDF download support
- External redirect support
- Cover images
**Example**:
```php
```
### list-faq.php
**Purpose**: Expandable FAQ/Q&A format
**Used**: FAQ sections, documentation
**Customizable**: Yes
**Same variables as list.php**
Features:
- Collapsible `` elements
- Semantic HTML
- Keyboard accessible
**Example**:
```php
= $pageContent ?>
```
## Context Object
All templates have access to `$ctx` (Context object):
### Properties
| Property | Type | Description |
|----------|------|-------------|
| `$ctx->contentDir` | string | Path to content directory |
| `$ctx->currentLang` | string | Current language code |
| `$ctx->defaultLang` | string | Default language code |
| `$ctx->availableLangs` | array | Available language codes |
| `$ctx->langPrefix` | string | URL language prefix (e.g., "/en" or "") |
| `$ctx->requestPath` | string | Current request path |
| `$ctx->hasTrailingSlash` | bool | Whether path has trailing slash |
| `$ctx->navigation` | array | Navigation menu items (computed) |
| `$ctx->homeLabel` | string | Site title (computed) |
| `$ctx->translations` | array | UI translations (computed) |
### Example Usage
```php
availableLangs as $lang): ?>
defaultLang
? '/' . trim($ctx->requestPath, '/')
: '/' . $lang . '/' . trim($ctx->requestPath, '/');
?>
currentLang ? 'aria-current="true"' : '' ?>>
= strtoupper($lang) ?>
```
## Navigation Array
Structure of `$navigation` items:
```php
[
[
'title' => 'Blog',
'url' => '/blog/',
'order' => 1
],
[
'title' => 'About',
'url' => '/about/',
'order' => 2
],
// ...
]
```
Already sorted by `menu_order` field.
## Translation Array
Structure of `$translations`:
```php
[
'home' => 'Home',
'read_more' => 'Read more',
'categories' => 'Categories',
'tags' => 'Tags',
'footer_text' => 'Made with FolderWeb',
'footer_handcoded' => 'Generated in',
'footer_page_time' => 'ms',
// ... custom translations
]
```
## Helper Functions Available in Templates
### resolveTemplate()
Find custom or default template:
```php
$templatePath = resolveTemplate('base', 'templates');
$cssPath = resolveTemplate('base.css', 'styles');
```
### htmlspecialchars()
Escape output (always use for user content):
```php
= htmlspecialchars($variable) ?>
```
### Other PHP Functions
All standard PHP functions are available:
- `isset()`, `empty()`
- `count()`, `array_filter()`
- `date()`, `time()`
- String functions
- etc.
## Creating Custom Templates
### Step 1: Create Template File
```bash
touch custom/templates/my-custom-list.php
```
### Step 2: Use Standard Variables
Custom list templates receive `$items`, `$metadata`, `$pageContent`, `$translations`.
### Step 3: Apply in Metadata
**content/my-section/metadata.ini**:
```ini
page_template = "my-custom-list"
```
Note: Omit `.php` extension.
## Template Best Practices
### Always Escape Output
```php
= htmlspecialchars($item['title']) ?>
= $item['title'] ?>
```
### Check Variables Before Use
```php
```
### Use Null Coalescing
```php
$author = $metadata['author'] ?? 'Anonymous';
```
### Semantic HTML
```php
```
### Accessibility
```php