VOOZH about

URL: https://deepwiki.com/calevans/staticforge/5.3-html-processing

⇱ HTML Processing | calevans/staticforge | DeepWiki


Loading...
Last indexed: 11 February 2026 (5f6a2a)
Menu

HTML Processing

Purpose and Scope

This document explains how StaticForge processes HTML files (.html extension) during site generation. HTML processing allows content authors to write raw HTML when they need precise control over markup, while still benefiting from frontmatter metadata, template wrapping, and the build pipeline.

For information about processing Markdown files, see Markdown Processing. For details on frontmatter syntax and metadata fields, see Content Files & Frontmatter. For URL generation logic that applies to both HTML and Markdown files, see URL Generation.

Sources: content/development/templates.md1-270 content/guide/quick-start.md203-240


HTML Renderer Feature Architecture

HTML processing in StaticForge is implemented by the HtmlRenderer feature, which operates as a specialized renderer within the event-driven architecture. Unlike the Markdown renderer which performs content transformation, the HTML renderer primarily handles metadata extraction and template application.

Core Components:

ComponentPurposeLocation
FeatureEvent registration and lifecycle managementsrc/Features/HtmlRenderer/Feature.php
HtmlRendererServiceProcessing orchestrationsrc/Features/HtmlRenderer/Services/HtmlRendererService.php
TemplateRendererTemplate applicationsrc/Services/TemplateRenderer.php
ExtensionRegistryFile type registrationInherited from core

The HTML renderer extends BaseFeature rather than BaseRendererFeature, indicating it does not require the metadata default application logic used by Markdown processing.

Sources: src/Features/HtmlRenderer/Feature.php1-76 src/Core/BaseRendererFeature.php1-41


Event Registration and Lifecycle

The HtmlRenderer feature registers with the event system during application bootstrap and listens exclusively to the RENDER event at priority 100.

HtmlRenderer Registration Flow


Registration Process:

  1. Extension Registration src/Features/HtmlRenderer/Feature.php56-57: The feature registers .html as a processable extension with ExtensionRegistry, enabling FileDiscovery to include HTML files during content scanning
  2. Service Initialization src/Features/HtmlRenderer/Feature.php40-53: The feature creates a TemplateRenderer instance with TemplateVariableBuilder and optional AssetManager dependency
  3. Event Subscription src/Features/HtmlRenderer/Feature.php29-31: The feature declares its RENDER event listener in the $eventListeners array, which BaseFeature automatically registers

Sources: src/Features/HtmlRenderer/Feature.php33-60 src/Features/MarkdownRenderer/Feature.php29-69


HTML Comment Frontmatter Extraction

HTML files use HTML comment delimiters to encapsulate YAML frontmatter, allowing metadata to coexist with valid HTML without rendering in browsers.

Frontmatter Format

HTML files place frontmatter within an HTML comment at the top of the file:


Delimiter Rules:

  • Opening delimiter: <!-- followed by newline, then ---
  • YAML content: Standard YAML key-value pairs
  • Closing delimiter: --- followed by newline, then -->
  • Content separator: Everything after --> is treated as page content

This format ensures:

  • Valid HTML that renders correctly if opened directly in a browser
  • Clean separation between metadata and content
  • Consistent parsing with Markdown frontmatter (both use YAML)

Sources: content/guide/quick-start.md207-227 content/development/templates.md1-270


HTML Processing Pipeline

When a RENDER event fires for an HTML file, the HtmlRenderer feature executes a streamlined processing pipeline.

Processing Flow Diagram


Pipeline Stages:

  1. Event Reception src/Features/HtmlRenderer/Feature.php71-74: The handleRender method receives event parameters containing file_path, metadata, and content (HTML extracted during file discovery)

  2. Service Delegation src/Features/HtmlRenderer/Feature.php73: The feature immediately delegates to HtmlRendererService.processHtmlFile() for actual processing logic

  3. Template Resolution src/Services/TemplateRenderer.php42-68: The renderer determines which Twig template to use via the resolution chain: frontmatter template field → category template → base.html.twig default

  4. Variable Building src/Services/TemplateRenderer.php87: TemplateVariableBuilder aggregates variables from metadata, container configuration, and feature data

  5. Template Rendering src/Services/TemplateRenderer.php90: Twig applies the selected template, inheriting from base.html.twig and filling blocks with content

  6. Asset Injection src/Services/TemplateRenderer.php92-95: If AssetManager is available and templates didn't include asset variables, automatically inject CSS/JS before closing tags

  7. File Writing: The final HTML is written to the calculated output_path in the public/ directory

Sources: src/Features/HtmlRenderer/Feature.php71-74 src/Services/TemplateRenderer.php32-104


Template Application

HTML files are wrapped with Twig templates following the same template resolution logic as Markdown files, enabling consistent site-wide layouts.

Template Resolution Chain

The template resolution follows a three-tier priority system:


Resolution Steps src/Services/TemplateRenderer.php42-68:

  1. Frontmatter Check: If metadata['template'] exists, use it directly (highest priority)
  2. Category Check: If metadata['category'] exists, look up category template mapping
  3. Category Template Lookup: Check if category_templates[slugified_category] exists in container
  4. Default Fallback: If no matches, use base template (ultimate fallback)
  5. Extension Append: Add .html.twig to the template name
  6. Path Construction: Prepend active template directory: {TEMPLATE}/{name}.html.twig

Example Resolution:


If category_templates['blog'] = 'blog-post' exists in container:

  • Template resolved: blog-post.html.twig
  • Full path: templates/staticforce/blog-post.html.twig

Sources: src/Services/TemplateRenderer.php42-73 content/development/templates.md178-195


Comparison: HTML vs. Markdown Processing

While both HTML and Markdown files follow the same event-driven pipeline, their processing differs significantly in content transformation stages.

Processing Differences Table

AspectHTML ProcessingMarkdown ProcessingRationale
Frontmatter Delimiters<!-- --- YAML --- -->--- YAML ---HTML requires comment syntax for valid HTML
Content TransformationNone (pass-through)Markdown → HTML conversionHTML is already in final format
Base ClassBaseFeatureBaseRendererFeatureHTML doesn't need default metadata application
Service DependenciesTemplateRenderer onlyMarkdownProcessor, ContentExtractor, TemplateRendererMarkdown requires parsing libraries
Feature NameHtmlRendererMarkdownRendererNaming reflects content type
Extension Registered.html.mdFile type identification

Shared Pipeline Elements

Both features share these common pipeline elements src/Services/TemplateRenderer.php32-104:

  • Template Resolution: Both use identical template resolution logic
  • Variable Building: Both use TemplateVariableBuilder to aggregate context
  • Asset Management: Both support AssetManager injection
  • Event Priority: Both register at RENDER event priority 100
  • Output Writing: Both write final HTML to output_path

Key Design Decision:

The HTML renderer deliberately avoids content transformation. HTML files are expected to contain valid, production-ready HTML markup. This design choice enables:

  1. Precise Control: Authors can use exact HTML/CSS when needed
  2. Component Reuse: Existing HTML components can be directly included
  3. Performance: Skipping transformation reduces processing overhead
  4. Debugging: Output matches input, simplifying troubleshooting

Sources: src/Features/HtmlRenderer/Feature.php1-76 src/Features/MarkdownRenderer/Feature.php1-85 src/Core/BaseRendererFeature.php1-41


Extension Registration and File Discovery

The HTML renderer integrates with StaticForge's extension registry to enable HTML file discovery during the content scanning phase.

Extension Registration Process


Registration Code Location:

src/Features/HtmlRenderer/Feature.php55-57 executes during feature registration:


Discovery Integration:

When FileDiscovery.discoverFiles() scans the content directory:

  1. File Enumeration: Recursively scans SOURCE_DIR for all files
  2. Extension Check: For each file, calls ExtensionRegistry.canProcess($extension)
  3. Inclusion Decision: If canProcess() returns true, file is added to discovered_files
  4. Metadata Extraction: HTML comment frontmatter is parsed and stored
  5. URL Generation: Output URL is calculated based on path and category

This registration ensures HTML files are treated as first-class content alongside Markdown files, participating fully in the build pipeline.

Sources: src/Features/HtmlRenderer/Feature.php55-57 src/Core/FileDiscovery.php1-85 (referenced in architecture diagrams)


Use Cases and Best Practices

When to Use HTML Files

HTML files are appropriate when:

  1. Complex Layouts: Content requires intricate HTML structure (tables, nested grids, custom components)
  2. Embedded Content: Integrating iframe embeds, complex forms, or interactive elements
  3. Existing HTML: Migrating existing HTML content into StaticForge
  4. Precise Control: Need exact control over HTML attributes, classes, and structure
  5. Performance: Avoiding Markdown parsing overhead for simple pages

When to Use Markdown Instead

Prefer Markdown files for:

  1. Text-Heavy Content: Articles, blog posts, documentation pages
  2. Readability: Content that will be edited frequently by non-developers
  3. Portability: Content that may be used in other systems
  4. Simplicity: Pages with straightforward formatting needs

Best Practices

Frontmatter Placement:

Always place HTML comment frontmatter at the very top of the file, before any other content:


Template Wrapping Awareness:

HTML files are wrapped in templates (typically base.html.twig), so:

  • Don't include <!DOCTYPE>, <html>, <head>, or <body> tags
  • Do include only the content for the {% block body %} section
  • Use semantic HTML elements (<article>, <section>, <aside>)

Asset References:

Always use the site_base_url variable for asset paths to ensure portability:


Validation:

Since HTML is not transformed, ensure:

  • HTML is valid and well-formed
  • All tags are properly closed
  • Accessibility attributes are present (alt, aria-label, etc.)
  • Semantic HTML5 elements are used appropriately

Sources: content/guide/quick-start.md203-240 content/development/templates.md156-176