docmodel show menu hide menu

Create Your Own Theme

docmodel themes are a relatively simple affair. To create a custom theme, you must add a theme directory to your project. To get you started, docmodel can create this directory for you and copy the default theme components into it. From your project directory, run:

docmodel --local

To activate the local theme, you must updated your project's configuration file to set the theme name to local:

"theme" : {
  "name": "local" 
}

Theme Files

A minimal theme directory is made up of the following items:

Item Type Required Description
theme.json file yes The theme's manifest file
page.html file yes Template file for documents.
assets directory no A directory containing your theme assets (css, js, images, etc). Merged into a project's assets directory when baking.
index.html file no Template file for a site index. If this item is not provided in a theme, index pages will not be supported.

theme.json

The theme.json file is your theme's manifest. It should contain the following content:

{
  "name"          : "default",
  "strings"       : {},
  "default_lang"  : "en", 
  "client_options": {}
}

It's worth noting that the $include directive can also be used in theme.json, however, includes will be resolved relative to your theme directory:

{
  "name"          : "default",
  "strings"       : {
    "$include": "a-json-file-in-your-theme-directory"
  },
  "default_lang"  : "en", 
  "client_options": {}
}

The client_options object will be rendered into a <script> block in each baked HTML page (assuming your theme requests it, see the section on Components, below). This object will be available to your client-side JavaScript at window.docmodel.options:

<script>var docmodel = {options: {/*the client_options object*/}}</script>

For further information on strings and default_lang, see the section on Strings, below.

page.html

A HTML file that will be used as the template for baked documents. You can use placeholder values within this file for docmodel components (document content, navigation links etc) and language-specific strings. See the relevant sections, below.

index.html

A HTML file that will be used as the template for a baked index page. You can use placeholder values within this file for some docmodel components (a more limited set than is available to document templates), but you can not use placeholders for language specific strings. A site will only ever have 1 index page--translations and versions are not available for this page.

Components

Placeholders for docmodel components take the form of a string identifier surrounded by double braces ({{) on either side.

{{A_COMPONENT_NAME}}

Available component placeholders are shown in the table below. While all of these components are available to page.html, only some are available to index.html.

Placeholder page.html index.html HTML Type Description
DOCUMENT yes yes Mixed Parsed document content
OUTDATED_WARNING yes no <div> Warning for outdated document versions
SITE_NAVIGATION yes yes <ul> Rendered site navigation links
NAVIGATION yes no <ul> Rendered documentation navigation links for current version / language
VERSIONS yes no <select> Rendered list of all available documentation versions (for the current language) where each option value is a link to the version's landing page.
LANGUAGES yes no <select> Rendered list of all available documentation languages (for the current version) where each option value is a link to the language's landing page.
RELATED_VERSIONS yes no <select> Like VERSIONS, but only for versions of the current document
RELATED_LANGUAGES yes no <select> Like LANGAUGES but only for translations of the current document
PREVIOUS_DOCUMENT yes no <a> A link to the previous document in the current version/language group
NEXT_DOCUMENT yes no <a> A link to the next document in the current version/language group
CLIENT_OPTIONS yes yes <script> Rendered theme.client_options object from configuration file (see above).

All of these replacements are optional. If you do not include one, its corresponding component will not be added to your baked documents. Please note that the replacements are "dumb"--they are not, as example, escaped within code blocks. {{DOCUMENT}} is always the last replacement to be made. Replacements are global--components can be added to a page multiple times.

Strings

You can support multiple languages in your themes by using theme string. The theme.json strings object should contain an ISO 639-1 language code key for each language you wish to support (i.e. each language your are providing document translations in):

{
  "name"          : "default",
  "strings"       : {
    "en" : {
      "a_placeholder": "its value"
    }, 
    "nl": {
      "a_placeholder": "its value in dutch"
    }
  },
  "default_lang"  : "en", 
  "client_options": {}
}

You can then reference these strings in your template files by surrounding the string name with double braces ({{) on each side, and prepending an at (@) symbol to the string name:

{{@a_placeholder}}

Now, when your documents are baked, the string placeholders will be replaced with the string for the relevant language. If a string value does not exist for a given language, the string value from your theme's default_lang will be used instead. String replacements in an index file will always be taken from your default language.

Example (Default Theme)

theme.json contents:

{
  "name"          : "default",
  "strings"       : {
    "en"          : {
      "site_title"       : "Documentation",
      "meta_title"       : "Documentation",
      "footer"           : "<a href='https://docmodel.com/'>generated by docmodel</a>",
      "code_theme"       : "agate", 
      "outdated_warning" : "This document is for an older version. The latest version is:", 
      "previous_document": "&laquo; Previous",
      "next_document"    : "Next &raquo;"   
    }
  },
  "default_lang"  : "en", 
  "base_href"     : null, 
  "client_options": {
    "sidebar_toc" : true
  }
}

page.html contents:

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta http-equiv='cache-control' content='no-cache'>
  <title>{{@meta_title}}</title>
  <link rel='stylesheet' href='/assets/styles.css'>
  <link rel='stylesheet' href='https://cdn.jsdelivr.net/highlight.js/9.9.0/styles/{{@code_theme}}.min.css'>
  <link href='https://fonts.googleapis.com/css?family=Roboto|Fjalla+One|Share+Tech+Mono' rel='stylesheet'>
</head>
<body>

  <header>
    <a href='/'>{{@site_title}}</a>
    <nav>{{SITE_NAVIGATION}}</nav>
  </header>

  <nav id='primary-nav'>
    {{NAVIGATION}}
    <div class='versions'>
      {{VERSIONS}}{{LANGUAGES}}
    </div>
  </nav>

<main>
  <div class='versions'>
    {{RELATED_VERSIONS}}{{RELATED_LANGUAGES}}
  </div>
  {{OUTDATED_WARNING}}
  {{DOCUMENT}}
  <div class='prev_next'>
    {{PREVIOUS_DOCUMENT}}{{NEXT_DOCUMENT}}
  </div>
</main>

  <footer>{{@footer}}</footer>

  <script>{{CLIENT_OPTIONS}}</script>
  <script src='https://code.jquery.com/jquery-3.1.1.min.js' integrity='sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=' crossorigin='anonymous'></script>
  <script src='https://cdn.jsdelivr.net/highlight.js/9.9.0/highlight.min.js'></script>
  <script src='https://cdn.jsdelivr.net/highlight.js/9.9.0/languages/typescript.min.js'></script>
  <script src='/assets/scripts.js'></script>
</body>
</html>

index.html contents:

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta http-equiv='cache-control' content='no-cache'>
  <title>{{@meta_title}}</title>
  <link rel='stylesheet' href='/assets/styles.css'>
  <link rel='stylesheet' href='https://cdn.jsdelivr.net/highlight.js/9.9.0/styles/{{@code_theme}}.min.css'>
  <link href='https://fonts.googleapis.com/css?family=Roboto|Fjalla+One|Share+Tech+Mono' rel='stylesheet'>
</head>
<body class='index'>

  <header>
    <a href='/'>{{@site_title}}</a>
    <nav>{{SITE_NAVIGATION}}</nav>
  </header>

  <main>
    {{DOCUMENT}}
  </main>

  <script>{{CLIENT_OPTIONS}}</script>
  <script src='https://code.jquery.com/jquery-3.1.1.min.js' integrity='sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=' crossorigin='anonymous'></script>
  <script src='https://cdn.jsdelivr.net/highlight.js/9.9.0/highlight.min.js'></script>
  <script src='https://cdn.jsdelivr.net/highlight.js/9.9.0/languages/typescript.min.js'></script>
  <script src='/assets/scripts.js'></script>
</body>
</html>
« PreviousNext »