# Metadata Reference Metadata files (`metadata.ini`) configure individual pages and directories. They control titles, URLs, templates, navigation, and more. ## Basic Structure ```ini title = "Page Title" summary = "Short description" date = "2024-12-15" search_description = "SEO-friendly description" ``` Place `metadata.ini` in any content directory: ``` content/blog/my-post/ ├── index.md └── metadata.ini ``` ## Core Fields ### `title` The page or item title. ```ini title = "My Blog Post" ``` **Default:** Extracted from first `# Heading` in Markdown, or folder name **Used in:** Page ``, list items, navigation menu **Type:** String ### `summary` Short description shown in list views. ```ini summary = "A brief introduction to this topic" ``` **Default:** None (empty) **Used in:** List item previews, RSS feeds, social media cards **Type:** String **Recommended length:** 150-200 characters ### `date` Publication or modification date. ```ini date = "2024-12-15" ``` **Default:** Extracted from folder name (`YYYY-MM-DD-title`) **Format:** `YYYY-MM-DD` (ISO 8601) **Used in:** List sorting, date displays, `<time>` elements **Type:** String (date) ### `search_description` SEO meta description for search engines. ```ini search_description = "Learn how to build fast, maintainable websites with FolderWeb" ``` **Default:** Uses `summary` if not set **Used in:** `<meta name="description">` tag **Type:** String **Recommended length:** 150-160 characters ### `slug` Custom URL slug (overrides folder name). ```ini slug = "custom-url" ``` **Default:** Folder name (with date prefix removed) **Used in:** URL generation **Type:** String (alphanumeric, hyphens, underscores) **Example:** ``` Folder: content/blog/2024-12-15-very-long-title/ Slug: short-title URL: /blog/short-title/ ``` ### `menu` Show this page in the navigation menu. ```ini menu = 1 ``` **Default:** `0` (not in menu) **Values:** `1` (show) or `0` (hide) **Type:** Integer ### `menu_order` Position in navigation menu (lower numbers first). ```ini menu = 1 menu_order = 10 ``` **Default:** `999` (last) **Used in:** Navigation sorting **Type:** Integer **Example:** ```ini # Home menu = 1 menu_order = 1 # About menu = 1 menu_order = 10 # Blog menu = 1 menu_order = 20 # Contact menu = 1 menu_order = 30 ``` ## Settings Section Advanced settings go in a `[settings]` section: ```ini title = "My Page" [settings] page_template = "list-grid" show_date = true hide_list = false ``` ### `page_template` Which template to use for list views. ```ini [settings] page_template = "list-grid" ``` **Default:** `list` (uses `list.php`) **Available templates:** - `list` — Simple vertical list - `list-grid` — Card grid layout - `list-compact` — Minimal compact list - Custom templates you create **Used in:** List view rendering **Type:** String (template name without `.php`) ### `show_date` Display the date on the page. ```ini [settings] show_date = true ``` **Default:** `true` **Values:** `true` or `false` **Type:** Boolean ### `hide_list` Don't show list view even if directory has subdirectories. ```ini [settings] hide_list = true ``` **Default:** `false` **Values:** `true` or `false` **Type:** Boolean **Use case:** Section landing pages that should show content instead of list ## Language-Specific Overrides Add language-specific sections to override fields: ```ini title = "About Us" summary = "Learn about our company" slug = "about" [no] title = "Om oss" summary = "Les om bedriften vår" slug = "om" [de] title = "Über uns" summary = "Erfahren Sie mehr über unser Unternehmen" slug = "uber-uns" ``` **Supported fields in language sections:** - `title` - `summary` - `search_description` - `slug` **Language codes:** Must match your configured languages (`config.ini`). **URLs with language-specific slugs:** - English: `/about/` - Norwegian: `/no/om/` - German: `/de/uber-uns/` ## Custom Fields Add any custom fields you need: ```ini title = "Project X" author = "Jane Doe" client = "ACME Corp" project_url = "https://example.com" featured = true tags = "web,design,portfolio" ``` Access custom fields in templates: ```php <?php if (isset($metadata['author'])): ?> <p>By <?= htmlspecialchars($metadata['author']) ?></p> <?php endif; ?> <?php if (isset($metadata['project_url'])): ?> <a href="<?= htmlspecialchars($metadata['project_url']) ?>"> View Project </a> <?php endif; ?> ``` Or in plugins: ```php Hooks::add(Hook::TEMPLATE_VARS, function(array $vars, Context $ctx) { $metadata = $ctx->get('metadata', []); if (isset($metadata['tags'])) { $vars['tags'] = explode(',', $metadata['tags']); } return $vars; }); ``` ## Complete Example **content/blog/2024-12-15-building-fast-sites/metadata.ini:** ```ini # Core fields title = "Building Fast Websites" summary = "Learn how to optimize your site for speed and performance" date = "2024-12-15" search_description = "A comprehensive guide to building fast, performant websites in 2024" # Navigation menu = 0 # Don't show in main menu menu_order = 999 # Custom slug slug = "fast-sites" # Settings [settings] show_date = true # Custom fields author = "Jane Doe" category = "Web Performance" tags = "performance,optimization,web" estimated_reading_time = 8 # Norwegian translation [no] title = "Bygge raske nettsider" summary = "Lær hvordan du optimaliserer nettstedet ditt for hastighet og ytelse" search_description = "En omfattende guide til å bygge raske, effektive nettsteder i 2024" slug = "raske-sider" ``` ## Metadata Priority When determining values, FolderWeb follows this priority: 1. **Language-specific metadata** (e.g., `[no]` section) 2. **Root metadata** (e.g., `title = "..."`) 3. **Auto-extracted values** (e.g., first heading, folder date) 4. **Defaults** (e.g., folder name) **Example:** ``` Folder: content/blog/2024-12-15-my-post/ ``` **Title resolution:** 1. Check `metadata.ini` for `[en] title = "..."` 2. Check `metadata.ini` for `title = "..."` 3. Extract from first `# Heading` in Markdown 4. Use folder name: "my-post" ## Metadata in List Items When rendering list views, each item receives these metadata fields: ```php $item = [ 'url' => '/blog/my-post/', 'path' => '/content/blog/2024-12-15-my-post', 'title' => 'My Post', 'summary' => 'Short description', 'date' => '2024-12-15', 'formatted_date' => '15. desember 2024', // Language-specific 'cover_image' => '/blog/my-post/cover.jpg', // If exists // All custom metadata fields... 'author' => 'Jane Doe', 'tags' => 'web,design', ]; ``` Access in list templates: ```php <?php foreach ($items as $item): ?> <article> <h2><?= htmlspecialchars($item['title']) ?></h2> <?php if (isset($item['author'])): ?> <p>By <?= htmlspecialchars($item['author']) ?></p> <?php endif; ?> <?php if (isset($item['summary'])): ?> <p><?= htmlspecialchars($item['summary']) ?></p> <?php endif; ?> </article> <?php endforeach; ?> ``` ## Best Practices ### 1. Use Consistent Field Names ```ini # Good: consistent naming author = "Jane Doe" published_date = "2024-12-15" featured = true # Bad: inconsistent naming Author = "Jane Doe" PublishDate = "2024-12-15" is_featured = true ``` ### 2. Keep Summaries Concise ```ini # Good summary = "Learn to optimize website performance in 5 steps" # Too long summary = "This comprehensive article will teach you everything you need to know about optimizing website performance, including lazy loading, code splitting, image optimization, and much more in detailed steps with examples" ``` ### 3. Use Semantic Custom Fields ```ini # Good: clear purpose author = "Jane Doe" category = "Tutorial" difficulty = "Beginner" # Bad: unclear purpose field1 = "Jane Doe" field2 = "Tutorial" field3 = "Beginner" ``` ### 4. Add Comments ```ini # SEO and social media title = "Building Fast Websites" search_description = "A guide to web performance optimization" # Author and categorization author = "Jane Doe" category = "Performance" # Custom display options featured = true # Show in featured section priority = 10 # Higher = more prominent ``` ## Debugging Metadata To see parsed metadata, create a debug template: **custom/templates/page.php:** ```php <pre><?php print_r($metadata); ?></pre> <hr> <?= $content ?> ``` Or in list templates: ```php <pre><?php print_r($items); ?></pre> <hr> <?= $pageContent ?> ``` **Remember to revert** before deploying to production. ## What's Next? - **[Template Variables](#)** — See how metadata is used in templates - **[Internationalization](#)** — Use language-specific metadata - **[Creating Plugins](#)** — Process metadata in custom plugins