# How to Create Custom Templates
This guide shows you how to override default templates with your own custom designs.
## Overview
FolderWeb uses a template fallback system:
1. Check `/custom/templates/` for custom version
2. Fall back to `/app/default/templates/` if not found
**Important**: Never modify files in `/app/default/` — always create custom versions in `/custom/`.
## Available Templates
- **base.php** - HTML wrapper (header, navigation, footer)
- **page.php** - Single page/article wrapper
- **list.php** - Simple list view (default)
- **list-grid.php** - Grid layout with images
- **list-card-grid.php** - Card grid (supports PDFs, external links)
- **list-faq.php** - Expandable FAQ/Q&A format
## Customizing the Base Template
The base template controls your entire site layout.
### Step 1: Copy the Default
```bash
mkdir -p custom/templates
cp app/default/templates/base.php custom/templates/base.php
```
### Step 2: Edit Your Copy
The base template has access to these variables:
```php
$content // The rendered page content (HTML)
$currentLang // Current language code (e.g., "en", "no")
$navigation // Array of navigation items
$homeLabel // Site title
$translations // Translation strings
$pageTitle // Current page title
$dirName // Parent directory name (for CSS classes)
$pageName // Current page name (for CSS classes)
```
### Example: Add a Custom Header
```php
```
## Customizing the Page Template
The page template wraps individual articles and pages.
### Step 1: Copy the Default
```bash
cp app/default/templates/page.php custom/templates/page.php
```
### Step 2: Customize
Available variables:
```php
$content // Main content HTML
$pageMetadata // Array of metadata (tags, categories, etc.)
$translations // Translation strings
```
### Example: Add Author Information
```php
Written by = htmlspecialchars($pageMetadata['author']) ?>
```
### Step 3: Apply Your Template
Create a `metadata.ini` in the directory:
```ini
page_template = "list-custom"
```
## Template Best Practices
### Always Escape Output
Prevent XSS attacks by escaping user-generated content:
```php
= htmlspecialchars($item['title']) ?>
```
### Use Short Echo Tags
FolderWeb uses modern PHP, so short tags are always available:
```php
= $variable ?> // Good
// Also works, but verbose
```
### Check Before Using
Always check if variables exist:
```php
```
### Leverage CSS Classes
The base template adds dynamic classes to ``:
```php
```
Use these for page-specific styling without JavaScript.
## Advanced: Accessing the Context Object
Templates can access the full context object `$ctx`:
```php
contentDir // Path to content directory
$ctx->currentLang // Current language
$ctx->defaultLang // Default language
$ctx->availableLangs // Array of available languages
$ctx->langPrefix // URL prefix (e.g., "/en" or "")
$ctx->requestPath // Current request path
$ctx->hasTrailingSlash // Boolean
$ctx->navigation // Navigation array (computed property)
$ctx->homeLabel // Site title (computed property)
$ctx->translations // Translation array (computed property)
?>
```
## Example: Breadcrumb Navigation
Add breadcrumbs to your page template:
```php
```
## Testing Your Templates
1. Clear your browser cache
2. Reload the page
3. Check browser console for errors
4. Validate HTML with W3C validator
## Reverting Changes
To revert to default templates, simply delete your custom version:
```bash
rm custom/templates/base.php
```
FolderWeb will automatically fall back to the default.
## Related
- [Customizing Styles](custom-styles.md)
- [Template Reference](../reference/templates.md)
- [Metadata Reference](../reference/metadata.md)