folderweb/docs/how-to/working-with-metadata.md

482 lines
9.2 KiB
Markdown
Raw Normal View History

2025-11-02 13:46:47 +01:00
# How to Work with Metadata
This guide shows you how to use `metadata.ini` files to control page behavior, appearance, and content.
## What is Metadata?
Metadata provides structured information about your content directories without cluttering your content files. It's stored in `metadata.ini` files using the INI format.
## Basic Metadata File
Create `metadata.ini` in any content directory:
```ini
title = "My Page Title"
date = "2025-11-02"
summary = "A brief description of this page."
```
## Common Metadata Fields
### Title
Controls the displayed title (overrides automatic title extraction):
```ini
title = "Custom Page Title"
```
If not provided, FolderWeb extracts the title from:
1. First H1 heading in content (`# Title` in Markdown)
2. Folder name (as fallback)
### Date
Set an explicit date (overrides folder name date extraction):
```ini
date = "2025-11-02"
```
Format: `YYYY-MM-DD`
FolderWeb automatically formats this in Norwegian style: "2. november 2025"
### Summary
Add a summary for list views:
```ini
summary = "This appears in blog listings and card grids."
```
Summaries are displayed in:
- List views
- Grid layouts
- Card grids
## Navigation Control
### Adding to Menu
```ini
menu = true
menu_order = 1
```
- **menu**: Set to `true` to include in site navigation
- **menu_order**: Controls order (lower numbers appear first)
**Example** - Setting up main navigation:
**content/blog/metadata.ini**:
```ini
menu = true
menu_order = 1
title = "Blog"
```
**content/about/metadata.ini**:
```ini
menu = true
menu_order = 2
title = "About"
```
**content/contact/metadata.ini**:
```ini
menu = true
menu_order = 3
title = "Contact"
```
Result: Navigation shows "Blog", "About", "Contact" in that order.
## Template Control
### Choosing List Template
For directories with subdirectories, control which list template is used:
```ini
page_template = "list-grid"
```
Available templates:
- `list` - Simple list (default)
- `list-grid` - Grid with cover images
- `list-card-grid` - Card-style grid (supports PDFs, external links)
- `list-faq` - Expandable FAQ format
**Example** - Blog with grid layout:
**content/blog/metadata.ini**:
```ini
title = "Blog"
page_template = "list-grid"
```
## External Redirects
Make a directory item link externally (used with `list-card-grid`):
```ini
redirect = "https://example.com"
```
**Example** - Portfolio with external links:
**content/portfolio/project-live-site/metadata.ini**:
```ini
title = "Visit Live Site"
summary = "Check out the deployed project."
redirect = "https://myproject.com"
```
When using the `list-card-grid` template, this creates a card that links to the external URL instead of an internal page.
## Multi-Language Metadata
Use sections for language-specific overrides:
```ini
; Default language values
title = "About Us"
summary = "Learn more about our company."
[no]
title = "Om Oss"
summary = "Lær mer om vårt selskap."
slug = "om-oss"
[fr]
title = "À Propos"
summary = "Découvrez notre entreprise."
slug = "a-propos"
```
Language sections override base values for that language.
### Translated Slugs
The `slug` field in language sections changes the URL:
```ini
[no]
slug = "om-oss"
```
Now the Norwegian version is accessible at `/no/om-oss/` instead of `/no/about/`.
## Custom Metadata Fields
You can add any custom fields you need:
```ini
title = "Article Title"
author = "Jane Doe"
reading_time = "5 min"
difficulty = "intermediate"
featured = true
```
Access these in custom templates:
```php
<?php if (isset($metadata['author'])): ?>
<p class="author">By <?= htmlspecialchars($metadata['author']) ?></p>
<?php endif; ?>
<?php if (isset($metadata['reading_time'])): ?>
<span class="reading-time"><?= htmlspecialchars($metadata['reading_time']) ?></span>
<?php endif; ?>
```
## Arrays in Metadata
INI format supports arrays using repeated keys:
```ini
tags[] = "PHP"
tags[] = "Web Development"
tags[] = "Tutorial"
categories[] = "Programming"
categories[] = "Backend"
```
Access in templates:
```php
<?php if (!empty($metadata['tags'])): ?>
<div class="tags">
<?php foreach ($metadata['tags'] as $tag): ?>
<span class="tag"><?= htmlspecialchars($tag) ?></span>
<?php endforeach; ?>
</div>
<?php endif; ?>
```
## Boolean Values
Use `true`, `false`, `1`, `0`, `yes`, `no`, `on`, `off`:
```ini
menu = true
featured = yes
draft = false
```
## Comments
Add comments with `;` or `#`:
```ini
; This is a comment
title = "My Page"
# This is also a comment
date = "2025-11-02"
```
## Metadata Inheritance
Metadata does **not** inherit from parent directories. Each directory needs its own `metadata.ini`.
## Metadata for List Items
When a directory is displayed in a list view, FolderWeb loads its metadata:
**content/blog/2025-11-01-first-post/metadata.ini**:
```ini
title = "My First Blog Post"
date = "2025-11-01"
summary = "An introduction to blogging with FolderWeb."
```
This metadata appears in the blog listing at `/blog/`.
## Complete Example: Blog Setup
### Blog Directory Metadata
**content/blog/metadata.ini**:
```ini
title = "Blog"
menu = true
menu_order = 1
page_template = "list-grid"
[no]
title = "Blogg"
slug = "blogg"
```
### Individual Post Metadata
**content/blog/2025-11-02-web-performance/metadata.ini**:
```ini
title = "Optimizing Web Performance"
date = "2025-11-02"
summary = "Learn techniques to make your website faster."
author = "Jane Developer"
reading_time = "8 min"
tags[] = "Performance"
tags[] = "Web Development"
tags[] = "Optimization"
categories[] = "Technical"
categories[] = "Tutorial"
[no]
title = "Optimalisering av Nettsideytelse"
summary = "Lær teknikker for å gjøre nettsiden din raskere."
```
## Accessing Metadata in Templates
### In Page Templates
```php
<?php
// Page-specific metadata
$metadata = $pageMetadata;
// Access fields
$author = $metadata['author'] ?? 'Unknown';
$tags = $metadata['tags'] ?? [];
?>
<article>
<header>
<h1><?= htmlspecialchars($metadata['title'] ?? '') ?></h1>
<p class="author">By <?= htmlspecialchars($author) ?></p>
</header>
<?= $content ?>
<?php if (!empty($tags)): ?>
<footer class="tags">
<?php foreach ($tags as $tag): ?>
<span><?= htmlspecialchars($tag) ?></span>
<?php endforeach; ?>
</footer>
<?php endif; ?>
</article>
```
### In List Templates
Each item in `$items` includes its metadata:
```php
<?php foreach ($items as $item): ?>
<article>
<h2>
<a href="<?= $item['url'] ?>">
<?= htmlspecialchars($item['title']) ?>
</a>
</h2>
<?php if ($item['date']): ?>
<time><?= $item['date'] ?></time>
<?php endif; ?>
<?php if ($item['summary']): ?>
<p><?= htmlspecialchars($item['summary']) ?></p>
<?php endif; ?>
<?php if ($item['cover']): ?>
<img src="<?= $item['cover'] ?>" alt="">
<?php endif; ?>
<?php if ($item['pdf']): ?>
<a href="<?= $item['pdf'] ?>" download>Download PDF</a>
<?php endif; ?>
<?php if ($item['redirect']): ?>
<a href="<?= $item['redirect'] ?>" target="_blank" rel="noopener">
Visit External Link
</a>
<?php endif; ?>
</article>
<?php endforeach; ?>
```
## Debugging Metadata
### Check if Metadata is Loaded
In your template, dump the metadata:
```php
<pre><?php var_dump($metadata); ?></pre>
```
Or for list items:
```php
<pre><?php var_dump($items); ?></pre>
```
### Verify INI Syntax
Use PHP to test your INI file:
```bash
php -r "print_r(parse_ini_file('content/blog/metadata.ini', true));"
```
This shows parsed values and helps identify syntax errors.
## Best Practices
### Use Consistent Field Names
Stick to standard fields for common data:
- `title` for titles
- `date` for dates
- `summary` for summaries
- `author` for authors
### Escape Output
Always escape metadata in templates:
```php
<?= htmlspecialchars($metadata['title']) ?>
```
### Provide Defaults
Use null coalescing for missing fields:
```php
$author = $metadata['author'] ?? 'Anonymous';
$date = $metadata['date'] ?? 'Unknown date';
```
### Keep It Simple
Only add metadata fields you actually use. Don't over-engineer.
### Use Comments
Document non-obvious metadata:
```ini
; Featured articles appear at the top of the homepage
featured = true
; Legacy field kept for backwards compatibility
old_url = "/blog/old-slug/"
```
## Common Patterns
### Blog Post
```ini
title = "Post Title"
date = "2025-11-02"
summary = "Brief description"
author = "Author Name"
tags[] = "tag1"
tags[] = "tag2"
```
### Documentation Page
```ini
title = "API Reference"
menu = true
menu_order = 3
page_template = "list"
```
### Portfolio Item
```ini
title = "Project Name"
date = "2025-11-02"
summary = "Project description"
redirect = "https://live-demo.com"
```
### FAQ Section
```ini
title = "Frequently Asked Questions"
menu = true
menu_order = 4
page_template = "list-faq"
```
## Related
- [Multi-Language Guide](multi-language.md)
- [Custom Templates](custom-templates.md)
- [Metadata Reference](../reference/metadata.md)
- [Template Variables Reference](../reference/templates.md)