--- version: "1.0" date: "2025-01-15" author: "DWS Foldsite Team" title: "Template System" description: "Master Foldsite's powerful cascading template system" summary: "Learn how Foldsite's hierarchical template discovery works - from simple defaults to sophisticated, context-aware layouts." quick_tips: - "base.html is required and wraps every page on your site" - "Templates cascade from specific to general - Foldsite uses the first match" - "Use Jinja2 syntax for dynamic content and logic" --- # Template System Foldsite's template system is both powerful and intuitive. Templates are HTML files with **Jinja2** syntax that define how your content is displayed. ## The Template Hierarchy Foldsite uses a **cascading template discovery system**. When rendering a page, it searches for templates from **most specific** to **most general**, using the first match found. ###Understanding Template Priority Think of it like CSS specificity - more specific selectors override general ones: ``` Specific file > Type + Extension > Type + Category > Generic type ``` ### Example: Rendering `content/blog/my-post.md` Foldsite searches in this order: 1. `templates/blog/my-post.html` ← Exact file match 2. `templates/blog/__file.md.html` ← Markdown files in blog/ 3. `templates/blog/__file.document.html` ← Document files in blog/ 4. `templates/__file.md.html` ← All markdown files 5. `templates/__file.document.html` ← All document files 6. `templates/__file.html` ← Any file 7. **First match wins!** ## Required Template: base.html **Every Foldsite project MUST have a `base.html`** in the templates root. This wraps every page on your site. ### Minimal base.html ```html
By {{ metadata.author }}
{% for tag in metadata.tags %} {{ tag }} {% endfor %} ``` ## Template Helpers Foldsite provides powerful helper functions accessible in all templates: ### Content Discovery ```jinja {# Get folder contents #} {% for file in get_folder_contents(currentPath) %} {{ file.name }} {% endfor %} {# Get sibling files #} {% for sibling in get_sibling_content_files(currentPath) %} {{ sibling[0] }} {% endfor %} {# Get sibling folders #} {% for folder in get_sibling_content_folders(currentPath) %} {{ folder[0] }} {% endfor %} ``` ### Blog Functions ```jinja {# Recent blog posts #} {% for post in get_recent_posts(limit=5, folder='blog') %}{{ post.metadata.description }}
{% endif %}{{ item }}
{% endfor %} {% for key, value in metadata.items() %}{{ key }}: {{ value }}
{% endfor %} {# Loop variables #} {% for item in items %} {{ loop.index }} {# 1-indexed #} {{ loop.index0 }} {# 0-indexed #} {{ loop.first }} {# True on first iteration #} {{ loop.last }} {# True on last iteration #} {% endfor %} ``` ### Filters and Functions ```jinja {% for file in get_folder_contents()|sort(attribute='date') %} ... {% endfor %} {% for post in get_recent_posts(limit=5)|reverse %} ... {% endfor %} ``` ## Best Practices ### 1. Start Simple, Add Complexity as Needed Begin with basic templates: ``` templates/ ├── base.html ├── __file.md.html └── __folder.md.html ``` Add specific overrides only when you need different styling or layout. ### 2. Keep base.html Minimal Your base template should handle: - HTML document structure - CSS loading - Site-wide navigation - Footer Leave content-specific layouts to page templates. ### 3. Use Template Helpers Don't manually read files or iterate directories. Use helpers: ```jinja ✓ Good: {% for post in get_recent_posts(limit=5) %} ✗ Bad: {# Trying to manually list files - won't work #} ``` ### 4. Leverage the Cascade Put general templates at the root, specific ones in subdirectories: ``` templates/ ├── __file.md.html # Default for all markdown └── blog/ └── __file.md.html # Special layout for blog ``` ### 5. Test with Debug Mode Enable debug mode in `config.toml` to see template discovery: ```toml [server] debug = true ``` This shows which templates Foldsite considered and why it chose the one it did. ## Common Patterns ### Pattern: Site Navigation In `base.html`: ```html ``` ### Pattern: Sidebar with Recent Posts ```html ``` ### Pattern: Tag Cloud ```html