Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

Template Injection

Loading…

Template Injection

Relevant source files

Purpose and Scope

Template Injection is the process of inserting processed HTML header and footer content into each markdown file during Phase 3 of the build pipeline. This occurs after SUMMARY.md Generation and before the final mdBook build. The system reads HTML template files, performs variable substitution and conditional rendering, and prepends/appends the resulting HTML to every markdown file in the book structure.

For information about the template system architecture and customization options, see Template System and Template System Details. For the complete Phase 3 pipeline, see Phase 3: mdBook Build.


Template Processing Architecture

The template injection system consists of two stages: template processing (variable substitution and conditional evaluation) and content injection (inserting processed HTML into markdown files).

graph TB
    subgraph "Input Sources"
        HeaderTemplate["header.html\n/workspace/templates/"]
FooterTemplate["footer.html\n/workspace/templates/"]
EnvVars["Environment Variables\nREPO, BOOK_TITLE,\nGIT_REPO_URL, etc."]
end
    
    subgraph "Template Processing"
        ProcessScript["process-template.py"]
ParseVars["Parse Variables\nVAR=value args"]
ReadTemplate["Read Template File"]
ProcessConditionals["Process Conditionals\n{{#if VAR}}...{{/if}}"]
SubstituteVars["Substitute Variables\n{{VAR}}"]
StripComments["Strip HTML Comments"]
end
    
    subgraph "Processed Output"
        HeaderHTML["HEADER_HTML\nShell Variable"]
FooterHTML["FOOTER_HTML\nShell Variable"]
end
    
 
   HeaderTemplate --> ProcessScript
 
   FooterTemplate --> ProcessScript
 
   EnvVars --> ParseVars
 
   ParseVars --> ProcessScript
 
   ProcessScript --> ReadTemplate
 
   ReadTemplate --> ProcessConditionals
 
   ProcessConditionals --> SubstituteVars
 
   SubstituteVars --> StripComments
 
   StripComments --> HeaderHTML
 
   StripComments --> FooterHTML

Template Processing Flow

Sources: scripts/build-docs.sh:195-234 python/process-template.py:11-50


Template File Discovery

The system locates template files using configurable paths with sensible defaults. Template discovery follows a priority order that allows for custom template overrides.

Configuration VariableDefault ValuePurpose
TEMPLATE_DIR/workspace/templatesBase directory for template files
HEADER_TEMPLATE$TEMPLATE_DIR/header.htmlPath to header template
FOOTER_TEMPLATE$TEMPLATE_DIR/footer.htmlPath to footer template

If a template file is not found, the system emits a warning and continues without that template component, allowing for header-only or footer-only configurations.

Sources: scripts/build-docs.sh:195-197


Variable Substitution Mechanism

The process_template function in process-template.py performs two types of text replacement: conditional blocks and simple variable substitution.

Simple Variable Substitution

Variables use the {{VARIABLE_NAME}} syntax and are replaced with their corresponding values passed as command-line arguments.

graph LR
    Template["Template: {{REPO}}"]
Variables["Variables:\nREPO=owner/repo"]
ProcessTemplate["process_template()\npython/process-template.py:11-50"]
Result["Result: owner/repo"]
Template --> ProcessTemplate
 
   Variables --> ProcessTemplate
 
   ProcessTemplate --> Result

The substitution pattern r'\{\{(\w+)\}\}' matches variable placeholders, and the replace_variable function looks up values in the variables dictionary. If a variable is not found, an empty string is substituted.

Sources: python/process-template.py:38-45

Conditional Rendering

Conditional blocks use {{#if VARIABLE}}...{{/if}} syntax to conditionally include content based on variable presence and non-empty values.

graph TB
    ConditionalPattern["Pattern:\n{{#if VAR}}...{{/if}}"]
CheckVar{"Variable exists\nAND non-empty?"}
IncludeContent["Include Content"]
RemoveBlock["Remove Entire Block"]
ConditionalPattern --> CheckVar
 
   CheckVar -->|Yes| IncludeContent
 
   CheckVar -->|No| RemoveBlock

The regex pattern r'\{\{#if\s+(\w+)\}\}(.*?)\{\{/if\}\}' captures both the variable name and the content block. The replace_conditional function evaluates the condition using if var_name in variables and variables[var_name].

Sources: python/process-template.py:24-36


Available Template Variables

The following variables are passed to template processing and can be used in both header and footer templates:

VariableSourceExample Value
DEEPWIKI_URLConstructed from REPOhttps://deepwiki.com/owner/repo
DEEPWIKI_BADGE_URLStatic URLhttps://deepwiki.com/badge.svg
GIT_REPO_URLEnvironment or derivedhttps://github.com/owner/repo
GITHUB_BADGE_URLConstructed from REPOhttps://img.shields.io/badge/...
REPOEnvironment or Git detectionowner/repo
BOOK_TITLEEnvironment or defaultDocumentation
BOOK_AUTHORSEnvironment or REPO_OWNERowner
GENERATION_DATEdate -u commandJanuary 15, 2024 at 14:30 UTC

Sources: scripts/build-docs.sh:199-213 scripts/build-docs.sh:221-230


Template Processing Invocation

The shell script invokes process-template.py twice: once for the header and once for the footer. Each invocation passes all variables as command-line arguments in KEY=value format.

Header Processing

The processed HTML is captured in the HEADER_HTML shell variable for later injection.

Sources: scripts/build-docs.sh:202-213

Footer processing follows the same pattern but stores the result in FOOTER_HTML.

Sources: scripts/build-docs.sh:219-230


graph TB
    Start["Start Injection"]
CheckTemplates{"HEADER_HTML or\nFOOTER_HTML set?"}
SkipInjection["Skip injection\nCopy files as-is"]
FindFiles["Find all .md files\nsrc/*.md src/*/*.md"]
ProcessFile["For each file"]
ReadOriginal["Read original content"]
CreateTemp["Create temp file:\nheader + content + footer"]
ReplaceOriginal["mv temp to original"]
CountFiles["Increment file_count"]
ReportCount["Report processed count"]
Start --> CheckTemplates
 
   CheckTemplates -->|No| SkipInjection
 
   CheckTemplates -->|Yes| FindFiles
 
   FindFiles --> ProcessFile
 
   ProcessFile --> ReadOriginal
 
   ReadOriginal --> CreateTemp
 
   CreateTemp --> ReplaceOriginal
 
   ReplaceOriginal --> CountFiles
 
   CountFiles --> ProcessFile
 
   ProcessFile --> ReportCount

Markdown File Injection

After templates are processed, the system injects the resulting HTML into all markdown files in the book structure. Injection occurs by creating a temporary file with concatenated content and then replacing the original.

Injection Algorithm

Sources: scripts/build-docs.sh:236-261

File Processing Pattern

The injection loop processes files matching the glob patterns src/*.md and src/*/*.md, covering both root-level pages and subsection pages.

The temporary file approach ensures atomic writes and prevents partial content if processing is interrupted.

Sources: scripts/build-docs.sh:243-257


graph LR
    CopyFiles["Copy markdown files\nto src/"]
ProcessHeader["Process header.html\n→ HEADER_HTML"]
ProcessFooter["Process footer.html\n→ FOOTER_HTML"]
InjectLoop["Inject into each\n.md file"]
InstallMermaid["Install mdbook-mermaid"]
BuildBook["mdbook build"]
CopyFiles --> ProcessHeader
 
   ProcessHeader --> ProcessFooter
 
   ProcessFooter --> InjectLoop
 
   InjectLoop --> InstallMermaid
 
   InstallMermaid --> BuildBook

Template Injection Sequence

Template injection occurs at a specific point in the Phase 3 pipeline, after markdown files are copied but before the mdBook build.

This ordering ensures that:

  1. SUMMARY.md is generated with original titles before injection
  2. All markdown files exist in their final locations
  3. Templates are processed once and reused for all files
  4. mdBook receives fully-decorated markdown files

Sources: scripts/build-docs.sh:190-271


Example Template Structure

The default header template demonstrates the use of variables and conditionals:

Key observations:

  • Conditional wrapping prevents broken links when GIT_REPO_URL is unset
  • Inline conditionals prevent mdBook from wrapping content in <p> tags
  • Style attributes provide layout control within markdown constraints

Sources: templates/header.html:1-8


Skipping Template Injection

Template injection can be effectively disabled by:

  1. Not providing template files at the expected paths
  2. Setting HEADER_TEMPLATE or FOOTER_TEMPLATE to non-existent paths
  3. Mounting empty template files via volume mounts

When templates are not found, the system emits warnings but continues:

Warning: Header template not found at /workspace/templates/header.html, skipping...
Warning: Footer template not found at /workspace/templates/footer.html, skipping...

Files are then copied without modification using the fallback path.

Sources: scripts/build-docs.sh:214-217 scripts/build-docs.sh:232-234


Template Processing Error Handling

The process-template.py script performs validation at startup:

Error conditions result in non-zero exit codes, which would cause the shell script to abort due to set -e on line 2.

Sources: python/process-template.py:53-78 scripts/build-docs.sh2


Performance Characteristics

Template processing and injection have the following performance characteristics:

OperationComplexityTypical Duration
Template file readO(1)< 1ms per file
Variable substitutionO(n × m) where n=template size, m=variables< 5ms per template
Conditional evaluationO(n × c) where c=conditional count< 5ms per template
Per-file injectionO(f) where f=file size< 10ms per file
Total injection timeO(files × file_size)~100-500ms for typical wikis

The system reports processing time via the file count message: "Processed N files with templates".

Sources: scripts/build-docs.sh258


Integration with mdBook

The injected HTML content becomes part of the markdown source that mdBook processes. mdBook’s HTML renderer:

  1. Preserves raw HTML blocks in markdown
  2. Applies syntax highlighting to code blocks
  3. Processes Mermaid diagrams via mdbook-mermaid preprocessor
  4. Wraps content in the theme’s page structure

This allows the templates to provide page-level customization that appears consistently across all pages while leveraging mdBook’s built-in features for navigation, search, and responsive layout.

Sources: scripts/build-docs.sh:264-271

Dismiss

Refresh this wiki

Enter email to refresh