Metanorma Site Generation (metanorma site
)
Introduction
The site
subcommand enables you to compile and publish multiple Metanorma
documents as a cohesive document site.
This functionality is particularly useful for:
-
Multiple documents belonging to the same series
-
Single documents published to multiple venues
-
Multiple parts of a document collection
Commands
Site generation
metanorma site generate [OPTIONS...] [SITE_MANIFEST_FILE]
If no SITE_MANIFEST_FILE is provided,
the file metanorma.yml
in the current directory is used.
CLI options
-c, --config CONFIG
-
File path for Metanorma site manifest YAML configuration (Default:
metanorma.yml
in the current directory) (Deprecated: use the SITE_MANIFEST_FILE argument instead) -o, --output-dir DIR
-
Directory for generated site output, relative to the current working directory (Default:
_site
in current directory)
-s, --stylesheet FILE
-
Specify custom stylesheet for HTML output, relative to the current working directory
-t, --template-dir DIR
-
Specify custom Liquid templates for site design, relative to the current working directory
--output-filename-template TEMPLATE_STRING
-
Define output filenames using Liquid templating (Uses Relaton model for variable access)
--agree-to-terms
-
Accept third-party licensing terms
--no-agree-to-terms
-
Reject licensing terms
--skip-agree-to-terms
-
Skip license agreement prompt
--install-fonts
-
Install required fonts (Default)
--no-install-fonts
-
Do not install fonts
--skip-install-fonts
-
Skip font installation prompt
--continue-without-fonts
-
Proceed when fonts are missing
--no-continue-without-fonts
-
Abort when fonts are missing
--skip-continue-without-fonts
-
Skip missing fonts prompt
-S, --strict
-
Abort compilation on errors
--no-strict
-
Continue on errors
--skip-strict
-
Skip strict mode prompt
Configuration using site manifest
The site generation process can be configured using a site manifest. The site manifest file is a configuration file that is in YAML format:
metanorma:
source:
files: (1)
- doc1.adoc
- "series/*.adoc"
collection:
name: "Site Title" (2)
organization: "Publisher" (3)
template:
path: "templates" (4)
stylesheet: "custom.css" (5)
output_filename: "" (6)
-
metanorma.source.files
: Array of files to process -
metanorma.collection.name
: Site title -
metanorma.collection.organization
: Site owner -
metanorma.template.path
: Custom template directory (see Templates and styling) -
metanorma.template.output_filename
: Filename template (see Output filename templates)
By default, the file metanorma.yml
located in the source directory would be
used.
Templates and styling
General
Customization of the site’s HTML output is done using Liquid templates.
Metanorma uses the template files found in the specified template directory to generate the site’s index page and individual document entries.
Template directory structure
The path to the template directory can be specified via the CLI using the
-t, --template-dir
option,
or in the site manifest under the metanorma.template.path
key.
If the path is an absolute path, it is used as is.
If it is a relative path, its full path is calculated based on where it is defined.
-
If it is defined in the site manifest file, then the path is relative to the directory containing the manifest file.
-
If it is defined via the CLI, then the path is relative to the current working directory, i.e., the directory from which the command was run.
-
If no manifest file is present, the path is also relative to the current working directory. If a template directory is not specified, the default template directory is used, which is located in the Relaton CLI repository
The template directory must contain:
_index.liquid
-
Main template for the site’s index page
_document.liquid
-
Template for individual document entries
- CSS stylesheet
-
Specify the path to the stylesheet, of which the content can be referenced in templates using the
css
variable.The path can be specified in the site manifest under the
metanorma.template.stylesheet
key, or via the CLI using the-s, --stylesheet
option.Path resolution follows the same rules as the template directory path.
For a more detailed example of what a template directory might look like, see the default templates in the Relaton CLI repository.
Template variables
The index template (_index.liquid
) has access to:
The document template
(e.g., _document.liquid
, via the document
template variable)
has access to:
-
docid.id
- Document identifier -
title
- Document title -
html
- HTML URL path -
pdf
- PDF URL path -
doc
- Word document URL path -
xml
- XML URL path -
rxl
- Relaton XML URL path -
uri
- Document URI -
doctype.type
- Document type -
edition.content
- Edition information -
docstatus.stage.value
- Document stage -
docstatus.stage.abbreviation
- Abbreviaton for the document status -
docstatus.substage.value
- Document substage -
revdate
- Revision date -
items
- Array of document items (if applicable, e.g., when the document is itself a collection)
_index.liquid
template<!-- _index.liquid -->
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<style>{{ css }}</style>
</head>
<body>
<h1>{{ title }}</h1>
<div class="documents">
{% render 'document' for documents as document %}
</div>
<footer>Generated: {{ date }}</footer>
</body>
</html>
Note
|
The example uses the render tag instead of include as this the
recommended way to include templates in Liquid.
The for parameter allows iteration through the documents collection while
maintaining proper variable scoping.
|
_document.liquid
template<!-- _document.liquid -->
<div class="document">
<h2><a href="{{ document.html }}">{{ document.docid.id }}</a></h2>
<p class="title">{{ document.title }}</p>
<p class="status">Status: {{ document.docstatus.stage }}</p>
{% if document.pdf %}
<a href="{{ document.pdf }}">PDF</a>
{% endif %}
</div>
For a more detailed example of what a template might look like, see the default Liquid templates.
Output filename templates
General
Using Liquid templating, Metanorma allows for custom output filenames across all output formats.
For the list of all variables available for filename templates (which is separate from those available in the HTML templates), see the Available variables section.
Default behavior
When an empty string is passed as the template (or when no template is specified), the system generates a normalized version of the document identifier.
For a document with identifier "ISO/IEC FDIS 12345-3", the default output would be:
iso-iec-fdis-12345-3
The generated document files would be named accordingly:
_site/ ├── index.html ├── documents.xml └── documents/ ├── iso-iec-fdis-12345-3.html ├── iso-iec-fdis-12345-3.doc ├── iso-iec-fdis-12345-3.pdf ├── iso-iec-fdis-12345-3.rxl └── iso-iec-fdis-12345-3.xml
Available variables
Templates can access document metadata through the document
object:
-
docidentifier
- Full document identifier -
language
- Document language code -
edition
- Edition number -
doctype
- Document type -
docnumber
- Document number -
partnumber
- Part number (if applicable)
metanorma:
template:
output_filename: "{{ document.docidentifier | downcase | replace: '/' , '-' }}"
metanorma:
template:
output_filename: |
{%- if document.doctype == 'international-standard' -%}
iso-
{%- else -%}
std-
{%- endif -%}
{{- document.docnumber -}}
{%- if document.partnumber %}-{{ document.partnumber }}{% endif %}
This demonstrates:
-
Conditional logic based on document type
-
Optional part number inclusion
-
Multi-line template formatting
-
Whitespace trimming with
{%-
,-%}
, and{{-
,-}}
-
Template filters
Common Liquid filters available:
For the full list of available Liquid filters, see Liquid Filters.
Error handling
-
Invalid syntax raises
Liquid::SyntaxError
-
Missing variables are replaced with empty strings
# Template: "{{ nonexistent }}_{{ document.language }}"
# Result: "_en"
Site structure
Generation process
-
Scans source directory for Metanorma documents
-
Compiles each document with specified options
-
Creates site directory structure
-
Generates collection index (documents.xml)
-
Creates HTML index page
-
Copies assets and compiled documents
Output directory structure
_site/ (1) ├── index.html (2) ├── documents.xml (3) └── documents/ (4) ├── doc1.html ├── doc1.pdf ├── doc1.rxl ├── doc1.xml ├── doc2.html ├── doc2.pdf ├── doc2.rxl └── doc2.xml
-
Default output directory
-
Main site index
-
Collection index
-
Compiled documents
Best practices
- Organize documents in logical directory structures
-
Place each document in a separate directory to avoid conflicts.
sources/ ├── doc1/ │ └── main.adoc ├── doc2/ │ └── main.adoc └── doc3/ ├── main.adoc └── annex.adoc
- Use consistent naming conventions in templates
-
Use the same name for the document template file as the references in the template files.
<!-- _index.liquid --> (1)
...
{% render 'document' for documents as document %} (2)
...
<!-- _document.liquid --> (2) (3)
...
<h1>{{ document.title }}</h1> (3)
...
-
The name of the index template file is always going to be
_index.liquid
. As of writing, this is not configurable. -
The name of the document template file should match the reference in the index template.
-
The name of the document template file should match the reference in the document template itself.
- Include error handling for optional metadata fields
-
default
filter-
Use Liquid’s
default
filter to handle missing metadata fields.<h1>{{ document.title | default: "Untitled" }}</h1>
- conditional logic
-
Use conditional logic to handle optional metadata fields.
{% if document.partnumber %} <p>Part {{ document.partnumber }}</p> {% endif %}
- Use whitespace trimming for whitespace-sensitive templates
-
This is particularly important when working with output filename templates, which can be sensitive to whitespace. Use Liquid’s whitespace control to manage whitespace in templates.
TIPS: When in doubt, always use whitespace control to ensure consistent filename template rendering.metanorma: template: output_filename: | {%- if document.doctype == 'standard' -%} std-{{- document.docnumber -}} {%- else -%} doc-{{- document.docidentifier | downcase -}} {%- endif -%}
Examples
Minimal configuration
Uses the default configuration file (metanorma.yml
) in the current directory,
and outputs to the default directory (_site
).
metanorma site generate
Basic site generation (given directory)
Uses the default configuration file (metanorma.yml
) in the ./sources
directory,
and outputs to the specified directory (./output
).
metanorma site generate ./sources -o output
Basic site generation (given site manifest file)
Uses the specified configuration file
(./sources/project-a/my-manifest.yml
),
and outputs to the specified directory (./output
).
metanorma site generate ./sources/project-a/my-manifest.yml -o output
Custom naming with metadata
Using the CLI:
> metanorma site generate \
--output-filename-template \
"{{ document.docidentifier }}-{{ document.version }}"
Alternatively, using the site manifest:
# metanorma.yml
metanorma:
template:
output_filename: "{{document.docidentifier}}-{{document.version}}"
Complex configuration
Longer template expressions are best defined in the site manifest, which allows for a more readable multiline format:
metanorma:
source:
files:
- "doc*/main.adoc"
- "collection*/metanorma.yml"
collection:
name: "Technical Documentation"
organization: "Acme Corp."
template:
stylesheet: "assets/stylesheets/site_index.css"
template_dir: "templates"
output_filename: |
{% if document.doctype == 'standard' -%}
std-{{ document.docnumber -}}
{%- else -%}
doc-{{ document.docidentifier | downcase -}}
{%- endif %}
CI/CD pipeline
For scripting and automation,
use the --agree-to-terms
option to bypass the license agreement prompt:
> metanorma site generate --agree-to-terms
See Continuous Integration and Continuous Deployment for more detailed examples on how to integrate Metanorma site generation into your CI/CD pipeline.