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
| Condition | Variable Value | Result |
|---|---|---|
| Variable not in dictionary | N/A | Content excluded |
| Variable is empty string | "" | Content excluded |
Variable is None | None | Content excluded |
Variable is False | False | Content excluded |
| Variable has non-empty value | Any truthy value | Content 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:
- Project Badges Section (lines 2-4): Conditionally displays GitHub badge using flexbox layout with gap spacing and bottom border
- Initiative Description (line 7): Displays “Projects with Books” initiative text from zenOSmosis
- 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.
Footer Template Structure
The default footer at templates/footer.html:1-11 provides:
- Visual Separator (line 1): Horizontal rule with custom styling
- Generation Timestamp (line 4): Always displayed using
GENERATION_DATEvariable - Repository Link (lines 5-9): Conditionally displays repository link using
GIT_REPO_URLandREPOvariables
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.
| Variable | Source | Example Value | Description |
|---|---|---|---|
REPO | REPO env var or Git remote | jzombie/deepwiki-to-mdbook | Repository in owner/repo format |
BOOK_TITLE | BOOK_TITLE env var or default | My Project Documentation | Title displayed in book |
BOOK_AUTHORS | BOOK_AUTHORS env var or default | Project Contributors | Author attribution |
GENERATION_DATE | date -u command | 2024-01-15 14:30:00 UTC | UTC timestamp when docs generated |
DEEPWIKI_URL | Hardcoded | https://deepwiki.com/... | Source wiki URL |
DEEPWIKI_BADGE_URL | Constructed from DEEPWIKI_URL | https://deepwiki.com/.../badge.svg | DeepWiki badge image |
GIT_REPO_URL | Constructed from REPO | https://github.com/owner/repo | Full GitHub repository URL |
GITHUB_BADGE_URL | Constructed from REPO | https://img.shields.io/badge/... | GitHub badge image |
Variable Construction Logic:
GIT_REPO_URL: Only set ifREPOis non-empty. Format:https://github.com/${REPO}GITHUB_BADGE_URL: Only set ifREPOis non-empty. Constructed using shields.io badge serviceDEEPWIKI_BADGE_URL: Derived fromDEEPWIKI_URLby 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 Variable | Default Value | Purpose |
|---|---|---|
TEMPLATE_DIR | /workspace/templates | Base directory for template files |
HEADER_TEMPLATE | $TEMPLATE_DIR/header.html | Path to header template |
FOOTER_TEMPLATE | $TEMPLATE_DIR/footer.html | Path 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:
- All content modifications (diagrams) are complete before templates are added
- Templates appear in every markdown file processed by mdBook
- The same header/footer styling applies consistently across all pages
File Processing Order:
build-docs.shprocesses header and footer templates once at the start of Phase 2- The processed templates are stored in temporary variables
- For each
.mdfile in themarkdown/directory:- Read original file content
- Concatenate:
processed_header + content + processed_footer - Write back to the same file
- 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:
| Condition | Detection | Response |
|---|---|---|
| Missing template file | os.path.isfile() check at line 62 | Print error to stderr, exit code 1 |
| Insufficient arguments | len(sys.argv) < 2 check at line 54 | Print usage message, exit code 1 |
| Missing variable | Dictionary lookup at line 43 | Return empty string (silent) |
| Invalid conditional | Regex fails to match | No replacement (silent) |
| File read error | Exception during file open | Unhandled 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