Add support for hide_list metadata option that allows directories to be displayed as pages instead of lists when they contain subfolders
11 KiB
Metadata Reference
Complete reference for all metadata fields and their usage in metadata.ini files.
File Format
Metadata files use INI format:
; Comments start with semicolon
key = "value"
array[] = "value1"
array[] = "value2"
[section]
key = "section value"
Standard Fields
title
Type: String
Used in: All content types
Purpose: Override automatic title extraction
title = "Custom Page Title"
If not provided, FolderWeb extracts title from:
- First H1 heading (
# Titlein Markdown) - Folder name (as fallback)
Multi-language:
title = "English Title"
[no]
title = "Norsk Tittel"
[fr]
title = "Titre Français"
date
Type: Date string (YYYY-MM-DD)
Used in: Blog posts, articles
Purpose: Override automatic date extraction
date = "2025-11-02"
If not provided, FolderWeb extracts date from folder names like 2025-11-02-post-title.
Dates are automatically formatted in Norwegian style: "2. november 2025"
summary
Type: String
Used in: List views
Purpose: Brief description for cards and listings
summary = "A concise description that appears in blog listings."
Multi-language:
summary = "English summary"
[no]
summary = "Norsk sammendrag"
menu
Type: Boolean
Used in: Top-level directories
Purpose: Include in site navigation
menu = true
Accepted values: true, false, 1, 0, yes, no, on, off
menu_order
Type: Integer
Used in: Navigation items
Purpose: Control navigation order (lower numbers first)
menu = true
menu_order = 1
page_template
Type: String
Used in: Directories with subdirectories
Purpose: Choose list template
page_template = "list-grid"
Available values:
list- Simple list (default)list-grid- Grid with cover imageslist-card-grid- Card-style gridlist-faq- Expandable FAQ format- Any custom template name (without
.phpextension)
slug
Type: String
Used in: Language sections
Purpose: Translate URL segments
[no]
slug = "om-oss"
[fr]
slug = "a-propos"
The actual folder is about/, but URLs become:
/about/(English)/no/om-oss/(Norwegian)/fr/a-propos/(French)
hide_list
Type: Boolean
Used in: Directories with subdirectories
Purpose: Hide list of subfolders and show only page content
hide_list = true
When enabled, directories with subfolders display as regular pages instead of showing a list view. Useful when you need subfolders for organization but want to present a single page to visitors.
Accepted values: true, false, 1, 0, yes, no, on, off
redirect
Type: URL string
Used in: List items (with list-card-grid template)
Purpose: Link to external site instead of internal page
redirect = "https://example.com"
Creates an external link card in card grid layouts.
Custom Fields
You can add any custom fields for use in your templates:
Common Custom Fields
; Author information
author = "Jane Doe"
author_email = "jane@example.com"
author_url = "https://janedoe.com"
; Content metadata
reading_time = "5 min"
difficulty = "intermediate"
featured = true
; Categorization
tags[] = "PHP"
tags[] = "Tutorial"
tags[] = "Web Development"
categories[] = "Programming"
categories[] = "Backend"
; SEO
meta_description = "Complete guide to FolderWeb metadata"
meta_keywords = "metadata, ini, folderweb"
; Social sharing
og_image = "/blog/post/social-card.jpg"
twitter_card = "summary_large_image"
; Version tracking
version = "1.2.0"
last_updated = "2025-11-02"
; Display options
hide_date = true
hide_author = false
hide_list = true
show_toc = true
; External references
github_url = "https://github.com/user/repo"
demo_url = "https://demo.example.com"
download_url = "/files/document.pdf"
Array Fields
Use [] syntax for array values:
tags[] = "PHP"
tags[] = "Web Development"
tags[] = "Tutorial"
authors[] = "Jane Doe"
authors[] = "John Smith"
related_posts[] = "/blog/post-1/"
related_posts[] = "/blog/post-2/"
Access in templates:
<?php foreach ($metadata['tags'] as $tag): ?>
<span><?= htmlspecialchars($tag) ?></span>
<?php endforeach; ?>
Boolean Values
Accepted boolean formats:
; True values
featured = true
featured = 1
featured = yes
featured = on
; False values
draft = false
draft = 0
draft = no
draft = off
Language Sections
Use [lang] sections for multi-language overrides:
; Base values (default language)
title = "About Us"
summary = "Learn about our company"
slug = "about"
; Norwegian overrides
[no]
title = "Om Oss"
summary = "Lær om vårt selskap"
slug = "om-oss"
; French overrides
[fr]
title = "À Propos"
summary = "Découvrez notre entreprise"
slug = "a-propos"
; Fields not overridden inherit base values
Language-specific fields override base fields for that language.
Comments
Use ; or # for comments:
; This is a comment
title = "My Page"
# This is also a comment
date = "2025-11-02"
; Comments can be on same line as values
menu = true ; Include in navigation
Special Characters
Quotes
Use quotes for values with special characters:
; Optional for simple values
title = Simple Title
title = "Simple Title"
; Required for values with spaces at start/end
title = " Padded Title "
; Required for values with special characters
summary = "Use \"quotes\" for nested quotes"
summary = 'Single quotes work too'
Escape Sequences
Standard INI escape sequences:
; Newline
text = "First line\nSecond line"
; Tab
text = "Indented\ttext"
; Quote
text = "He said \"Hello\""
Metadata Location
Directory Metadata
Place metadata.ini in the directory it describes:
content/blog/metadata.ini # Blog configuration
content/about/metadata.ini # About page metadata
Item Metadata
Place metadata.ini in each subdirectory:
content/blog/2025-11-01-post/metadata.ini # Post metadata
content/blog/2025-11-02-post/metadata.ini # Post metadata
Metadata Scope
Metadata applies only to its directory. No inheritance from parent directories.
Complete Examples
Blog Configuration
content/blog/metadata.ini:
; Display settings
title = "Blog"
page_template = "list-grid"
; Navigation
menu = true
menu_order = 1
; Multi-language
[no]
title = "Blogg"
slug = "blogg"
[fr]
title = "Blog"
slug = "blog"
Blog Post
content/blog/2025-11-02-web-performance/metadata.ini:
; Basic information
title = "Optimizing Web Performance"
date = "2025-11-02"
summary = "Learn techniques to make your website faster."
; Author information
author = "Jane Developer"
author_url = "https://jane.dev"
; Content metadata
reading_time = "8 min"
difficulty = "intermediate"
featured = true
; Categorization
tags[] = "Performance"
tags[] = "Web Development"
tags[] = "Optimization"
categories[] = "Technical"
categories[] = "Tutorial"
; SEO
meta_description = "Complete guide to web performance optimization"
; Multi-language versions
[no]
title = "Optimalisering av Nettsideytelse"
summary = "Lær teknikker for å gjøre nettsiden din raskere."
[fr]
title = "Optimisation des Performances Web"
summary = "Apprenez à accélérer votre site web."
Documentation Page
content/docs/metadata.ini:
title = "Documentation"
menu = true
menu_order = 2
page_template = "list"
; Custom fields
show_toc = true
github_url = "https://github.com/user/repo"
[no]
title = "Dokumentasjon"
slug = "dokumentasjon"
Portfolio Project
content/portfolio/project-name/metadata.ini:
title = "Project Name"
date = "2025-11-02"
summary = "Brief project description"
; External links
redirect = "https://project-demo.com"
github_url = "https://github.com/user/project"
; Project details
client = "Company Name"
role = "Lead Developer"
technologies[] = "PHP"
technologies[] = "HTML"
technologies[] = "CSS"
[no]
title = "Prosjektnavn"
summary = "Kort prosjektbeskrivelse"
FAQ Section
content/faq/metadata.ini:
title = "Frequently Asked Questions"
menu = true
menu_order = 4
page_template = "list-faq"
[no]
title = "Ofte Stilte Spørsmål"
slug = "oss"
[fr]
title = "Questions Fréquemment Posées"
slug = "faq"
Accessing Metadata in Templates
In Page Templates
Variable: $pageMetadata
<?php
$title = $pageMetadata['title'] ?? 'Untitled';
$author = $pageMetadata['author'] ?? null;
$tags = $pageMetadata['tags'] ?? [];
?>
<article>
<h1><?= htmlspecialchars($title) ?></h1>
<?php if ($author): ?>
<p class="author">By <?= htmlspecialchars($author) ?></p>
<?php endif; ?>
<?= $content ?>
<?php if (!empty($tags)): ?>
<div class="tags">
<?php foreach ($tags as $tag): ?>
<span class="tag"><?= htmlspecialchars($tag) ?></span>
<?php endforeach; ?>
</div>
<?php endif; ?>
</article>
In List Templates
Variable: $metadata (directory metadata), $items (item metadata)
<!-- Directory metadata -->
<h1><?= htmlspecialchars($metadata['title'] ?? 'Untitled') ?></h1>
<!-- Items with their metadata -->
<?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; ?>
</article>
<?php endforeach; ?>
Validation
Check Syntax
Test INI file parsing:
php -r "print_r(parse_ini_file('content/blog/metadata.ini', true));"
Common Errors
Unquoted special characters:
; Wrong
title = Title with: special characters
; Correct
title = "Title with: special characters"
Missing array brackets:
; Wrong (only last value kept)
tags = "PHP"
tags = "Tutorial"
; Correct (array created)
tags[] = "PHP"
tags[] = "Tutorial"
Invalid section names:
; Wrong
[language.no]
; Correct
[no]
Best Practices
Always Escape Output
<?= htmlspecialchars($metadata['title']) ?>
Provide Defaults
$author = $metadata['author'] ?? 'Anonymous';
$tags = $metadata['tags'] ?? [];
Check Before Using
<?php if (isset($metadata['author'])): ?>
<p>By <?= htmlspecialchars($metadata['author']) ?></p>
<?php endif; ?>
Use Consistent Field Names
Stick to standard names across your site:
authornotwriterorbytagsnotkeywordsortopicssummarynotdescriptionorexcerpt
Document Custom Fields
Add comments explaining non-obvious fields:
; Featured articles appear at top of homepage
featured = true
; External demo link (overrides internal page)
demo_url = "https://demo.example.com"