Creating Custom Themes

Kampose themes define the layout, content structure, and visual presentation of generated documentation. This guide covers the complete process of creating custom themes from initial setup to advanced customization.

Theme Organization

Kampose organizes themes by output format within the installation's themes/ directory:

themes/
├── html/          # HTML-based themes (dotNet/docFx convention)
│   └── myTheme/
└── md/            # Markdown-based themes (devOps convention)
    └── myTheme/

Each theme resides in its own subdirectory, where the directory name serves as the theme identifier for configuration references and CLI commands.

Theme Structure

While Kampose does not enforce a rigid directory structure, the following organization provides clear separation of concerns and maintainability:

myTheme/
├── theme.json      # Theme configuration (required)
├── templates/      # Handlebars templates
├── styles/         # CSS stylesheets
├── scripts/        # JavaScript files
└── assets/         # Static resources (images, fonts, etc.)

Theme Configuration

The theme.json file contains all theme settings and must be present in the theme root directory.

Configuration Schema

The configuration file supports the following properties:

The JSON schema provides detailed validation rules for the configuration file. You can use this schema in compatible editors to ensure correctness while authoring themes.

Theme Inheritance

Themes can inherit from other themes by specifying a base theme identifier. Inheritance provides access to all templates, JavaScript files, CSS files, assets, and parameters from the parent theme, enabling customization without duplication.

This inheritance model allows you to:

Template System

Kampose uses Handlebars templates for rendering documentation pages. Templates are organized by filename only (case-insensitive), ignoring directory hierarchy, and must use the .hbs extension.

All theme templates are compiled before documentation generation begins. Syntax errors in any template will halt the process with detailed error information.

Page Templates (required)

Each documentation page type requires a corresponding template file. Templates receive page-specific data through a model variable.

Template FilePurposeModel ContentModel
topic_page.hbsConceptual documentation topicTopic information and contentTopicModel
namespace_page.hbsNamespace overview pageNamespace, including types and documentationNamespaceModel
class_page.hbsClass type documentation (type-only)Class type metadata, including members and documentationClassModel
class_members_page.hbsClass type and member documentation on single pageClass type metadata, including members and documentationClassModel
struct_page.hbsStruct type documentation (type-only)Struct type metadata, including members and documentationStructModel
struct_members_page.hbsStruct type and member documentation on single pageStruct type metadata, including members and documentationStructModel
interface_page.hbsInterface type documentation (type-only)Interface type metadata, including members and documentationInterfaceModel
interface_members_page.hbsInterface type and member documentation on single pageInterface type metadata, including members and documentationInterfaceModel
enum_page.hbsEnum type and value documentationEnum type metadata, including values and documentationEnumModel
delegate_page.hbsDelegate type documentationDelegate type metadata and documentationDelegateModel
constructor_page.hbsConstructor documentationConstructor metadata and documentationConstructorModel
constructor_overloads_page.hbsConstructor overloads documentation on single pageCollection of overloaded constructorsOverloadCollection<ConstructorModel>
field_page.hbsField documentationField metadata and documentationFieldModel
property_page.hbsProperty documentationProperty metadata and documentationPropertyModel
property_overloads_page.hbsProperty overloads documentation on single pageCollection of overloaded propertiesOverloadCollection<PropertyModel>
method_page.hbsMethod documentationMethod metadata and documentationMethodModel
method_overloads_page.hbsMethod overloads documentation on single pageCollection of overloaded methodsOverloadCollection<MethodModel>
event_page.hbsEvent documentationEvent metadata and documentationEventModel
operator_page.hbsOperator documentationOperator metadata and documentationOperatorModel
operator_overloads_page.hbsOperator overloads documentation on single pageCollection of overloaded operatorsOverloadCollection<OperatorModel>

Kampose uses the Kampute.DocToolkit library to extract reflection metadata and XML comments from .NET assemblies. To know more about each model's properties and structure, please refer to the linked API documentation.

API Template (required)

In addition to the page templates listed above, api.hbs is a special, required template that Kampose uses to generate the API page when an explicit api.md topic file is not present.

Unlike page templates, api.hbs supplies the topic body (not a full page layout) and receives the entire documentation context (assemblies, namespaces, types, and topics) instead of the page model and global template variables.

Partial Templates

Partial templates enable content reuse across multiple documentation pages. Kampose automatically registers every template file as a partial, making all templates available for inclusion.

Reference partials by filename without extension: {{> class_members_page}}. This approach promotes consistency and reduces duplication for common elements like headers, footers, navigation, and shared content blocks.

Global Template Context

All page templates have access to these global variables in addition to the page-specific model:

VariableTypeDescription
languageobjectProgramming language name and identifier
generatorstringKampose version information
absoluteUrlsbooleanWhether generated URLs are absolute
hasNamespacePagesbooleanWhether namespaces have dedicated pages
hasTypePagesbooleanWhether types have dedicated pages
hasMemberPagesbooleanWhether type members have dedicated pages
homePageTitlestringHome page title if configured
apiPageTitlestringAPI page title if configured
themeobjectTheme metadata information
scriptsarrayBundled JavaScript file URIs (alphabetical order)
stylesarrayBundled CSS file URIs (alphabetical order)

Theme parameters are available in the global template context in addition to the variables listed above, and can be referenced directly by name in templates.

At runtime the same global template values, including the variables listed above and configured theme parameters, are available to bundled scripts on the global JavaScript object kampose.config.

Debugging Templates

Use {{#json this}} to output the current template context as JSON for debugging and understanding available data structures.

Note that circular references in the object graph are automatically handled during JSON serialization. When a cycle is detected, the cyclic reference is replaced with null in the JSON output. This means some properties may appear as null even though they reference actual objects—they are simply part of a circular reference that cannot be fully serialized.

Template Enhancement Tools

Kampose provides extensive template functionality through built-in helpers and formatters:

Handlebars Helpers A comprehensive set of helpers for logic operations, string manipulation, arithmetic calculations, and utility functions. These helpers simplify common template tasks and enhance functionality. See the template helper functions documentation for complete usage details.

Built-in Formatters Specialized formatters handle common documentation tasks like rendering XML comments and generating code member links. These formatters automatically format .NET objects and documentation content. See the template formatters documentation for implementation details.

Template Overrides

When inheriting from a base theme, templates with identical names override inherited templates. This selective override capability allows precise customization of specific documentation areas while preserving other components.

Stylesheets

Configure CSS files using the styles.source setting with glob patterns to match desired CSS files.

Matched CSS files are bundled and minified into a single output file, with the path determined by styles.targetPath. File ordering within the bundle follows the sequence in the styles.source pattern.

Style Inheritance and Overrides

When inheriting from a base theme, the styles.targetPath setting determines override behavior:

Same Target Path CSS files with identical relative paths override inherited styles. Additional files extend the base theme's bundle.

Different Target Path Creates a new bundle while preserving the base theme's styles. You control whether to use only your bundle or include inherited bundles.

JavaScript

Configure JavaScript files using the scripts.source setting with glob patterns to match desired JavaScript files.

Matched JavaScript files are bundled and minified into a single output file, with the path determined by scripts.targetPath. File ordering within the bundle follows the sequence in the scripts.source pattern.

JavaScript code has access to global template variables through the kampose.config object and the complete documentation sitemap via the kampose.sitemap object.

Script Inheritance and Overrides

Similar to stylesheets, the scripts.targetPath setting controls override behavior:

Same Target Path JavaScript files with identical relative paths override inherited scripts. Additional files extend the base theme's bundle.

Different Target Path Creates a new bundle while preserving the base theme's scripts. You control whether to use only your bundle or include inherited bundles.

Static Assets

Configure static assets (images, fonts, etc.) using the assets setting with glob patterns to match desired files.

Asset files are copied to the output directory while preserving their directory structure relative to the theme folder.

Asset Overrides

When inheriting from a base theme, provide replacement files with identical relative paths to override inherited assets. File name casing is ignored during override matching.

Theme Parameters

Theme parameters enable customization of documentation behavior and appearance. Parameters are accessible in templates and JavaScript code, providing flexible configuration options.

Each parameter requires a unique name (case-insensitive) and specific type definition:

TypeDescription
booleanTrue or false values
numberInteger or floating-point numbers
stringPlain text strings
markdownMarkdown-formatted text (generates partial templates)
uriURI/URL strings
arrayArrays of values
objectKey-value pair objects

Markdown Parameter Processing

Markdown parameters receive special processing since they may contain template variables and helper functions. Kampose creates partial templates for these parameters using the naming convention {parameterName}_partial.

Example usage for a parameter named overallFooter:

{{#if overallFooter}}
{{!-- Use triple braces to prevent double escaping --}}
{{{> overallFooter_partial}}}
{{/if}}

Always reference Markdown parameters using their generated partial to ensure proper template variable expansion.

Parameter Configuration

Parameters support default values used when not explicitly configured. Parameters without default values are ignored if not set in the build configuration.

Provide descriptive text for each parameter to help users understand its purpose, expected values, and usage context.

Parameter Inheritance

When inheriting from a base theme, define parameters with identical names to override inherited parameter definitions. This allows customization of base theme behavior without modifying the original configuration.

Configuration Example

The following theme.json demonstrates a complete theme configuration:

{
    "metadata": {
        "name": "My Theme",
        "format": "html",
        "version": "0.1",
        "author": "Myself",
        "license": "MIT",
        "homepage": "https://kampute.github.io/doc-toolkit/api/Kampute.DocToolkit.my-theme",
        "description": "A custom HTML-based theme for my documentation."
    },
    "templates": [
        "templates/**/*.hbs"
    ],
    "styles": {
        "source": [
            "styles/**/*.css"
        ],
        "targetPath": "css/styles.css"
    },
    "scripts": {
        "source": [
            "scripts/**/*.js"
        ],
        "targetPath": "js/scripts.js"
    },
    "assets": [
        "assets/**"
    ],
    "parameters": {
        "disableSearch": {
            "type": "boolean",
            "defaultValue": false,
            "description": "Whether to disable the search functionality in the documentation."
        },
        "favicon": {
            "type": "uri",
            "description": "URI of the favicon."
        },
        "footer": {
            "type": "markdown",
            "defaultValue": "Copyright © {{now 'yyyy'}}",
            "description": "Footer content of the documentation."
        }
    }
}

Best Practices

Create maintainable and extensible themes by following these guidelines:

Leverage Existing Themes Build upon existing themes rather than starting from scratch. This reduces development time and ensures compatibility with established patterns.

Use Modular Templates Create partial templates for reusable components. This promotes consistency, simplifies maintenance, and enables easy customization by derived themes.

Organize Resources Logically Separate styles and scripts into logical files based on functionality. This approach facilitates selective overrides in derived themes.

Provide Clear Parameters Define parameters with meaningful default values and comprehensive descriptions. This enables straightforward theme configuration for end users.

Test Thoroughly Validate your theme across different documentation scenarios to ensure proper rendering of all content types and edge cases.

Troubleshooting

Common theme development issues and their solutions:

Template Issues

When templates are missing or not rendering correctly, check these common causes:

When content is missing from rendered pages, investigate these areas:

Stylesheet Problems

When styles are not being applied to your documentation, troubleshoot these issues:

JavaScript Issues

When scripts are not working as expected, check these potential problems:

Asset Problems

When assets are missing from the generated documentation, verify these settings: