VOOZH about

URL: https://deepwiki.com/calevans/staticforge/8.1-content-renderers

⇱ Content Renderers | calevans/staticforge | DeepWiki


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

Content Renderers

Purpose and Scope

This document covers the two core content rendering features in StaticForge: MarkdownRenderer and HtmlRenderer. These features are responsible for transforming content files (.md and .html) into final HTML output during the RENDER event. This includes extracting frontmatter metadata, converting content to HTML, and applying Twig templates.

For information about template structure and variables, see Template System. For the event lifecycle and how RENDER fits into the overall pipeline, see Event System.


Renderer Architecture Overview

Both renderers extend BaseRendererFeature and implement the same fundamental pattern: listen to the RENDER event at priority 100, delegate processing to a service class, and return modified parameters with rendered HTML content.

Renderer Class Hierarchy


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


Extension Registration

Both renderers register their file extensions with ExtensionRegistry during the register() method. This signals to FileDiscovery that these file types should be included in the build.

FeatureExtensionRegistry Location
MarkdownRenderer.mdsrc/Features/MarkdownRenderer/Feature.php65-66
HtmlRenderer.htmlsrc/Features/HtmlRenderer/Feature.php56-57

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


MarkdownRenderer Feature

The MarkdownRenderer processes .md files by extracting YAML frontmatter, converting Markdown syntax to HTML, and wrapping the result in a Twig template.

Event Registration


The renderer listens to the RENDER event at priority 100, which is the standard priority for content transformation. This allows pre-render features (priority < 100) to modify metadata before rendering, and post-render features (priority > 100) to modify the HTML output after rendering.

Sources: src/Features/MarkdownRenderer/Feature.php29-31

Service Dependencies

The feature initializes four key services during registration:

ServicePurposeLocation
MarkdownProcessorConverts Markdown to HTML using CommonMarksrc/Features/MarkdownRenderer/Feature.php41
ContentExtractorExtracts YAML frontmatter from contentsrc/Features/MarkdownRenderer/Feature.php42
TemplateRendererApplies Twig templates to rendered contentsrc/Features/MarkdownRenderer/Feature.php50-54
MarkdownRendererServiceOrchestrates the rendering pipelinesrc/Features/MarkdownRenderer/Feature.php57-62

Sources: src/Features/MarkdownRenderer/Feature.php33-69

Rendering Pipeline


Sources: src/Features/MarkdownRenderer/Feature.php80-83

Frontmatter Extraction

The ContentExtractor service parses YAML frontmatter delimited by --- markers:


The extracted metadata is merged with defaults from BaseRendererFeature::applyDefaultMetadata():

Default KeyDefault ValuePurpose
template'base'Fallback template if none specified
title'Untitled Page'Fallback title if none specified

Sources: src/Core/BaseRendererFeature.php33-39


HtmlRenderer Feature

The HtmlRenderer processes .html files by extracting frontmatter from HTML comments and wrapping the content in a Twig template. Unlike Markdown files, HTML content is passed through without transformation.

Event Registration


Identical priority to MarkdownRenderer since only one renderer processes each file based on its extension.

Sources: src/Features/HtmlRenderer/Feature.php29-31

Service Dependencies

ServicePurposeLocation
TemplateRendererApplies Twig templatessrc/Features/HtmlRenderer/Feature.php47-51
HtmlRendererServiceOrchestrates HTML processingsrc/Features/HtmlRenderer/Feature.php53

Sources: src/Features/HtmlRenderer/Feature.php33-60

HTML Frontmatter Format

HTML files use HTML comment blocks for frontmatter:


The service strips the comment delimiters and parses the YAML content inside.

Sources: content/guide/quick-start.md207-227


Shared Functionality: BaseRendererFeature

Both renderers inherit from BaseRendererFeature, which provides common metadata handling.

Default Metadata Application


The applyDefaultMetadata() method ensures all rendered files have minimum required fields even if frontmatter is incomplete or missing.

Sources: src/Core/BaseRendererFeature.php33-39


Template Resolution Logic

Template selection follows a three-tier priority system implemented in TemplateRenderer::render():

Resolution Hierarchy


Sources: src/Services/TemplateRenderer.php42-71

Template Resolution Examples

ScenarioFrontmatterContainer StateResult
Explicit templatetemplate: docs-docs.html.twig
Category templatecategory: blogcategory_templates['blog'] = 'blog-post'blog-post.html.twig
No template--base.html.twig
Category without templatecategory: tutorialsNo mapping for 'tutorials'base.html.twig

Sources: src/Services/TemplateRenderer.php46-67

Category Slugification

Category names are normalized for template lookup using slugifyCategory():


This matches the filename format used by the Categories feature when storing category templates.

Sources: src/Services/TemplateRenderer.php273-277


Asset Management Integration

Both renderers integrate with AssetManager through TemplateRenderer. If AssetManager is available in the container, the renderer automatically injects registered CSS and JavaScript assets.

Asset Injection Strategy


This fallback mechanism ensures assets are included even if template authors forget to add {{ styles|raw }} and {{ scripts|raw }} placeholders.

Sources: src/Services/TemplateRenderer.php218-268


RENDER Event Data Flow

Input Parameters

The RENDER event receives parameters from the file processing loop:

Parameter KeyTypeDescription
file_pathstringAbsolute path to source file
output_pathstringAbsolute path to output file
urlstringPublic URL for the page
metadataarrayParsed frontmatter

Sources: content/development/events.md44-47

Output Parameters

Renderers modify the parameters and return them to the event chain:

Parameter KeyTypeDescriptionAdded By
contentstringRendered HTML contentBoth renderers
renderedboolFlag indicating file was processedBoth renderers
skip_fileboolOptional flag to skip further processingCategoryIndex

Sources: src/Features/CategoryIndex/Feature.php86-106


File Processing Conditions

Skip Conditions

Renderers only process files when specific conditions are met:


Sources: src/Features/CategoryIndex/Feature.php86-106

Extension Registry Check

The ExtensionRegistry maintains a list of processable extensions. During file discovery, only files with registered extensions are included in the build.

Sources: src/Features/MarkdownRenderer/Feature.php64-66 src/Features/HtmlRenderer/Feature.php55-57


Template Variable Context

Variable Building Process

TemplateRenderer uses TemplateVariableBuilder to construct the context passed to Twig templates:


Sources: src/Services/TemplateRenderer.php86-90

Variable Precedence

When key collisions occur, later sources override earlier ones:

  1. Core variables (lowest priority)
  2. Frontmatter metadata
  3. Container variables
  4. Feature data
  5. Asset variables (highest priority)

Sources: content/development/templates.md74-92


Error Handling

Template Rendering Failures

If template rendering fails, TemplateRenderer falls back to a basic HTML template:


The fallback template is a minimal HTML5 document with placeholders for site name, page title, content, and metadata.

Sources: src/Services/TemplateRenderer.php98-104 src/Services/TemplateRenderer.php155-182


Configuration

Environment Variables

VariableRequiredDefaultUsed By
TEMPLATE_DIRYestemplatesTemplate path resolution
TEMPLATEYessampleActive template directory
SITE_BASE_URLYes-Asset URLs, absolute links

Sources: content/guide/configuration.md130-169

Container Variables

Renderers access these variables from the dependency injection container:

VariableTypePurpose
category_templatesarrayMaps category slugs to template names
site_configarrayParsed siteconfig.yaml data
discovered_filesarrayAll files in the build

Sources: src/Services/TemplateRenderer.php51-60


Usage in Custom Features

Extending Renderers

Custom features can interact with renderers through events:


Sources: content/development/events.md84-108

Renderer Priority Considerations

EventStandard PriorityPurposeRun Before/After
PRE_RENDER50-99Modify metadataBefore renderers (100)
RENDER100Transform contentBoth renderers use 100
POST_RENDER101-250Modify HTML outputAfter renderers (100)

Sources: content/development/events.md113-126


Comparison: Markdown vs HTML Rendering

AspectMarkdownRendererHtmlRenderer
File Extension.md.html
Frontmatter Format--- YAML ---<!-- --- YAML --- -->
Content ProcessingMarkdown → HTML via CommonMarkRaw HTML passthrough
Services RequiredMarkdownProcessor, ContentExtractor, TemplateRendererTemplateRenderer only
Template ApplicationYesYes
Default Templatebasebase
Asset InjectionYesYes

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


Performance Characteristics

Single-Pass Rendering

Both renderers operate on a single-pass principle:

  1. File read: Once during discovery
  2. Metadata extraction: Once during rendering
  3. Content transformation: Once during rendering
  4. Template application: Once during rendering

This design avoids redundant file I/O and parsing operations.

Sources: content/development/architecture.md19-26

Caching Strategy

StaticForge does not cache intermediate rendering results. Each build performs full rendering because:

  1. Static sites rebuild infrequently
  2. Full rebuilds ensure consistency
  3. No cache invalidation complexity
  4. Fast rebuilds (<1 second for typical sites)

Sources: src/Services/TemplateRenderer.php79-84

Refresh this wiki

On this page