folderweb/docs/reference/metadata.md
Ruben 441c8bca68 Add hide_list metadata option to directories
Add support for hide_list metadata option that allows directories to be
displayed as pages instead of lists when they contain subfolders
2025-11-25 20:30:11 +01:00

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:

  1. First H1 heading (# Title in Markdown)
  2. 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 images
  • list-card-grid - Card-style grid
  • list-faq - Expandable FAQ format
  • Any custom template name (without .php extension)

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:

  • author not writer or by
  • tags not keywords or topics
  • summary not description or excerpt

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"