kiln(1)

NAME

kiln - a simple static site generator

SYNOPSIS

kiln build [-c config]

kiln new path

DESCRIPTION

kiln build builds a kiln site.

kiln new creates a new kiln site at the given path.

OPTIONS

  kiln build

-c config
    Specifies the configuration file to use. Defaults to "config.toml".

OVERVIEW

A kiln site is built in one or more steps called tasks. Tasks read content from the content directory, process the content, and write the content to the output directory. Tasks can also be configured to copy static content to the output directory.

The following directories are common to all tasks:

Directory | Description
content/ | Content directory
templates/ | Templates directory

The basic unit of a kiln site is the page. Each page either represents a content file or a subdirectory containing other pages. Pages may be preprocessed, run through templates, and postprocessed (in that order). Each operation takes the output of the last operation as input.

CONTENT DIRECTORY

The content directory contains site content files which can be nested in subdirectories. Any file or directory in the content directory whose name begins with "_" will be ignored, with the exception of files with the name "_index" (e.g. "_index.gmi").

Content files can specify dates in their filenames. For example, the file content/2020-11-20-Hello-world.gmi will result in a page with a path of /Hello-world/ and a date of November 20, 2020.

Files with the name "_index" are treated specially. They can be used to provide frontmatter and content for the parent directory which will otherwise have none. If an "_index" file is present in a directory, an index page (e.g. "index.gmi") for that directory will be generated and written to the output directory.

  FRONTMATTER

Pages can specify additional metadata in frontmatter. Frontmatter is delimited by "---" and is specified in YAML. Newlines after the closing delimiter are removed from the content.

Example:

        ---
        title: Page title
        date: 2021-04-24
        params:
          key: value
        ---
        Page content

The following keys are supported:

title
    The title of the page.

    Example:

        ---
        title: My first post
        ---

date
    The date of the page. Pages are sorted by date in reverse order, so newer pages will be placed above older pages.

    Example:

        ---
        date: 2021-05-21
        ---

weight
    The weight of the page. Pages are sorted by weight in increasing order, so pages with a smaller weight will be placed above pages with a larger weight.

    Example:

        ---
        weight: 1
        ---

outputs
    Optionally specifies a list of tasks that can build this page. Defaults to all tasks.

    Example:

        ---
        outputs: ["Gemini", "HTTPS"]
        ---
        ---
        outputs: [] # Excluded from all tasks
        ---

template
    Optionally specifies the name of the template to use when building this page. If unspecified, defaults to "page" for regular pages and "index" for index pages. The template is then found according to TEMPLATE RESOLUTION.

    Example:

        ---
        title: About me
        template: about
        ---

params
    Specifies extra parameters to be provided to templates.

    Example:

        ---
        params:
          key: value
        ---

  SORTING

Pages are sorted automatically. Pages are first ordered by weight in increasing order, then by date from newest to oldest, and then by filename in alphabetical order.

TEMPLATES DIRECTORY

The templates directory contains templates for use when building the site. Templates use the Go templating language. The following templates are supported:

Template | Description
page.ext | Page template
index.ext | Directory index template
base.ext | Base template from which the page and index templates inherit
atom.xml | Atom feed template

The extension of page and index templates is configurable and will replace ".ext" above. See CONFIGURATION.

For more information on the Go templating language, see https://golang.org/pkg/text/template/.

  PAGE AND INDEX TEMPLATES

The content for page and index templates can be accessed using the .Content page variable. For example:

    page header
    {{ .Content }}
    page footer

Other page variables are documented in PAGE VARIABLES.

In HTML templates, page content is escaped by default. If the content is known to be safe, it must be marked as safe to avoid escaping. For example:

    <body>
    {{ .Content | safeHTML }}
    </body>

See TEMPLATE FUNCTIONS for more information.

  BASE TEMPLATES

Base templates are inherited only by page and index templates. Base templates generally define at least one block which can optionally be customized by page and index templates, according to the Go templating language.

For example, the base template could contain:

    {{ block "body" . }}
    	Blocks can have default content
    {{ end }}
    {{ block "extra_content" . }}{{ end }}

The page and index templates can then optionally customize these blocks, for example:

    {{ define "body" }}
    	Body goes here
    {{ end }}

  TEMPLATE RESOLUTION

The scope of a template is limited by the directory it is placed in. For example, a page template in the templates/blog/ directory will only apply to files in content/blog/. A page template placed in templates/ will only apply to files in content/ and not its subdirectories.

Fallback templates can be specified in the templates/_default/ directory. These templates will apply only when the required kind of template is not found in the template directory.

The template for a specific page can be overridden by setting the template key in the page's frontmatter. See FRONTMATTER for more details.

For example, the page file content/blog/my_first_post.gmi will be rendered with the template templates/blog/page.ext. If that template is not found, it falls back to templates/_default/page.ext. If that template is also not found, then no template will be used.

Base templates also follow the same rules. For example, the index template templates/blog/index.ext inherits firstly from templates/blog/base.ext, and then falls back to templates/_default/base.ext if present.

There is no override mechanism for base templates.

  PARTIAL TEMPLATES

Partial templates can be placed in the templates/_partials directory. Partial templates can be executed from any other template using the partial function. For example, a template could contain:

    {{ partial "navbar.ext" . }}

Then templates/_partials/navbar.ext is executed. Since argument . is provided, all data from the current context is provided. See TEMPLATE FUNCTIONS for more information.

In HTML templates, the partial template content is escaped by default. If the content is known to be safe, it must be marked as safe to avoid escaping. For example:

    <body>
    {{ partial "navbar.ext" . | safeHTML }}
    </body>

See TEMPLATE FUNCTIONS for more information.

CONFIGURATION

By default, kiln looks for a configuration file named "config.toml". An alternative configuration file can be specified with the -c flag. See OPTIONS.

The configuration file uses the TOML format.

The following keys are supported:

Key | Description
title | Site title
params | Extra parameters made available to templates

  TASKS

Tasks can be specified in the [[tasks]] array of tables.

The following configuration options are supported per task:

name
    An optional name for the task.

    Example:

        [[tasks]]
        name = "Gemini"
        [[tasks]]
        name = "HTML export"

input
    A list of input file extensions. Files in the content directory with a matching extension will be processed.

    Example:

        [[tasks]]
        input = [".gmi", ".md"]

output
    The output file extension. Files written to the output directory will use this extension.

    Example:

        [[tasks]]
        output = ".html"

template
    The template file extension. Templates with this file extension will be used to format the content. If unset, no templates will be used.

    Example:

        [[tasks]]
        template = ".gmi"

preprocess
    Maps file extensions to preprocess commands. Preprocess commands will run before templating. The commands will be provided the content of the page as standard input and should write the processed content to standard output.

    Example:

        [[tasks]]
        input = [".gmi", ".md"]
        output = ".html"
        preprocess.gmi = "gmnitohtml"
        preprocess.md = "mdtohtml"

postprocess
    Specifies a command which will run after templating and before content is written to the output directory. It will be provided the content of the page as standard input and should write the processed content to standard output.

    Example:

        [[tasks]]
        input = [".gmi"]
        output = ".html"
        template = ".gmi"
        postprocess = "gmnitohtml"

static_dir
    Specifies a directory from which to read static content. All files in this directory will be copied to the output directory without modificiation. Static assets like images should be stored in this directory. If unset, no static content directory will be used.

    Example:

        [[tasks]]
        static_dir = "static"

output_dir
    Specifies the directory to which output files will be written.

    Example:

        [[tasks]]
        output_dir = "public"

url
    The base URL to use for page URLs. The base URL should not have trailing forward slashes.

ugly_urls
    Specifies whether page paths will contain file extensions. By default, clean paths without any extension are used.

    Example:

        [[tasks]]
        ugly_urls = true

The following configuration builds a simple Gemini site.

        [[tasks]]
        input = [".gmi"]
        output = ".gmi"
        template = ".gmi"
        output_dir = "public"

The following configuration generates a Gemini text site and also exports an HTML version of the site. This configuration makes use of the gmnitohtml(1) command to convert Gemini text to HTML.

        # Build the site
        [[tasks]]
        input = [".gmi"]
        output = ".gmi"
        template = ".gmi"
        static_dir = "static"
        output_dir = "public"
        # Export an HTML version of the site
        [[tasks]]
        input = [".gmi"]
        output = ".html"
        template = ".gmi"
        postprocess = "gmnitohtml"
        static_dir = "static"
        output_dir = "public_html"

The following configuration generates an HTML site from Markdown and Gemini text files in the content directory and HTML templates in the templates directory. This configuration makes use of the mdtohtml(1) command to convert Markdown to HTML, and the gmnitohtml(1) command to convert Gemini text to HTML.

        [[tasks]]
        input = [".md", ".gmi"]
        output = ".html"
        template = ".html"
        preprocess.md = "mdtohtml"
        preprocess.gmi = "gmnitohtml"
        static_dir = "static"
        output_dir = "public"

  PERMALINKS

Permalinks can be used to rewrite page paths. Permalinks are specified in the [tasks.permalinks] table of the configuration file. Keys denote a path to a directory, and values use the Go templating language to rewrite the final path of pages in that directory. The templates have the same data that page templates have available to them (see PAGE VARIABLES).

The following configuration will rewrite the paths of pages in the content/blog directory to /YYYY/MM/DD/slug. For example, the file content/blog/2021-05-12-hello-world.gmi will have a path of /2021/05/12/hello-world/.

        [[tasks]]
        # ...
        [tasks.permalinks]
        "/blog/" = "/{{ .Date.Format `2006/01/02` }}/{{ path.Base .Path }}"

For more information on templates, see TEMPLATES.

  FEEDS

Feeds can be specified in the [[tasks.feeds]] array of tables. Multiple feeds can be specified per task.

Example feed configuration:

        [[tasks]]
        # ...
        # This generates a feed for the files in content/blog
        # and writes it to blog/atom.xml (relative to the output directory)
        [[tasks.feeds]]
        input_dir = "blog"
        title = "My Blog"
        template = "atom.xml"
        output = "blog/atom.xml"
        # You can generate multiple feeds per task
        # The generated feed can be written anywhere
        # Here it is written to feed.xml (relative to the output directory)
        [[tasks.feeds]]
        input_dir = "blog"
        title = "My Blog"
        template = "custom_feed.xml"
        output = "feed.xml"

input_dir
    the content folder with which to populate the feed

title
    the title of the feed, accessible via {{ .Title }} in the feed template

template
    the template to use for the feed

output
    the output path for the rendered feed

TEMPLATES

Templates have certain data and functions available to them.

  SITE VARIABLES

The following site-wide variables are available:

.Title
    The title of the site.

.Params
    Extra parameters specified in configuration.

.Generated
    Site generation time.

.Root
    The root page of the site. See PAGE VARIABLES.

Some of these variables are defined in your site's configuration. See CONFIGURATION.

Site variables can be accessed from templates with the site function. See TEMPLATE FUNCTIONS.

  PAGE VARIABLES

The following page variables are available:

.Title
    The title of the page

.Date
    The date of the page

.Weight
    The weight of the page

.Path
    The path to the page

.URL
    The URL of the page. If no base URL is configured, it is equivalent to .Path.

.FilePath
    The path of the page file or directory relative to the content directory

.Content
    The contents of the page

.Params
    Extra parameters specified in frontmatter

.Prev
    The previous page in sorted order

.Next
    The next page in sorted order

.Pages
    List of pages in this directory

.Dirs
    List of subdirectories in this directory

Some of these variables are defined in page frontmatter. See FRONTMATTER.

Page variables can be accessed from page and index templates.

  PAGE FUNCTIONS

The following page functions are available:

.GetPage path
    Retrieves the page in this directory with the given path, which may be relative or absolute.

    Example:

        {{/* Retrieve a directory relative to the root directory
        	and iterate over its pages */}}
        {{ with site.Root.GetPage "/blog" }}
        	{{ range .Pages }}
        		{{ .Title }}
        	{{ end }}
        {{ end }}
        {{/* Retrieve a directory relative to the current directory
        	and iterate over its pages */}}
        {{ with .GetPage "posts" }}
        	{{ range .Pages }}
        		{{ .Title }}
        	{{ end }}
        {{ end }}
        {{/* Retrieve a page relative to the current directory */}}
        {{ with .GetPage "posts/hello-world.gmi" }}
        	{{ .Title }}
        {{ end }}

Page functions can be accessed from page and index templates.

  FEED VARIABLES

The following feed variables are available:

.Title
    The title of the feed

.Path
    The path to the feed directory

.URL
    The URL of the feed directory

.Pages
    List of pages in this feed

Some of these variables are defined in feed configuration. See FEEDS.

Feed variables can be accessed from feed templates.

  PARTIAL TEMPLATES

Partial templates can be placed in the templates/_partials directory. Partial templates can be executed from any other template with the partial function. See TEMPLATE FUNCTIONS.

  TEMPLATE FUNCTIONS

All templates have the following functions available to them:

and args...
    Returns the boolean AND of its arguments by returning the first empty argument or the last argument, that is, "and x y" behaves as "if x then y else x". All the arguments are evaluated.

call function, args...
    Returns the result of calling the first argument, which must be a function, with the remaining arguments as parameters. Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where Y is a func-valued field, map entry, or the like. The first argument must be the result of an evaluation that yields a value of function type (as distinct from a predefined function such as print). The function must return either one or two result values, the second of which is of type error. If the arguments don't match the function or the returned error value is non-nil, execution stops.

eq arg1, arg2
    Returns the boolean truth of arg1 == arg2.

exec command, input
    Executes the given external command with input provided as standard input. Returns its standard output.

ge arg1, arg2
    Returns the boolean truth of arg1 >= arg2.

gt arg1, arg2
    Returns the boolean truth of arg1 > arg2.

html args...
    Returns the escaped HTML equivalent of the textual representation of its arguments. This function is unavailable in HTML templates, with a few exceptions.

index collection, args...
    Returns the result of indexing its first argument by the following arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each indexed item must be a map, slice, or array.

js args...
    Returns the escaped JavaScript equivalent of the textual representation of its arguments.

le arg1, arg2
    Returns the boolean truth of arg1 <= arg2.

len list
    Returns the integer length of its argument.

lt arg1, arg2
    Returns the boolean truth of arg1 < arg2.

math.Add arg1, arg2
    Returns arg1 + arg2 as an integer if both arguments are integers, otherwise as a float.

math.Sub arg1, arg2
    Returns arg1 - arg2 as an integer if both arguments are integers, otherwise as a float.

math.Mul arg1, arg2
    Returns arg1 * arg2 as an integer if both arguments are integers, otherwise as a float.

math.Div arg1, arg2
    Returns arg1 / arg2 as a float.

math.Mod arg1, arg2
    Returns arg1 % arg2 as an integer.

math.Ceil arg
    Returns the least integer value greater than or equal to arg.

math.Floor arg
    Returns the greatest integer value less than or equal to arg.

math.Log arg
    Returns the natural logarithm of arg as a float.

math.Max arg1, arg2
    Returns the greater of arg1 and arg2 as an integer if both arguments are integers, otherwise as a float.

math.Min arg1, arg2
    Returns the lesser of arg1 and arg2 as an integer if both arguments are integers, otherwise as a float.

math.Pow arg1, arg2
    Returns arg1 ^ arg2 as a float.

math.Round arg
    Returns the nearest integer to arg, rounding half away from zero.

math.Sqrt arg
    Returns square root of arg as a float.

ne arg1, arg2
    Returns the boolean truth of arg1 != arg2.

not arg
    Returns the boolean negation of its single argument.

or args...
    Returns the boolean OR of its arguments by returning the first non-empty argument or the last argument, that is, "or x y" behaves as "if x then x else y". All the arguments are evaluated.

partial name, data
    Executes the named partial template with the provided data. See PARTIAL TEMPLATES.

    Example:

        {{ partial "header.gmi" . }}

path.Base path
    Returns the last element of path.

path.Clean path
    Returns the shortest path name equivalent to path.

path.Dir path
    Returns all but the last element of path, typically the path's directory.

path.Ext path
    Returns the filename extension used by path.

path.Join elem...
    Joins any number of path elements into a single path.

print args...
    Formats using the default formats for its operands and returns the resulting string. Spaces are added between operands when neither is a string.

printf format, args...
    Formats according to a format specifier and returns the resulting string.

println args...
    Formats using the default formats for its operands and returns the resulting string. Spaces are always added between operands and a newline is appended.

reverse list
    Returns a reversed copy of the provided slice or array.

safeCSS css
    Encapsulates known safe CSS content.

safeHTML html
    Encapsulates a known safe HTML document fragment.

safeHTMLAttr attr
    Encapsulates an HTML attribute from a trusted source.

safeJS js
    Encapsulates a known safe JavaScript expression.

safeURL url
    Encapsulates a known safe URL or URL substring.

site
    Returns site information (see SITE VARIABLES).

slice list, args...
    slice returns the result of slicing its first argument by the remaining arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2], while "slice x" is x[:], "slice x 1" is x[1:], and "slice x 1 2 3" is x[1:2:3]. The first argument must be a string, slice, or array.

strings.Count string, substr
    Counts the number of non-overlapping instances of substr in string. If substr is an empty string, Count returns 1 + the number of Unicode code points in string.

strings.HasPrefix string, prefix
    Reports whether string begins with prefix.

strings.HasSuffix string, suffix
    Reports whether string ends with suffix.

strings.Join elems, sep
    Concatenates the elements of its first argument to create a single string. The separator string sep is placed between elements in the resulting string.

strings.Repeat string, count
    Returns a new string consisting of count copies of string.

    It panics if count is negative or if the result of (len(string) * count) overflows.

strings.Replace string, old, new, n
    Returns a copy of string with the first n non-overlapping instances of old replaced by new. If old is empty, it matches at the beginning of the string and after each UTF-8 sequence, yielding up to k+1 replacements for a k-rune string. If n < 0, there is no limit on the number of replacements.

strings.ReplaceAll string, old, new
    Returns a copy of string with all non-overlapping instances of old replaced by new. If old is empty, it matches at the beginning of the string and after each UTF-8 sequence, yielding up to k+1 replacements for a k-rune string.

strings.Split string, sep
    Slices string into all substrings separated by sep and returns a slice of the substrings between those separators.

    If string does not contain sep and sep is not empty, Split returns a slice of length 1 whose only element is string.

    If sep is empty, Split splits after each UTF-8 sequence. If both string and sep are empty, Split returns an empty slice.

strings.Title string
    Returns a copy of the string with all Unicode letters that begin words mapped to their Unicode title case.

    BUG: The rule Title uses for word boundaries does not handle Unicode punctuation properly.

strings.ToLower string
    Returns string with all Unicode letters mapped to their lower case.

strings.ToUpper string
    Returns string with all Unicode letters mapped to their upper case.

strings.Trim string, cutset
    Returns a slice of string with all leading and trailing Unicode code points contained in cutset removed.

strings.TrimLeft string, cutset
    Returns a slice of string with all leading Unicode code points contained in cutset removed.

    To remove a prefix, use strings.TrimPrefix instead.

strings.TrimPrefix string, prefix
    Returns string without the provided leading prefix string. If string doesn't start with prefix, it is returned unchanged.

strings.TrimRight string, cutset
    Returns a slice of string with all trailing Unicode code points contained in cutset removed.

    To remove a suffix, use strings.TrimSuffix instead.

strings.TrimSpace string
    Returns a slice of string with all leading and trailing white space removed, as defined by Unicode.

strings.TrimSuffix string, suffix
    Returns string without the provided trailing suffix string. If string doesn't end with suffix, it is returned unchanged.

urlquery args...
    Returns the escaped value of the textual representation of its arguments in a form suitable for embedding in a URL query. This function is unavailable in HTML templates, with a few exceptions.