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 System Details

Loading…

Template System Details

Relevant source files

Purpose and Scope

This document provides comprehensive technical documentation of the template system used to customize headers and footers in generated markdown files. The template system supports variable substitution, conditional rendering, and custom template injection through volume mounts.

For information about specific template variables and their usage, see Template Variables. For guidance on providing custom templates, see Custom Templates. For the broader Phase 2 enhancement pipeline where templates are injected, see Phase 2: Diagram Enhancement.

Template Processing Architecture

The template system consists of two core components: the template processor script and the default template files. The processor applies variable substitution and conditional logic, while default templates provide the baseline content structure.

Template System Component Architecture

graph TB
    subgraph "Template Processor"
        ProcessScript["process-template.py"]
ProcessFunc["process_template()"]
ReplaceConditional["replace_conditional()"]
ReplaceVariable["replace_variable()"]
end
    
    subgraph "Default Templates"
        HeaderTemplate["templates/header.html"]
FooterTemplate["templates/footer.html"]
TemplateReadme["templates/README.md"]
end
    
    subgraph "Runtime Configuration"
        EnvVars["Environment Variables\nTEMPLATE_DIR\nHEADER_TEMPLATE\nFOOTER_TEMPLATE"]
VariablesDict["variables dict\nREPO, BOOK_TITLE\nGENERATION_DATE, etc."]
end
    
    subgraph "Processing Steps"
        ReadTemplate["Read template file"]
ParseVars["Parse CLI arguments\nVAR=value format"]
ProcessCond["Process conditionals\n{{#if}}...{{/if}}"]
ProcessVars["Process variables\n{{VARIABLE}}"]
RemoveComments["Remove HTML comments"]
end
    
 
   EnvVars --> ProcessScript
 
   HeaderTemplate --> ReadTemplate
 
   FooterTemplate --> ReadTemplate
 
   ReadTemplate --> ProcessFunc
 
   ParseVars --> VariablesDict
 
   VariablesDict --> ProcessFunc
    
 
   ProcessFunc --> ProcessCond
 
   ProcessCond --> ReplaceConditional
 
   ReplaceConditional --> ProcessVars
 
   ProcessVars --> ReplaceVariable
 
   ReplaceVariable --> RemoveComments
 
   RemoveComments --> Output["Processed HTML output"]

Sources: python/process-template.py:1-83 templates/header.html:1-9 templates/footer.html:1-11

Template Syntax

The template system supports three syntax constructs: variable substitution, conditional rendering, and HTML comments. All processing occurs through regular expression pattern matching in process_template().

Variable Substitution

Variables use double curly brace syntax: {{VARIABLE_NAME}}. The processor replaces these with values from the variables dictionary.

Variable Processing Flow

graph LR
    Input["Template: {{BOOK_TITLE}}"]
Pattern["variable_pattern\nr'\\{\\{(\\w+)\\}\\}'"]
Match["re.sub()
match"]
Lookup["variables.get('BOOK_TITLE', '')"]
Output["Processed: My Documentation"]
Input --> Pattern
 
   Pattern --> Match
 
   Match --> Lookup
 
   Lookup --> Output

The replace_variable() function at python/process-template.py:41-43 implements variable lookup. If a variable is not found in the dictionary, it returns an empty string rather than raising an error.

Sources: python/process-template.py:38-45 templates/README.md:12-15

Conditional Rendering

Conditionals control whether content blocks are included in the output based on variable presence and non-empty values. The syntax is {{#if VARIABLE}}...{{/if}}.

Conditional Evaluation Logic

ConditionVariable ValueResult
Variable not in dictionaryN/AContent excluded
Variable is empty string""Content excluded
Variable is NoneNoneContent excluded
Variable is FalseFalseContent excluded
Variable has non-empty valueAny truthy valueContent included

The conditional pattern at python/process-template.py26 uses re.DOTALL flag to match content across multiple lines. The replace_conditional() function evaluates the condition at python/process-template.py:32-34

Example from Default Header:

This conditional at templates/header.html3 ensures the GitHub badge only appears when GIT_REPO_URL is configured.

Sources: python/process-template.py:24-36 templates/README.md:17-22 templates/header.html3

HTML Comment Removal

HTML comments are automatically stripped from the processed output using the pattern <!--.*?--> with the re.DOTALL flag at python/process-template.py48 This allows template authors to include documentation within template files without affecting the output.

Sources: python/process-template.py:47-48 templates/README.md:24-28

Default Template Structure

The system provides two default templates located in the templates/ directory. These templates are embedded in the Docker image and used unless overridden by volume mounts.

Template File Locations and Purpose

graph TB
    subgraph "Docker Image: /workspace/templates/"
        HeaderFile["header.html\nProject badges\nInitiative description\nGitHub links"]
FooterFile["footer.html\nGeneration timestamp\nRepository link"]
ReadmeFile["README.md\nDocumentation\nNot processed"]
end
    
    subgraph "Environment Variables"
        TemplateDir["TEMPLATE_DIR\ndefault: /workspace/templates"]
HeaderPath["HEADER_TEMPLATE\ndefault: $TEMPLATE_DIR/header.html"]
FooterPath["FOOTER_TEMPLATE\ndefault: $TEMPLATE_DIR/footer.html"]
end
    
    subgraph "Runtime Resolution"
        BuildScript["build-docs.sh"]
CheckExists["Check file existence"]
UseDefault["Use default templates"]
UseCustom["Use custom templates\n(if mounted)"]
end
    
 
   TemplateDir --> HeaderPath
 
   TemplateDir --> FooterPath
 
   HeaderPath --> BuildScript
 
   FooterPath --> BuildScript
 
   BuildScript --> CheckExists
 
   CheckExists --> UseDefault
 
   CheckExists --> UseCustom
 
   UseDefault --> HeaderFile
 
   UseDefault --> FooterFile

Sources: templates/header.html:1-9 templates/footer.html:1-11 templates/README.md:1-77

Header Template Structure

The default header at templates/header.html:1-9 contains three main sections:

  1. Project Badges Section (lines 2-4): Conditionally displays GitHub badge using flexbox layout with gap spacing and bottom border
  2. Initiative Description (line 7): Displays “Projects with Books” initiative text from zenOSmosis
  3. Conditional GitHub Link (line 7): Second conditional that provides GitHub source link

The inline conditional comment at templates/header.html1 explains why conditionals must be inline: to prevent mdBook from wrapping links in separate paragraph tags.

The default footer at templates/footer.html:1-11 provides:

  1. Visual Separator (line 1): Horizontal rule with custom styling
  2. Generation Timestamp (line 4): Always displayed using GENERATION_DATE variable
  3. Repository Link (lines 5-9): Conditionally displays repository link using GIT_REPO_URL and REPO variables

Sources: templates/header.html:1-9 templates/footer.html:1-11

sequenceDiagram
    participant BS as build-docs.sh
    participant PT as process-template.py
    participant FS as Filesystem
    participant MD as Markdown Files
    
    Note over BS: Phase 2: Enhancement
    
    BS->>BS: Set template variables\nREPO, BOOK_TITLE, etc.
    BS->>FS: Check HEADER_TEMPLATE exists
    BS->>FS: Check FOOTER_TEMPLATE exists
    
    BS->>PT: process-template.py header.html\nVAR1=val1 VAR2=val2...
    PT->>FS: Read header.html
    PT->>PT: Apply conditionals
    PT->>PT: Substitute variables
    PT->>PT: Remove comments
    PT-->>BS: Return processed header
    
    BS->>PT: process-template.py footer.html\nVAR1=val1 VAR2=val2...
    PT->>FS: Read footer.html
    PT->>PT: Apply conditionals
    PT->>PT: Substitute variables
    PT->>PT: Remove comments
    PT-->>BS: Return processed footer
    
    BS->>MD: For each .md file in markdown/
    loop Each File
        BS->>FS: Read original content
        BS->>FS: Write: header + content + footer
    end
    
    Note over BS,MD: Templates now injected\nReady for mdBook build

Template Processing Pipeline

Templates are processed and injected during Phase 2 of the build pipeline, after markdown extraction but before mdBook build. The build-docs.sh script orchestrates this process.

Template Injection Workflow

Sources: python/process-template.py:53-82

Available Template Variables

The following variables are available in all templates. These are set by build-docs.sh before template processing and passed as command-line arguments to process-template.py.

VariableSourceExample ValueDescription
REPOREPO env var or Git remotejzombie/deepwiki-to-mdbookRepository in owner/repo format
BOOK_TITLEBOOK_TITLE env var or defaultMy Project DocumentationTitle displayed in book
BOOK_AUTHORSBOOK_AUTHORS env var or defaultProject ContributorsAuthor attribution
GENERATION_DATEdate -u command2024-01-15 14:30:00 UTCUTC timestamp when docs generated
DEEPWIKI_URLHardcodedhttps://deepwiki.com/...Source wiki URL
DEEPWIKI_BADGE_URLConstructed from DEEPWIKI_URLhttps://deepwiki.com/.../badge.svgDeepWiki badge image
GIT_REPO_URLConstructed from REPOhttps://github.com/owner/repoFull GitHub repository URL
GITHUB_BADGE_URLConstructed from REPOhttps://img.shields.io/badge/...GitHub badge image

Variable Construction Logic:

  • GIT_REPO_URL: Only set if REPO is non-empty. Format: https://github.com/${REPO}
  • GITHUB_BADGE_URL: Only set if REPO is non-empty. Constructed using shields.io badge service
  • DEEPWIKI_BADGE_URL: Derived from DEEPWIKI_URL by appending /badge.svg

Sources: templates/README.md:30-40

Customization Mechanisms

The template system supports customization through three mechanisms: environment variables, volume mounts, and complete template directory replacement.

Environment Variable Configuration

Environment 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

These variables allow changing template paths without modifying the Docker image.

Sources: templates/README.md:53-56

Volume Mount Strategies

Strategy 1: Replace Individual Templates

This overrides only the header template, keeping the default footer.

Strategy 2: Replace Entire Template Directory

This replaces all default templates. The custom directory must contain both header.html and footer.html.

Strategy 3: Custom Template Location

This uses environment variables to point to templates in a different location.

Sources: templates/README.md:44-51

graph TB
    subgraph "Phase 1: Extraction"
        Scraper["deepwiki-scraper.py\nGenerate raw markdown"]
RawMD["raw_markdown/\ndirectory"]
end
    
    subgraph "Phase 2: Enhancement"
        DiagramInject["Diagram injection\ninto markdown"]
TemplateProcess["Template processing\nprocess-template.py"]
TemplateInject["Template injection\nPrepend header\nAppend footer"]
EnhancedMD["markdown/\ndirectory"]
end
    
    subgraph "Phase 3: Build"
        SummaryGen["SUMMARY.md generation"]
MDBookBuild["mdbook build"]
HTMLOutput["book/\ndirectory"]
end
    
 
   Scraper --> RawMD
 
   RawMD --> DiagramInject
 
   DiagramInject --> TemplateProcess
 
   TemplateProcess --> TemplateInject
 
   TemplateInject --> EnhancedMD
 
   EnhancedMD --> SummaryGen
 
   SummaryGen --> MDBookBuild
 
   MDBookBuild --> HTMLOutput

Integration with Build Process

The template system integrates into the three-phase build pipeline at a specific injection point during Phase 2.

Build Phase Integration Points

The template injection occurs after diagram enhancement but before SUMMARY.md generation. This ensures:

  1. All content modifications (diagrams) are complete before templates are added
  2. Templates appear in every markdown file processed by mdBook
  3. The same header/footer styling applies consistently across all pages

File Processing Order:

  1. build-docs.sh processes header and footer templates once at the start of Phase 2
  2. The processed templates are stored in temporary variables
  3. For each .md file in the markdown/ directory:
    • Read original file content
    • Concatenate: processed_header + content + processed_footer
    • Write back to the same file
  4. Continue to Phase 3 with enhanced files

Sources: python/process-template.py:1-83

Template Processing Error Handling

The process-template.py script implements basic error handling for common failure scenarios:

Error Conditions and Responses:

ConditionDetectionResponse
Missing template fileos.path.isfile() check at line 62Print error to stderr, exit code 1
Insufficient argumentslen(sys.argv) < 2 check at line 54Print usage message, exit code 1
Missing variableDictionary lookup at line 43Return empty string (silent)
Invalid conditionalRegex fails to matchNo replacement (silent)
File read errorException during file openUnhandled exception propagates

The error handling philosophy is “fail early for missing inputs, fail silently for missing variables.” This allows templates to gracefully degrade when optional variables (like GIT_REPO_URL) are not provided, while catching configuration errors before processing begins.

Sources: python/process-template.py:54-63

Dismiss

Refresh this wiki

Enter email to refresh