Site, page and nav variables
Site, page and nav variables
When a markdown file (or other supported content) is rendered, the
Mako template receives a number of context variables as partly described
above. A few of these variables, such as MDTEMPLATES
and
DATADIR
set directly by wmk
(see above).
Others are user-configured either (1) in wmk_config.yaml
(the contents of the site
object and potentially additional
“global” varaibles in template_context
); or (2) the cascade
of index.yaml
files in the content
directory
and its subdirectories along with the YAML frontmatter of the markdown
file itself, the result of which is placed in the page
object.
When gathering the content of the page
variable,
wmk
will start by looking for index.yaml
files
in each parent directory of the markdown file in question, starting at
the root of the content
directory and moving upwards, at
each step extending and potentially overriding the data gathered at
previous stages. Only then will the YAML in the frontmatter of the file
itself be parsed and added to the page
data.
The file-specific frontmatter may be in the content file itself, or
it may be in a separate YAML file with the same name as the content file
but with an extra .yaml
extension. For instance, if the
content filename is important.md
, then the YAML file would
be named important.md.yaml
. If both in-file and external
frontmatter is present, the two will be merged, with the in-file values
“winning” in case of conflict.
At any point, a data source in this cascade may specify an extra YAML
file using the special LOAD
variable. This file will then
be loaded as well and subsequently treated as if the data in it had been
specified directly at the start of the file containing the
LOAD
directive.
Which variables are defined and used by templates is very much up the
user, although a few of them have a predefined meaning to
wmk
itself. For making it easier to switch between
different themes it is however suggested to stick to the following
meaning of some of the variables:
The variables site
and page
are dicts with
a thin convenience layer on top which makes it possible to reference
subkeys belonging to them in templates using dot notation rather than
subscripts. For instance, if page
has a dict variable named
foo
, then a template could contain a fragment such as
${ page.foo.bar or 'splat' }
– even if the foo
dict does not contain a key named bar
. Without this
syntactic sugar you would have to write something much more defensive
and long-winded such as
${ page.foo.bar if page.foo and 'bar' in page.foo else 'splat' }
.
The nav
variable
The nav
key in the wmk_config.yaml
file, if
present, will be treated as a navigation tree for the site and
represented as a tree-like Nav
object.
A typical nav setting looks something like this:
nav:
- Home: /
- User Guide:
- Lorem:
- Ipsum: /guide/ipsum/
- Eu fuit: /guide/mageisse/
- Dolor sit amet: /guide/concupescit/
- Resources:
- Community: 'https://example.com/'
- Source code: 'https://github.com/example/com/'
- About:
- License: /about/license/
- History: /about/history/
In templates, this will be available as the nav
variable.
There are two types of entries in the nav: links and sections. A link is just a title and an URL. A section has a title and a list of links or sections (possibly nested).
Each item has a parent
(with the nav
itself
as the top level parent) and a level
(starting from 0 for
the immediate children of the nav
). The nav
has a homepage
attribute which by default is the first
local link in the nav. Each local link has previous
and
next
attributes. Each section has children
.
There are other attributes but these are the basics.
The nav
variable is relatively new (as of version 1.2.x,
May 2023) and not really supported by themes yet. It is especially
intended for sites with a hierarchical structure but neither very many
pages nor deeply nested, such as a typical documentation site.
The TOC
variable
When a page is rendered, the generated HTML is examined and a simple
table of contents object constructed, which will be available to
templates as TOC
. It contains a list of the top-level
headings (i.e. H1 headings, or H2 headings if no H1 headings are
present, etc.), with lower-level headings hierarchically arranged in its
children
. Other attributes are url
and
title
. TOC.item_count
contains the heading
count (regardless of nesting).
The TOC
variable can e.g. be used by the page template
to show a table of contents elsewhere on the page.
The table of contents object is not constructed unless each heading
has an id
attribute. When using the default
python-markdown, this means that the toc
extension must be
active.
System variables
The following frontmatter variables affect the operation of
wmk
itself, rather than being exclusively handled by Mako
templates.
Templates
Note that a variable called something like
page.foo
below is referenced as such in Mako templates but
specified in YAML frontmatter simply as foo: somevalue
.
page.template
specifies the Mako template which will render the content.page.layout
is used by several other static site generators. For compatibility with them, this variable is supported as a fallback synonym withtemplate
. It has no effect unlesstemplate
has not been specified explicitly anywhere in the cascade of frontmatter data sources.
For both template
and layout
, the
.mhtml
extension of the template may be omitted. If the
template
value appears to have no extension,
.mhtml
is assumed; but if the intended template file has a
different extension, then it of course cannot be omitted.
Likewise, a leading base/
directory may be omitted when
specifying template
or layout
. For instance, a
layout
value of post
would find the template
file base/post.mhtml
unless a post.mhtml
file
exists in the template root somewhere in the template search path.
If neither template
nor layout
has been
specified and no default_template
setting is found in
wmk_config.yaml
, the default template name for markdown
files is md_base.mhtml
.
Affects rendering
page.slug
: If the value ofslug
is nonempty and consists exclusively of lowercase alphanumeric characters, underscores and hyphens (i.e. matches the regular expression^[a-z0-9_-]+$
), then this will be used instead of the basename of the markdown file to determine where to write the output. If aslug
variable is missing, one will be automatically added bywmk
based on the basename of the current markdown file. Templates should therefore be able to depend upon slugs always being present. Note that slugs are not guaranteed to be unique, although that is good practice.page.pretty_path
: If this is true, the basename of the markdown filename (or the slug) will become a directory name and the HTML output will be written toindex.html
inside that directory. By default it is false for files namedindex.md
orindex.html
and true for all other files. If the filename contains symbols that do not match the character class[\w.,=-]
, then it will be “slugified” before final processing (although this only works for languages using the Latin alphabet).page.do_not_render
: Tellswmk
not to write the output of this template to a file inhtdocs
. All other processing will be done, so the gathered information can be used by templates for various purposes. (This is similar to theheadless
setting in Hugo).page.draft
: If this is true, it prevents further processing of the markdown file unlessrender_drafts
has been set to true in the config file.page.no_cache
: If this is true, the rendering cache will not be used for this file. (See also theuse_cache
setting in the configuration file).page.markdown_extensions
,page.markdown_extension_configs
,page.pandoc
,page.pandoc_filters
,page.pandoc_options
,page.pandoc_input_format
,page.pandoc_output_format
: See the description of these options in the section on the configuration file, above.page.POSTPROCESS
: This contains a list of processing instructions which are called on the rendered HTML just before writing it to the output directory. Each instruction is either a function (placed intoPOSTPROCESS
by a shortcode) or a string (possibly specified in the frontmatter). If the latter, it points to a function entry in theautoload
dict imported from either the project’spy/wmk_autoload.py
file or the theme’spy/wmk_theme_autoload.py
file. In either case, the function receives the html as the first argument while the rest of the arguments constitute the template context. It should return the processed html.page.PREPROCESS
: This is analogous topage.POSTPROCESS
, except that the instructions in the list are applied to the markdown (or other content document) just before converting it to HTML. The function receives two arguments: the document text and thepage
object. It should return the altered document source. Note that this happens before shortcodes have been expanded, so (unlikepage.POSTPROCESS
) such actions cannot be added via shortcode.
Note that if two files in the same directory have the same slug, they
may both be rendered to the same output file; it is unpredictable which
of them will go last (and thus “win the race”). The same kind of
conflict may arise between a slug and a filename or even between two
filenames containing non-ascii characters. It is up to the content
author to take care to avoid this; wmk
does nothing to
prevent it.
Standard variables and their recommended meaning
The following variables are not used directly by wmk
but
affect templates in different ways. It is a list of recommendations
rather than something which must be necessarily followed.
Typical site variables
Site variables are the keys-value pairs under site:
in
wmk_config.yaml
.
site.title
: Name or title of the site.site.lang
: Language code, e.g. ‘en’ or ‘en-us’. Used e.g. for translations by some themes.site.locale
: Locale code, e.g. ‘en_US.utf8’. Used when sortingMDCONTENT
by name or title.site.tagline
: Subtitle or slogan.site.description
: Site description.site.author
: Main author/proprietor of the site. Depending on the site templates (or the theme), may be a string or a dict with keys such as “name”, “email”, etc.site.base_url
: The protocol and hostname of the site (perhaps followed by a directory path ifsite.leading_path
is not being used). Normally without a trailing slash.site.leading_path
: If the web pages built bywmk
are not at the root of the website but in a subdirectory, this is the appropriate prefix path. Normally without a trailing slash.site.build_time
: This is automatically added to the site variable bywmk
. It is a datetime object indicating when the rendering phase of the current run started.site.lunr_search
: A boolean automatically added to the site variable. It is true whenlunr_index
is true in the configuration file.
Templates or themes may be configurable through various site
variables, e.g. site.paginate
for number of items per page
in listings or site.mainfont
for configuring the font
family.
Classic meta tags
These variables mostly relate to the text content and affect the
metadata section of the <head>
of the HTML page.
page.title
: The title of the page, typically placed in the<title>
tag in the<head>
and used as a heading on the page. Normally the title should not be repeated as a header in the body of the markdown file. Most markdown documents should have a title. If it is not explicitly specified, the title will be generated automatically from the filename.page.slug
: See above. If it is missing, the slug is created from the title.page.id
: This is guaranteed to be unique at rendering time. If it is present but not unique, then “-1”, “-2”, etc., will be appended as necessary. If it is not explicitly specified, then it is generated by slugifying the full path to the source markdown file (relative to the content directory). For instance,blog/2022/09/The letter Þ in Old English.md
will become the IDblog-2022-09-the-letter-th-in-old-english
.page.description
: Affects the<meta name="description" ...>
tag in the<head>
of the page. The variablesummary
(see later) may also be used as fallback here.page.keywords
: Affects the<meta name="keywords" ...>
tag in the<head>
of the page. This may be either a list or a string (where items are separated with commas).page.robots
: Instructions for Google and other search engines relating to this content (e.g.noindex, nofollow
) should be placed in this variable.page.author
: The name of the author (if there is only one). May lead to<meta name="keywords" ...>
tag in the<head>
as well as appear in the body of the rendered HTML file. Some themes may expect this to be a dict with keys such asname
,email
,image
, etc.page.authors
: If there are many authors they may be specified here as a list. It is up to the template how to handle it if bothauthor
andauthors
are specified, but one way is to add theauthor
to theauthors
unless already present in the list.page.summary
: This may affect the<meta name="description" ...>
tag as a fallback if nodescription
is provided, but its main purpose is for list pages with article teasers and similar content.
Note that this is by no means an exhaustive list of variables likely
to affect the <head>
of the page. Notably, several
other variables may affect meta tags used for sharing on social media.
The most common is probably page.image
(described below).
In any case, the implementation itself is up to the theme or template
author.
Dates
Dates and datetimes should normally be in a format conformant with or
similar to ISO 8601, e.g. 2021-09-19
and
2021-09-19T09:19:21+00:00
. The T
may be
replaced with a space and the time zone may be omitted (localtime is
assumed). If the datetime string contains hours it should also contain
minutes, but seconds may be omitted. If these rules are followed, the
following variables are converted to date or datetime objects (depending
on the length of the string) before they are passed on to templates.
page.date
: A generic date or datetime associated with the document.page.pubdate
: The date/datetime when first published. Currentlywmk
does not skip files withpubdate
in the future, but it may do so in a later version.page.modified_date
: The last-modified date/datetime. Note thatwmk
will also add the variableMTIME
, which is the modification time of the file containing the markdown source, so this information can be inferred from that if this variable is not explicitly specified.page.created_date
: The date the document was first created.page.expire_date
: The date from which the document should no longer be published. Similarly topubdate
, this currently has no direct effect onwmk
but may do so in a later version.
See also the description of the DATE
and
MTIME
context variables above.
Media content
page.image
: The main image associated with the document. Affects theog:image
meta tag in HTML output and may be used for both teasers and content rendering.page.images
: A list of images associated with the document. Ifimage
is not specified, the main image will be taken to be the first in the list.page.audio
: A list of audio files/urls associated with this document.page.videos
: A list of video files/urls associated with this document.page.attachments
: A list of attachments (e.g. PDF files) associated with this document.
Taxonomy
page.section
: One of a quite small number of sections on the site, often corresponding to the leading subdirectory incontent
. E.g. “blog”, “docs”, “products”.page.categories
: A list of broad categories the page belongs to. E.g. “Art”, “Science”, “Food”. The first-named category may be regarded as the primary one.page.tags
: A list of tags relevant to the content of the page. E.g. “quantum physics”, “knitting”, “Italian food”.page.weight
: A measure of importance attached to a page and used as an ordering key for a list of pages. This should be a positive integer. The list is normally ascending, i.e. with the lower numbers at the top. (Pages may of course be ordered by other criteria, e.g. bypubdate
).