Template Components Architecture
NCMDS uses a modular component-based template system that separates concerns and makes the codebase more maintainable. Components are organized by file type for better clarity.
📂 Component Structure
All template components are located in templates/components/, organized by type:
templates/
├── layout.html # Main layout (includes all components)
├── home.html # Hero landing page
└── components/
├── html/ # HTML template components
│ ├── head.html # Meta tags, CSS, theme variables
│ ├── header.html # Site header with toggles
│ ├── sidebar.html # Navigation sidebar
│ ├── toc.html # Table of contents
│ ├── doc_navigation.html # Prev/Next buttons
│ ├── footer.html # Site footer
│ ├── ai_chat.html # AI chat widget
│ ├── export_buttons.html # QMD export button
│ └── text_to_speech_button.html # Read aloud button
└── scripts/ # JavaScript components
└── scripts.html # JavaScript functionality
🧩 Component Details
HTML Components (components/html/)
head.html
Purpose: Document head configuration Includes: - Meta tags (charset, viewport, description, author) - Title tag - CSS links (main stylesheet, highlight.js) - Theme CSS variables (dark and light modes)
header.html
Purpose: Site header with navigation controls Includes: - Logo (SVG or image) - Site name - Theme toggle button (dark/light mode) - Sidebar toggle button (conditional) - TOC toggle button (conditional) - Mobile menu toggle
sidebar.html
Purpose: Documentation navigation Includes: - Sidebar title - Auto-generated navigation list - Empty state message - Active link highlighting
toc.html
Purpose: Table of contents for current document Includes: - TOC title - Generated TOC content (from Markdown headers) - Conditional rendering (only shows if TOC exists)
doc_navigation.html
Purpose: Previous/Next document navigation Includes: - Previous document button with title - Next document button with title - Spacers for missing prev/next - SVG icons for navigation
footer.html
Purpose: Site footer
Includes:
- Footer link groups (configurable in config.yaml)
- Author link
- Copyright information
ai_chat.html
Purpose: AI chat widget (Explain with AI)
Includes:
- Chat widget container with model selector
- Message input and send button
- Fullscreen toggle
- Streaming response display
- Configurable via ai_chat section in config.yaml
export_buttons.html
Purpose: QMD export button
Includes:
- Export to QMD button (visible in sidebar)
- Conditional rendering based on export config
- Downloads all documentation as a single QMD file
text_to_speech_button.html
Purpose: Read aloud button
Includes:
- Listen/Stop toggle button
- Uses browser's Web Speech API
- Configurable speech rate, pitch, and language
- Position configurable via text_to_speech section in config.yaml
JavaScript Components (components/scripts/)
scripts.html
Purpose: All JavaScript functionality Includes: - Syntax highlighting initialization - Mobile menu toggle - Sidebar toggle with localStorage - TOC toggle with localStorage - Theme toggle with localStorage - Smooth scroll for anchor links - Active link highlighting - Copy button functionality for code blocks
🎯 Main Layout
The main layout.html file is extremely simple and clean:
<!DOCTYPE html>
<html lang="{{ config.html.language }}">
{% include 'components/html/head.html' %}
<body>
{% include 'components/html/header.html' %}
<div class="site-container">
{% include 'components/html/sidebar.html' %}
<main class="main-content">
<div class="content-wrapper">
{% if doc_last_updated %}
<div class="doc-meta" aria-label="Document metadata">
<span class="doc-meta-label">Last updated</span>
<time class="doc-meta-value">{{ doc_last_updated }}</time>
</div>
{% endif %}
{% if doc_tags or doc_difficulty or doc_owner or doc_writer %}
<div class="doc-taxonomy" aria-label="Document metadata tags">
<!-- Difficulty, owner, writer chips and tag badges -->
</div>
{% endif %}
<article class="markdown-body">
{{ content|safe }}
</article>
{% include 'components/html/doc_navigation.html' %}
</div>
</main>
{% include 'components/html/toc.html' %}
</div>
{% include 'components/html/footer.html' %}
{% include 'components/html/export_buttons.html' %}
{% include 'components/html/text_to_speech_button.html' %}
{% include 'components/html/ai_chat.html' %}
{% include 'components/scripts/scripts.html' %}
</body>
</html>
✅ Benefits
Maintainability
- Each component has a single responsibility
- Easy to locate and modify specific functionality
- Reduced file complexity
Reusability
- Components can be included in multiple templates
- Consistent UI across different pages
- DRY (Don't Repeat Yourself) principle
Clarity
- Clear separation of concerns
- Self-documenting structure
- Easy to understand for new contributors
Testing
- Individual components can be tested in isolation
- Easier to debug issues
- Better error localization
🔧 Customization
Modifying a Component
To customize a specific part of the UI, simply edit the corresponding component file:
# Example: Customize the header
templates/components/html/header.html
Creating New Components
- Create a new
.htmlfile in the appropriatetemplates/components/subdirectory: html/for HTML template componentsscripts/for JavaScript components- Add your component code (HTML, Jinja2 templates)
- Include it in
layout.htmlwhere needed:
{% include 'components/html/your_component.html' %}
Component Dependencies
Some components depend on:
- Config variables: Passed from ncmds.py via Jinja2 context
- CSS classes: Defined in modular CSS files under static/default_theme/ (imported by static/main.css)
- JavaScript: In scripts.html for interactive components, plus static/ai_chat.js and static/search.js for dedicated features
- External CSS: static/ai_chat.css for AI chat widget styling
🎨 Styling Components
Component styles are organized in modular CSS files under static/default_theme/. Each component typically has its own CSS file:
static/
├── main.css # Entry point (imports all modules)
├── ai_chat.css # AI chat widget styles
├── style.css # Legacy stylesheet (backup)
└── default_theme/
├── base.css # Reset & typography
├── header.css # Header component styles
├── hero.css # Hero section styles
├── sidebar.css # Sidebar styles
├── toc.css # Table of contents styles
├── content.css # Main content & markdown
├── code.css # Code blocks & syntax highlighting
├── navigation.css # Navigation & footer
├── search.css # Search functionality styles
├── responsive.css # Media queries
└── utilities.css # Utility classes
Example CSS structure:
/* Header Component (in default_theme/header.css) */
.site-header { ... }
.header-container { ... }
.logo { ... }
/* Sidebar Component (in default_theme/sidebar.css) */
.sidebar { ... }
.sidebar-nav { ... }
.nav-list { ... }
📚 Related Documentation
- Configuration Guide - Configure component behavior
- Theme Creation - Customize component appearance
- Getting Started - Project structure overview