1. Introduction

Styx is a functional static site generator written in Nix expression language.

Styx is aimed to be flexible and easy to customize. It is based on the Nix package manager, so it get many of its advantages: caching system, determinism to name a few.

Styx was inspired by the NixOS weekly project and the Hugo static site generator.

1.2. Styx Overview

Pros:

  • Uniformity: The same language is for templates and logic (and can be used for data too).

  • Caching: Styx benefit of the Nix caching system, so only needed pages are rebuild.

  • Light weight: Styx has very few dependencies.

  • Flexibility: Styx is very flexible and make it is easy to implement new features.

Cons:

  • Performance: Some parts of Styx like the markup file conversion can be quite slow, this is partly counter-balanced by the caching system, but on a fresh site generation Styx can be magnitudes slower than other static site generators.

  • Semantics: Styx is using the Nix expression language for its logic and templates. The Nix expression language is quite different of usual languages and can need some time to get familiar with.

  • Nix: Styx has only one dependency, the Nix package manager. To use Styx you must install Nix, and depending your platform, that can be challenging. But installing Nix might totally change your views on package management!

2. Installation

The only requirement to install Styx is the Nix package manager. Refer to the Nix installation instructions to install Nix.

It is possible to install styx with the following command:

$ nix-env -i https://github.com/styx-static/styx/archive/latest.tar.gz

For testing purposes, nix-shell can be used to start a temporary environment with styx without needing to install it:

$ nix-shell -p $(nix-build https://github.com/styx-static/styx/archive/latest.tar.gz)

3. Quick Start

The styx showcase theme example site can be previewed by the following command:

$ styx preview --in $(nix-build -A styx-themes.showcase '<nixpkgs>')/example (1)

This command download the showcase theme in the nix store, build the site also in the nix store and launch the preview from there.
This will only create files in the nix store.

The showcase example site will be accessible at http://127.0.0.1:8080. Check the posts as they provide some information about how styx works.


To start a new site, the following set of commands can be used:

$ styx new site my-site (1)
$ cd my-site (2)
1 Initialize a new styx site in the my-site directory.
2 Enter the my-site directory.
3 Start hacking!

It is recommended to start by reading the site.nix section to get familiar on how site.nix is structured.

Sample site.nix configuration can be found in the themes examples directory.

4. Basics

Styx is using the Nix expression language. The Nix expression language is a lazy evaluated functional language with unconventional semantics.
It is recommended to read the Nix expression language chapter of the Nix manual to get more familiar with it.

4.1. Hello world!

Let’s look at a very basic example of a styx site.

Hello world!
{ lib, styx, runCommand, writeText, ... }: (1)

let (2)

  styxLib = import "${styx}/share/styx/lib" { (3)
    inherit lib; (4)
    pkgs = { inherit styx runCommand writeText; };
  };

  index = { (5)
    layout = template: "<html><body>${template}</body></html>"; (6)
    template = page: '' (7)
      <h1>Styx example page</h1>
      ${page.content}
    '';
    content = "<p>Hello world!</p>"; (8)
    href = "index.html"; (9)
  };

in (10)
  styxLib.generateSite { pagesList = [ index ]; } (11)
1 site.nix is a function written in the nix language. Nix functions have the { arg1 ? default, arg2, …​, argN, …​ }: body pattern.
The arguments of the function are the dependencies needed to build the site.
2 let is a special construction to declare local variables, a let block must finish by a in. let a = 1; b = 2; in a + b is a basic example of using let.
3 This declare a styxLib variable that holds the styx library. import is used to importing a file. ${styx}/share/styx/lib is a function and require an argument set.
4 inherit is a shorthand for writing sets, { inherit a; } is equivalent to { a = a; }.
5 This declare an index variable as an attribute set. An attribute set is a basic key-value structure. index will be the only page generated.
6 To generate a page, styx requires a few attributes to be set, namely layout, template and href. This line declares the layout attribute that is a function that take the template argument and return the page source.
template: form is different from the first point function head, this function use a simple parameter (Point one was using a deconstructed attribute set parameter).
7 This declare a template attribute. template is a function that takes the page attribute set, page in this case as a parameter and generate a result that will be passed to the layout function.
8 This declare a content attribute. This is not mandatory, and could have been integrated in the template key. But most of styx data fetchers will add a content attribute to the page set containing the fetched content.
9 This declare a href attribute. The href attribute is used to specify the path of the page to be generated.
10 The in mark the end of the let declaration, this means lib and index will be available in the next expression.
11 This generate the site by using the library generateSite function, its parameter is an attribute set with the argument pagesList being a list of the single index page.

Everything is ready, the "Hello world!" site preview can be generated.

Generating a preview of the "Hello world!" site
$ styx preview
Even if this is a simple example, nix language semantics can be confusing. In a nutshell to build a site, generateSite evaluates page.layout (page.template page) and output the result in page.href for every page in pagesList.
That is the reason layout, template and href are required attributes of a page set.
Nix expression language is lazily evaluated, so infinite data structures are not a problem (unless some code try to evaluate them).

4.2. Structure

In its simplest form, styx just needs a site.nix to generate a site like presented in the Hello world! example.

But the styx new command will generate a few more files for convenience.

├── conf.nix (1)
├── readme.md (2)
├── site.nix (3)
├── data/ (4)
└── themes/ (5)
1 conf.nix is the main configuration, see Configuration for details.
2 readme.md provides some basic information about how to start using styx.
3 site.nix is the main file for site generation, see [sitenix] for details.
4 data/ is an empty directory meant to hold site data.
5 themes/ is an empty directory meant to hold custom themes.
The file structure of styx is totally free and can be changed at will.
It is even possible to change the name of site.nix. In that case the --file flag of the styx command can be used to specify the file name.

4.3. site.nix

The site.nix used in the Hello world! example contains only enough code to generate a single page. It is likely that a site.nix to generate a normal site will contain more informations.

The extreme case is the showcase theme example site site.nix that use almost every feature available.

It is best practice to divide site.nix in multiple sections, with each section handling a particular topic.
It is common to use the following sections:

  • Init

  • Themes

  • Template environments

  • Data

  • Pages

  • Arguments preparation

  • generateSite

4.3.1. site.nix in a nutshell

site.nix is a function:

  • taking at least nixpkgs lib, styx, runCommand and writetext attributes.

  • returning the generateSite function.

generateSite is a function:

  • taking at least the list of pages set to generate as an argument.

  • that evaluate each page set with page.layout (page.template page) and output the result in page.href.

  • returning a generated static site.

generateSite is a wrapper for nixpkgs runCommand function.
Everything that is between the top function head and generateSite is meant to prepare the arguments for generateSite.

4.3.2. Init

This section is the basic setup of styx, it should not be changed and used as is for most setups.

Standard Init section
/*-----------------------------------------------------------------------------
   Init

   Initialization of Styx, should not be edited
-----------------------------------------------------------------------------*/

{ lib, styx, styx-themes, runCommand, writeText
, renderDrafts ? false
, siteUrl ? null
}@args:

let styxLib = import "${styx}/share/styx/lib" {
  inherit lib;
  pkgs = { inherit styx runCommand writeText; };
};
in with styxLib;

let

  /* Configuration loading
  */
  conf = let (1)
    conf       = import ./conf.nix;
    themesConf = lib.themes.loadConf themes;
    mergedConf = recursiveUpdate themesConf conf;
  in
    overrideConf mergedConf args;

  /* Load themes templates
  */
  templates = lib.themes.loadTemplates {
    inherit themes defaultEnvironment customEnvironments;
  };

  /* Load themes static files
  */
  files = lib.themes.loadFiles themes;
1 This loads the conf.nix file and merges it with theme configuration and main function siteUrl argument.

4.3.3. Themes

This section is where used themes are declared. Themes are a central concept in styx and provide ways to manage site assets in a flexible manner.

Themes are detailed in the Themes section.

Standard themes section
/*-----------------------------------------------------------------------------
   Themes setup

-----------------------------------------------------------------------------*/

  /* Themes used
  */
  themes = [ styx-themes.showcase ]; (1)
1 themes is a list so it is possible to set multiple themes at the same time to combine them. Themes at the beginning of the list have a higher priority.
Themes can be paths like ./themes/my-site or packages from the styx-themes set.

4.3.4. Template environments

Template environments control the set of variables available in the templates.

There are two types of environment:

  • Default: The environment used in every template that do not have a custom environment

  • Custom: Custom environment for a specific template

Normal sites should not require custom environments, but they can become useful in more complex setups.

Standard template environments section
/*-----------------------------------------------------------------------------
   Template environments

-----------------------------------------------------------------------------*/


  /* Default template environment
  */
  defaultEnvironment = { inherit conf templates data; lib = styxLib; }; (1)

  /* Custom environments for specific templates
  */
  customEnvironments = {}; (2)
1 This declare the default environment thet should feed most of needs.
2 Custom template environments are detailed in the template section.
defaultEnvironment refers to not yet declared variables, but it is not a problem as a let block allows to access any variable declared or that will be declared in it.

4.3.5. Data

The data section is responsible for loading the data used in the site.

The Data section explains in detail how to manage data.

Standard data section
/*-----------------------------------------------------------------------------
   Data

   This section declares the data used by the site
   the data set is included in the default template environment
-----------------------------------------------------------------------------*/

  data = {
    about  = loadFile { dir = ./pages; file = "about.md"; }; (1)
  };
1 Example of loading a markdown file with the loadFile function.

4.3.6. Pages

The pages section is used to declare the pages that will be generated by generateSite.
Even if generateSite expects a page list, it is usually declared as an attribute set for convenience.

There are multiple functions available to generate different type of pages, but a page is ultimately an attribute set with at least the layout, template and href attribute defined.

The Pages section explains in detail how to create pages.

Standard pages section
/*-----------------------------------------------------------------------------
   Pages

   This section declares the pages that will be generated
-----------------------------------------------------------------------------*/

  pages = {

    about = {
      href = "about.html";
      template = templates.generic.full;
    } // data.about; (1)

  };
1 // is the operator to merge attribute sets, this merge the data.about data attribute set in the pages.about page attribute set.
As many pages tends to use the same layout, the layout attribute is usually set in one go to all templates in the "arguments preparation" section.
Only pages that use a different layout usually explicitly set it in pages.

4.3.7. Argument preparation

This is the last part before generating the site. The only purpose of this section is to prepare the generateSite function arguments.

Standard argument preparation section
/*-----------------------------------------------------------------------------
   generateSite arguments preparation

-----------------------------------------------------------------------------*/

  pagesList = let
    # converting pages attribute set to a list
    list = pagesToList pages;
    # setting a default layout
    in map (setDefaultLayout templates.layout) list;

  substitutions = {
    siteUrl = conf.siteUrl;
  };

This section just turns the pages attribute set into a list of pages, and set a default layout to pages that did not declare one.

The substitution set should be declared in this section.

For details about substitutions see Substitutions.

4.3.8. generateSite

This is the final part and shortest section of site.nix. This section consists in a call to generateSite.

Standard generateSite section
/*-----------------------------------------------------------------------------
   Site rendering

-----------------------------------------------------------------------------*/

in generateSite { inherit files pagesList substitutions; }
files is automatically generated in the init section using enabled themes.
inherit is a shorthand for writing sets, { inherit a; } is equivalent to { a = a; }.

4.4. Configuration

Styx is configured with the conf.nix file present in the site root directory.

This files consists in an attribute set defining configuration options, and custom attributes can be added at will.

The main configuration is made through themes via the theme attribute. Every theme defines some set of configuration options that can be overridden in conf.nix theme attribute.

siteUrl is the only required field, and must not end with a slash.

Standard conf.nix
{
  # URL of the site, must be set to the url of the domain the site will be deployed
  siteUrl = "http://yourdomain.com";

  # Theme specific settings
  # it is possible to override any of the theme configuration settings in the 'theme' set
  theme = {
    # Changing the theme site.title setting
    site.title = "Styx Site";
  };
}

5. Command line interface

The Styx provides a command line program styx.

5.1. Generic flags

styx --help

Display the help message.

styx --version

Display the version.

5.2. Common flags

--in DIR

Run the command in DIR.

--file FILE

Use FILE instead of site.nix.

--drafts

Process and render drafts.

--show-trace

Show debug output when styx command fails. (Nix flag)

--arg NAME VALUE

Pass an argument NAME to site.nix main function.

--argstr NAME VALUE

Pass a string argument NAME to site.nix main function.

-I PATH

Add PATH to to the Nix expression search path, useful to use custom versions of nixpkgs.

5.3. New

The new command is used to create a site or a theme.

5.3.1. Site

The new site command is used to create a new Styx site.

styx new site NAME

Create a Styx site in NAME directory in current path.

styx new site NAME --in DIR

Create a Styx site in DIR/NAME.

5.3.2. Theme

The new theme command is used to create a new theme.

styx new theme NAME --in DIR

Create a theme skeleton in DIR/NAME.

5.4. Build

The build command is used to build a Styx site.

styx build

Build the Styx site and write the output in the public directory.

styx build --output DIR

Build the nix site and write the output in the DIR directory.

The nix-build --show-trace, --arg NAME VALUE, --argstr NAME VALUE and -I PATH flags can be used with the build command.

5.5. Preview

The preview command is used to launch a server that will list on localhost (127.0.0.1) port 8080 by default. The preview command will override conf.siteUrl to preserve links.

The server can be stopped by pressing Ctrl+C.

styx preview

Start a preview server on 127.0.0.1:8080.

styx preview --port 9090

Start a preview server on 127.0.0.1:9090.

styx preview --port 9090 --drafts

Start a preview server on 127.0.0.1:9090 with drafts rendered.

Drafts are rendered only if the related logic is present in site.nix. The --drafts flag just make styx pass renderDrafts as true to site.nix.

5.6. Live

The live command is similar to preview, with the unique difference that the site is automatically rebuilt when a change is made.

The live mode should be quitted by pressing q.

styx live

Start a live preview server on 127.0.0.1:8080.

styx live --port 9090

Start a live preview server on 127.0.0.1:9090.

styx live --port 9090 --drafts

Start a live preview server on 127.0.0.1:9090 with drafts rendered.

The live mode does not automatically reload the browser.
If the live mode is not quitted by pressing q, there is a possibility that the server process will stay alive in background. The server process can be found by running ps aux | grep caddy and killed with the kill command.

5.7. Manual

The manual command can be used to launch styx HTML documentation in the default browser ($BROWSER).

styx manual

Open the HTML help in the default browser.

BROWSER=firefox styx manual

Open the HTML help in firefox.

5.8. Serve

The serve command is used to build a site and launch a local server. This allow to check the site without having to deploy it. The server can be stopped by pressing Ctrl+C.

styx serve

Will serve on the localhost on port 8080.

styx-serve --port 9090

Will serve on the port 9090.

styx serve --detach

Will serve on the localhost on port 8080 and run the server on background, process can be found by running ps aux | grep caddy.

The nix-build --show-trace, --arg NAME VALUE, --argstr NAME VALUE and -I PATH flags can be used with the serve command.
Styx use the caddy server, even if it is performant server, styx serve launchs it without any special settings.
For production environments it is recommended to use a carefully configured server over styx serve.

5.9. Deploy

The deploy command is used to deploy A styx site on a remote server. Currently only GitHub pages are supported.

For more details see the Deployment section.

styx deploy --init—​gh-pages

Prepare a git repository to be able to deploy on GitHub pages.

styx deploy --gh-pages

Commit the Styx site to the gh-pages branch.

6. Themes

Themes are a central concept in styx and are used to manage a site assets, namely files and templates. They also provide a configuration interface.

Themes also can be combined to offer modularity and easiness of upgrade.

6.1. Getting themes

Styx themes are listed in the official theme repository.

Themes available at the moment of writing this documentation are:

  • Showcase: A theme that show most of styx functionalities and provides many templates.

  • Hyde: A port of the Jekyll Hyde theme to styx. Hyde is a simple and beautiful blog theme.

  • Agency: A port of the Hugo agency theme to styx. Agency is a single page site with a modern design fitting company or agency websites.

  • Orbit: A port of the Hugo orbit theme to styx. Orbit is a single page site resume / profile theme.

6.2. Using themes

Declaring used themes is done in the theme section of site.nix. Official themes can be used directly from the styx-themes package set.

Using a local my-site theme and the showcase theme
  themes = [ ./themes/my-site styx-themes.showcase ]; (1)

6.3. Structure

Themes are usually stored in the themes directory, or directly called from the styx-themes package set.

Every theme is stored in its own directory, and themes are expected to follow a certain structure.

Anatomy of a Styx theme
themes
└── NAME (1)
    ├── theme.nix (2)
    ├── files (3)
    └── templates (4)
1 Name of the theme. The name should be a valid directory name.
2 theme.nix defines the theme configuration options, this is file is required and must be named theme.nix.
3 files is a directory holding static files for the themes. All the files in this directory will be copied in the generated site.
4 templates is a directory storing all the templates files.
Themes structure is one of the few part using implicit settings in styx.

6.4. theme.nix

theme.nix defines the theme configuration interface. It is defined as an attribute set.

It is a simple attribute set that defines the theme configuration options with some default values.

Example of a theme.nix
{
  site = {
    title = "The Agency";
    author = "Your name";
    description = "Your description";
  };
}

theme.nix attribute set will be merged in site.nix conf variable in two attributes:

  • conf.theme: The global theme configuration, all the enabled themes configuration will be merged in this variable. This allow to extend theme configuration in conf.nix. Templates that access themes configuration should use conf.theme.

  • conf.themes.NAME: NAME is the theme name, this holds the theme default configuration as it is declared in theme.nix.

6.5. Files

The files directory holds the static files of the theme. Every file in in this directory will be copied in the generated site.

If multiple themes are enabled, every theme file directory contents will be copied to the generated site.

6.5.1. Special files

Styx automatically convert sass, scss and less files to css during site generation.

6.6. Templates

Every template in the templates directory will be accessible by its file basename in the templates attribute set. Directories are converted to nested sets.

Example of a template directory structure
├── archive.nix
└── post
    ├── full.nix
    └── list.nix
Generated attribute set
templates = {
  archive = <<lambda>>;
  posts = {
    full = <<lambda>>;
    list = <<lambda>>;
  };
};
the <<lambda>> notation is borrowed from the nix-repl tool, and means a non fully evaluated function.
The nix language is functional, and it allows to partially apply functions and to pass function as argument to other functions.

Styx templates are functions that return text or page attribute sets when fully evaluated.

Templates are divided in three types:

  • Layout templates, responsible for the final rendering of a page, it must return text. (page attribute set layout key)

  • Normal templates, responsible for preparing a page for the layout template, this kind of templates usually return a page attribute set.

  • Partial templates, responsible for rendering a part of a layout or a normal template.

The normal template evaluation flow is:

  • Normal templates evaluate the page attribute set and generates a partial result that is stored in the page attribute set content key.

  • Layout templates evaluate the page attribute set returned by the normal template and produce the final source of the page.

6.6.1. Text handling basics

Most of the work in template is done by manipulating text.

This introduce the basics of text handling in the templates:

  • single-line or multi-line text (leading spaces are stripped without changing relative line align), delimited by ''.

    Multi-line text
    ''
      Hello world!
      Hello Styx!
    ''
  • single-line or multi-line text, delimited by ".

    Single-line text
    "Hello world!"

Nix expressions can be included in text in enclosed in ${…​}.

Expression antiquotation
let name = "world"; in
"Hello ${name}!"

6.6.2. Layout templates

The layout template is responsible for rendering the final source of the page.
The layout template function usually takes a template environment, and a page attribute set with a content attribute.

In a HTML context, the layout template is usually responsible of the HTML code that is not directly related to the content, like the head tag contents.

Layout template example
env:
page:
''
  <html>
    ...
  <body>
    ...
    ${page.content}
    ...
  </body>
  </html>
''
Layout templates are just functions, in case the partial template return the full page source like in a rss feed case, it is possible to set the page layout to the id function. This will make the layout evaluation transparent and return the template result.

6.6.3. Normal templates

Normal templates are similar to the layout templates, with the only difference that their result will be evaluated by the layout template. A normal template should set or update the content attribute of a page attribute set so the layout template can produce the final source.

Normal templates can also add other attributes to the page attribute to fit any special need.

Example of a partial template
{ templates, ... }:
page:
let
  content =
    ''
      <h1>${page.title}</h1>
    '';
in
  page // { inherit content; }
In some cases, it is useful to have the partial template to return the final source of the page.
By setting the page layout to the id function, it is possible to bypass the layout template and have the partial template result being the final source source of the page.

6.6.4. Partial templates

Partials templates are templates that that are used in normal or layout templates.

Partial templates can take arguments and be used to with mapTemplate to apply a template to a list of content, or just used as includes.

6.6.5. Template environment

The template environment is the first parameter to every template function.

It is automatically set when the templates are loaded from a theme.

The default template environment consists in:

  • conf: The configuration attribute set.

  • lib: The library attribute set, it contains Styx and nixpkgs functions.

  • templates: The templates attribute set.

  • data: The data attribute set.

  • pages: The pages attribute set.

The template environment is set in site.nix and can be easily modified upon needs.

It is possible to set a specific template environment to a specific template by declaring it in the customTemplateEnvironments set.

Setting custom template environments
  customEnvironments = {
    layout = defaultEnvironment // { foo = "bar"; }; (1)
  };
1 The environment passed to the layout template is the default environment extended with a foo variable.

6.6.6. Template environment in templates

There are two ways of writing the environment in the template, as a set or as a deconstructed set.

Environment as a variable
environment: (1)
page:
''
  ${environment.conf.siteTitle}
''
1 environment is used as a set, and its key can be accessed with ..
Environment as a deconstructed set
{ conf, lib, ... }: (1)
page: (1)
''
  ${conf.siteTitle}
''
1 environment is deconstructed in its keys values. The last …​ means all others keys and is required if the set contains more keys than the keys deconstructed.

6.6.7. Calling templates in templates

It is possible to call templates in a template by accessing to the templates attribute of the template environment.

Calling a template in a template
{ templates, ... }:
page:
''
  ${templates.foo}
''
When templates are loaded, they will automatically receive the template environment as a parameter, this will partially evaluate the template function. This means that the template function will be become a single argument function (page).
Trying to call the current template will trigger an infinite loop and make the site generation fail.

6.6.8. Applying templates to multiple contents

The mapTemplate function can be used to map a template to a list of contents.

Applying a template to multiple contents
{ templates, ... }:
page:
''
  ${mapTemplate templates.post.list page.posts}
''

6.7. Themes in site.nix

Themes are declared as a list in the themes variable.

Declaring used themes
  themes = [ styx-themes.showcase ]; (1)
1 The themes variable is a list of theme packages or paths, it is possible to set multiple themes. In that case, themes at the head of the list will have a higher priority.

Themes related files are automatically loaded in site.nix via the lib.themes.loadTemplates and lib.themes.loadFiles functions.

Loading theme related files
  templates = lib.themes.loadTemplates { (1)
    inherit themes defaultEnvironment customEnvironments;
  };

  files = lib.themes.loadFiles themes; (2)

  themes = [ styx-themes.showcase ];
1 Load themes templates. See loadFiles for details.
2 Load themes files. See loadTemplates for details.

6.8. Combining Themes

In site.nix, themes are declared as a list. If multiple themes in the list provide the same file or template, the one from the first theme to declare it will be used.

This allows to "extends" themes without modifying them.

For example, to use the showcase theme but only change the layout template. It is possible to create a new theme, and copy the layout.nix template in the new theme templates directory and change only this file.

Creating a new foo theme
$ styx new theme foo --in themes (1)
$ cp $(nix-build -A styx-themes.showcase '<nixpkgs>')/templates/layout.nix themes/foo/templates/layout.nix (2)
1 Create the theme directory.
2 Copying showcase theme layout.nix to the foo theme.

After a new theme has been created, it must be declared in site.nix to be used.

Using foo and showcase themes in site.nix
  themes = [ ./themes/foo styx-themes.showcase ]; (1)
1 Using foo and showcase theme, with foo having a higher priority than default.
Combining themes is the recommended way to extend an existing theme as it make theme upgrades easier.

7. Data

Data refers to the data fetched or declared in the data section of site.nix.

Data gets included in the default template environment and can also be used in the pages section of site.nix to attach data to pages.

7.1. Creating data

Data can be created by directly defining a nix data structure.
An example of such usage is the navbar items that are declared as a list of page attributes sets.

Creating navbar data
  data.navbar = [ pages.about pages.contact ];

7.2. Importing data

The styx data sub-library provides functions two functions to import markup data:

  • loadFile: load a single data file and return it as an attribute set.

  • loadDir: to load all the files in a directory and return them as a list of attributes set.

The data loading functions return a set per file loaded and do a few things:

  • A fileData field is added that contains the file data as an attribute set with the following keys:

    • basename: The base name of the file.

    • ext: The extension of the file.

    • dir: The directory of the file.

    • name: The name of the file, basename and ext field combined with a ..

  • Metadata is automatically parsed and merged to the set.

  • Data with introduction gain a intro attribute containing the introduction.

  • Multipages data gain a subpages attribute, a list containing each page content.

  • Converted markup is inserted in a content attribute.

  • If the file basename begins in a YYYY-MM-DD format, this value will be inserted in a date attribute.

Nix data should be imported with the import function, that return the data in the nix file as it is.

7.3. Formats

This section present the data file formats supported by styx.

7.3.1. Asciidoc

AsciiDoc is a simple but complete markup language.

It is the format of choice for complex posts or pages as it has more functionalities than markdown.

AsciiDoc example
= Lorem ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean dapibus aliquet justo ac lacinia.

The converted html will be in the content attribute of the data attribute set.

It is possible to add extra data to an asciidoc file by using Metadata.
Asciidoctor is used to convert asciidoc.

7.3.2. Markdown

Markdown is a lightweight markup language.

It is the format of choice for posts or pages as it allows to write content in a simple manner.

Markdown example
# Lorem ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean dapibus aliquet justo ac lacinia.

The converted html will be in the content attribute of the data attribute set.

It is possible to add extra data to a markdown file by using Metadata.
MultiMarkdown is used to convert markdown.

7.3.3. Nix

Nix expression language is the language used in site.nix and in every template.

It is a simple functional language and fits well data that has multiple fields.

Nix data
[
  { name = "Alice"; interests = [ "science" "writing" ]; }
  { name = "Bob";   interests = [ "sports" "reading" ]; }
]

Markup with metadata and nix data structures can be considered equivalent as it is possible to declare fields in nix data as markdown text, and markdown can declare nix fields as metadata.

Which one to choose is really a matter of choice but:

  • Nix is well suited for complex data structures with multiple fields.

  • Markup is well suited do content centric data.

7.4. Metadata

Metadata is the way to attach Nix data to markup files.

A metadata block is a Nix attribute set which opening is {--- and closing ---}.

Adding metadata to a markdown file
{---
date = "2016-10-10";
tags = [ "foo" "bar" ];
---}

# Lorem ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean dapibus aliquet justo ac lacinia.

Metadata attributes will automatically be added to the data attribute set.

7.5. Introduction

It is possible to declare a section on an imported markup file as the introduction.

Introduction and main contents are separated by >>>, content prior the separator will be inserted in the intro attribute.

Adding an introduction to a markdown file
Lorem ipsum dolor sit amet, consectetur adipiscing elit.

>>>

# Lorem ipsum

Mauris quis dolor nec est accumsan dictum eu ut nulla. Sed ut tempus quam, vel bibendum lacus. Nulla vestibulum velit sed ipsum tincidunt maximus.
intro field contents are included in the content field.

7.6. Multipage data

It is possible to split markup file in many subpages by using the <<< separator.

Splitting a markdown file in 3 pages
# Lorem ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean dapibus aliquet justo ac lacinia.

<<<

# Cras malesuada metus

Cras malesuada metus quis mi pulvinar faucibus. Vivamus suscipit est ante, ut auctor tortor semper nec.

<<<

# Phasellus consequat

Phasellus consequat a nibh sit amet ultricies. Quisque feugiat justo eu condimentum convallis.

The resulting data set will have an extra subpages field that will hold the list of subpages content.

The data section is only responsible for generating the data attribute set. Transforming the data attribute sets in a page attribute sets is handled by the pages section.
For example, the mkPagesList or mkMultipages function can generate pages from a multipage data set.

7.7. Taxonomies

7.7.1. Overview

Taxonomies are a way to group and structure data.

Styx taxonomies are a two layers grouping system, taxonomies and terms.
The taxonomy layer group the content declaring a specific data attribute, and the term layer group the contents in the taxonomy depending of the values set to that specific attribute.

A common example of taxonomy is tags, tags will be the taxonomy and sports or technology will be the terms.

Taxonomy are organized in the following structure:

  • Taxonomy: Name of the grouping characteristic, for example tags.

  • Term: Groups in the taxonomy, for tags it will the values tags can take, for example sports or technology.

  • Values: Objects grouped by a taxonomy term, for example all the posts with the technology tag.

7.7.2. Creating a taxonomy data structure

A taxonomy data structure is created with the mkTaxonomyData function.
This function take a set parameter with two required attributes data and taxonomies.

taxonomies

A list of taxonomy fields to look for into data.

data

The list of attribute sets (usually pages attribute sets) to where the taxonomy field will be looked for.

Creating a taxonomy structure
  data.taxonomies = mkTaxonomyData {
                      data = pages.posts;
                      taxonomies = [ "tags" "categories" ];
                    };

This will generate a taxonomy data structure where:

  • tags and categories are taxonomies.

  • terms would be all the values of tags or categories set in pages.posts.

  • values would be all the pages in the pages.posts declaring tags or categories.

Then, the taxonomy related pages can be generated in the page section using the mkTaxonomyPages function.

This example use pages and not data attribute sets because data attribute sets do not have a href field making it impossible to generate links to them.
Using data attribute sets such as data.posts would make it impossible to generate pages from the taxonomy with mkTaxonomyPages.

The taxonomy data structure uses property lists, lists of attribute sets with a single key, for easier data manipulation.

Taxonomy data structure
[
  {
    TAXONOMY1 = [
      { TERM1 = [ VALUE1 VALUE2 ... ]; }
      { TERM2 = [  ... ]; }
      ...
    ];
  }
  {
    TAXONOMY2 = [
      { TERM1 = [ VALUE1 VALUE2 ... ]; }
      { TERM2 = [  ... ]; }
      ...
    ];
  }
]

7.7.3. Adding taxonomy to data

Adding taxonomy fields to a content consists in adding a metadata attribute with taxonomy name containing a list of terms.

Setting tags to a markdown file
{---
  tags = [ "foo" "bar" ];
---}

# Lorem ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean dapibus aliquet justo ac lacinia.
Terms must be a list of strings.

8. Pages

Pages refer to the pages declared in site.nix.

Pages are declared in a pages an attribute set. Every page or list of pages declared in this set will be generated.

8.1. Overview

Pages get passed to the generateFunction that turn each page into a text file in the generated site.

Pages are usually generated as html documents, but any kind of text file can be generated from a page attribute set.

8.2. The page attribute set

The page attribute set is an attribute set that must defines at least three attributes:

  • layout: A function that take the template result as a parameter and return the source of the file to generate.

  • template: A function that take the page attribute set as a parameter and returns an updated attribute set.

  • href: The path of the page to generate.

This is the strict minimum and most of templates will require extra attributes like content or title.

Hello world! contains an example of a simple page attribute set.

Simple page attribute set
pages.index = {
  layout = template: "<html><body>${template}</body></html>";
  template = page: "<h1>Hello world!</h1>";
  href = "index.html";
};

In a normal site.nix, the template would be an attribute from the templates set like templates.generic.full.

Page attribute sets are usually augmented by various attributes or merged with data sets to fit any needs.

generateSite evaluate page.layout (page.template page) and output the result in page.href for every page in its pagesList argument.
As many pages tends to use the same layout, the layout attribute is usually set in one go to all templates in the "arguments preparation" section.
Usually, only pages that use a different layout explicitly declares it in pages.
The following examples will omit the layout like done in a normal site.nix.

8.3. Simple pages

Generating a simple page is trivial as it is just declaring the required attributes.

Creating an error 404 page
pages.e404 = {
  href     = "404.html";
  template = templates.e404;
};
Attribute set attributes should not start with a number. That is why the 404 template is templates.e404 and not templates.404.
Nix allow to use attributes starting with a number, but they must be called by using ". This is error prone and not used in styx.

8.4. Attaching data to a page

Generating a page from an imported data is a very common case, and is easy to achieve.

Attaching a data set to a page attribute set.
pages.about = {
  href = "about.html";
  template = templates.generic.full;
} // data.about;

The // operator will merge the data.about data set in the about page set.

8.5. Bypassing the layout

For pages which the template generate the full page source like for RSS feeds, applying a layout is not needed.
In such cases, the id function, a function that return its parameter without changing it can be used as a layout.

Using id as a layout
pages.feed = {
  href = "feed.xml";
  template = templates.feed;
  posts = take 10 posts;
  layout = id;
};
The id function is defined as x: x.

8.6. Split pages

Split pages refers to a list of data split though multiple similar pages.

A common example of split page is a blog archive page, the full list of blogs are split in many pages.

Split pages can be generated with the mkSplit or mkSplitCustom function.
mkSplit being a simpler version of mkSplitCustom function that should fit most of needs.

mkSplit example
pages.archives = mkSplit {
  baseHref = "archives";
  template = templates.archives;
  itemsPerPage = 5;
  data = pages.posts;
};

This will create a list of pages attribute sets with the following extra attributes:

href

Set accordingly to baseHref. baseHref.html for the first page, and baseHref-i.html for the following pages where i is the index of the page.

items

The list of items for this page.

index

The position of this page in the list of split pages.

pages

The split pages lists, useful for generating a pagination.

For more complex splitting needs see the mkSplitCustom function documentation.

mkSplit only requires baseHref, itemsPerPage and data as parameters. Any extra parameter passed will be added to every split page attribute set.
This is on purpose and is used in the previous example to set all the split pages template in the mkSplit declaration.

8.7. Multipages

Multipages are page attribute sets that have a subpages attribute containing a list of subpages content.

Multipages are usually generated by importing Multipage data.

Mulipage pages are referred as:

  • all: The full subpages list.

  • head: First page in the subpages list.

  • tail: All the subpages, but the first.

8.7.1. Single pages

Multipages can be generated with the mkMultipages function.

mkMultipages example
pages.about = mkMultipages ({
  template = templates.generic.full-multipage;
  baseHref = "about";
} // data.about);
mkMultipages only requires baseHref and subpages as parameters. Any extra parameter passed will be added to every generated attribute attribute set.

8.7.2. Pages in a list

For a list of pages that might contains multipages, the problem get a little different.

If mkMultipages is naively used, every subpage will end up in the page list, and it is not what is expected most of the time.

If we have a list of posts, and some are multipages, we want the pages.posts list of pages to include single page posts and the first page of the any multipage post.
That way, multipage post subpages will not end up in posts archives or in the RSS feed.

So for multipages in a list, the generation will be separated in two steps.

  1. First generate the page list with single page data and multipage first page data.

  2. Generate the multipage subpages data.


First step, generate the page set list with single page data and multipage first page data.

This could be done using mkMultipages and filtering / mapping, but a mkPageList function is available and do exactly that.

Generating the page list with multipage head pages
pages.posts = mkPageList {
  data = data.posts; (1)
  multipageTemplate = templates.post.full-multipage; (2)
  template = templates.post.full;
};
1 data is a list of data attribute set to generate pages attribute set from.
2 multipageTemplate is the template that will be used for data set that have a subpages field.

mkPageList will loop through data and if it finds a multipage, render only the first page (head) attribute set setting its template to multipageTemplate template.


Next step is to generate the tail of the multipages posts.

mkMultitail is the function to generate page sets for the tail of multipages in a list of data sets.

Generating the multipage posts tail
pages.multiPostsTail = mkMultiTail {
  data = data.posts;
  template = templates.post.full-multipage;
};

This is very similar to the mkPageList function but only tail pages sets are generated. As only tail pages are rendered, the template is directly set with the template attribute.

It is possible to set a prefix to the generated href attribute of mkPageList and mkMultiTail function with the hrefPrefix argument.
If the baseHref argument is set, it must be the same for the same data set, else the links between head and tail pages will be broken.

8.8. Taxonomy pages

To see how to generate taxonomy data, refer to Taxonomies.

Taxonomies pages can be generated from a taxonomy data structure with the mkTaxonomyPages function.

  taxonomies = mkTaxonomyPages {
    data = data.taxonomies;
    taxonomyTemplate = templates.taxonomy.full;
    termTemplate = templates.taxonomy.term.full;
  };

The mkTaxonomyPages function will create the following page attribute sets:

  • TAXONOMY/index.html, the taxonomy index page set for every taxonomy. A terms attribute will be added to the page attribute set containing all the taxonomy terms.

  • TAXONOMY/TERM/index.html, the term index page set for every term in every taxonomy. A values attribute will be added to the page attribute set containing all the values that use the term.

If required mkTaxonomyPages generated pages href can be changed with the taxonomyHrefFun and the termHrefFun, for details see mkTaxonomyPages.
If any of these functions is changed, the templates should be updated accordingly.

9. Site Generation

Site generation is the final section of site.nix.

It mainly consists in a call to generateSite, and the preparation of its arguments.

9.1. Substitutions

Subtitutions are a way to use some variables in markup files or static files.

Substitutions are a set that is passed to the generateSite. Any value of this set can be replaced will be replaced in text files that generateSite outputs.

To be replaced, the variable as to be surrouded by @, for example @siteUrl@.

Simple substitution set
{
  siteUrl = conf.siteUrl;
}
Using a substitution in a markdown file
Learn more in the [Styx 0.1.0 Documentation](@siteUrl@/documentation-v0-1-0.html).
Using a substitution in a css file
background: url(@siteUrl@/images/foo.png);
Substitutions are specially useful for resolving in-site links with conf.siteUrl, but they can also be used with sass or less to externalize css variables in conf.nix.

9.2. Special files

Styx automatically convert sass, scss and less files to css during site generation.

9.3. Hooks

generateSite provide two hooks to customize the site generation process:

  • preGen: A string or multiline string with shell commands to run before generating the site.

  • postGen: A string or multiline string with shell commands to run after generating the site.

10. Deployment

10.1. GitHub pages

Styx support basic deployment to GitHub pages.

This is a two step process:

  • first by preparing the repository to deploy on GitHub pages. (deploy --init-gh-pages)

  • then by updating that branch. (deploy --gh-pages)

10.1.1. Initialization

styx deploy --init-gh-pages command will prepare the repository for GitHub deployment. This command will do the following:

  • create a gh-pages directory

  • add the gh-pages folder to .gitignore

  • clone the repository in the gh-pages folder

  • create a new empty gh-pages branch in the gh-pages folder

10.1.2. Update the gh-pages branch

styx deploy --gh-pages command will build the site, and update the gh-pages folder folder with the generated static site and commit it to the gh-pages branch.

10.2. NixOps

NixOps is a deployment tool for NixOS configurations, and can be used to deploy styx sites.

NixOps expression to deploy a styx website
{
  network.description = "Styx example";

  webserver = { config, pkgs, ... }: { (1)
    deployment = { (2)
      targetEnv = "virtualbox";
      virtualbox.memorySize = 1024;
      virtualbox.headless = true;
    };

    networking.firewall.allowedTCPPorts = [ 80 ]; (3)

    services.nginx = { (4)
      enable = true;
      httpConfig = ''
        server {
          listen 80;
          location / {
            root ${pkgs.callPackage ./site.nix {}}; (5)
          }
        }
      '';
    };
  };
}
1 Creating a machine named webserver to the deployment.
2 Set up deployment information, this example deploy on a VirtualBox machine.
3 Opening the port 80 on the webserver machine.
4 Nginx settings.
5 Setting Nginx root location to the styx site package. Remote repositories can be fetched with nixpkgs fetch* functions.
The NixOps manual provide information about all the deployment options.

A styx website can be deployed via NixOps with the following set of commands:

$ nixops create -d styx-site nixops-expression.nix (1)
$ nixops deploy -d styx-site (2)
1 This command create a new NixOps deployment, the -d flag specify the deployment name.
The deployment information can be queried with the nixops info -d styx-site.
nixops-expression.nix is a file containing the nix expression for the deployment like the one showed in the example.
2 This command will create the VirtualBox machine and deploy the configuration into it.
If all goes well, the website will be available by opening the deployment machine in a browser. The deployement machine IP can be found with the nixops info -d styx-site.

10.3. Other

Styx does not yet provide a universal deployment method, but rsync can be used to deploy a Styx site to a remote server via ssh.

11. Library

The library contains various functions that are used through site.nix and templates. The functions are grouped in namespaces, but are also all included in the top-level scope to be used in an easy way.

11.1. Themes

This namespace contains functions related to themes.


loadConf

Description

Load themes configuration.

Parameter Type

Standard

Parameters
  • themes: A list of themes paths or packages to load configuration from.

Return

A configuration attribute set with the theme and themes attributes.
theme is the merged themes configuration, and themes.THEME holds the per theme default configuration.

Example
themesConf = styxLib.themes.loadConf themes;

loadFiles

Description

Load themes static files.

Parameter Type

Standard

Parameters
  • themes: A list of themes paths or packages to load configuration from.

Return

A list of directory paths.

Example
files = styxLib.themes.loadFiles themes;

loadTemplates

Description

Load themes templates.

Parameter Type

Attribute Set

Parameters
  • themes: A list of themes paths or packages to load configuration from.

  • defaultEnvironment: The default template environment.

  • customEnvironments: (optional) A set which attributea are template paths and the values template environments.

Return

An attribute set containing all the themes template with their environment applied.

Example
templates = styxLib.themes.loadTemplates {
  inherit themes defaultEnvironment customEnvironments;
};

11.2. Template

The template namspace contains functions useful in templates.


htmlAttr

Description

Create html tag attributes.

Parameter Type

Standard

Parameters
  • attrName: Tag attribute to generate.

  • value: Value of the attribute to generate, can be a string or a list of strings.

Return

A string of the attribute.

Example
htmlAttr "class" [ "foo" "bar" ]
Results in
class="foo bar"

isExternalHref

Description

Checks whether a strings starts with http.

Parameter Type

Standard

Parameters
  • href: The href to check.

Return

true if href starts with http, false if not.

Example
isExternalHref item.href

generatorMeta

Description

Generate a meta generator tag for Styx.

Return

<meta name="generator" content="Styx" />

Example
generatorMeta

mapTemplate

Description

Map a template function to a list of items and returns the result as a string.

Parameter Type

Standard

Parameters
  • templateFunction: A template or a function that take a single argument and returns a string.

  • items: A list of items to apply the template to.

Return

The result of the template applied to every item as a string.

Example
mapTemplate templates.post.list page.items

mapTemplate can and is often used with functions that acts like a template.

Using a function with mapTemplate
mapTemplate (i: "<li>${i}</li>") [ "foo" "bar" ]
Results in
<li>foo</li>
<li>bar</li>

mapTemplateWithIndex

Description

Similar to mapTemplate but pass a parameter to the template function that corresponds to the index of the item.

Parameter Type

Standard

Parameters
  • templateFunction: A template or a function that take the index and the item and returns a string.

  • items: A list of items to apply the template to.

Return

The result of the template applied to every item as a string.

Example
mapTemplateiWithIndex (index: item:
  "<li>${index} - ${item}</li>"
) [ "foo" "bar" ]
Results in
<li>1 - foo</li>
<li>2 - bar</li>

mod

Description

Returns the modulo of a number.

Parameter Type

Standard

Parameters
  • dividend: The dividend of the modulo.

  • divisor: The divisor of the modulo.

Return

The modulo.

Example
mod 3 2
Results in
1

isEven

Description

Check if a number is even.

Parameter Type

Standard

Parameters
  • number: The number to check.

Return

true if number is even, false if not.

Example
isEven 2
Results in
true

isOdd

Description

Check if a number is odd.

Parameter Type

Standard

Parameters
  • number: The number to check.

Return

true if number is odd, false if not.

Example
isOdd 2
Results in
false

parseDate

Description

Parse a date.

Parameter Type

Standard

Parameters
  • date: A date in the format YYYY-MM-DD, e.g. 2012-12-21.

Return

An attribute set containing date parts.

Example
with (parseDate "2012-12-21"); "${D} ${b} ${Y}"
Results in
21 Dec 2012

parseDate returns a set with the following attributes:

YYYY

The year in 4 digit format (2012).

YY

The year in 2 digit format (12).

Y

Alias to YYYY.

y

Alias to YY.

MM

The month in 2 digit format (12, 01).

M

The month number (12 ,1).

m

Alias to MM.

m-

Alias to M.

B

Month in text format (December, January).

b

Month in short text format (Dec, Jan).

DD

Day of the month in 2 digit format (01, 31).

D

Day of the month (1, 31).

d-

Alias to D.


11.3. Data

The data namespace contains functions related to the data set and data formats.


loadDir

Description

Load a directory containing data that styx can handle.

Parameter Type

Attribute Set

Parameters
  • dir: The directory as a nix path.

Return

A list of data sets.

Example
data.drafts = loadDir {
  dir = ./drafts;
  isDraft = true;
});

Any extra arguments to loadDir will be forwarded to every generated data set.

Setting isDraft to every file in a folder
data.drafts = loadDir {
  dir = ./drafts;
  isDraft = true;
};
loadDir will print a warning for every file in the directory it cannot import.

loadFile

Description

Load a file in a format that Styx can handle.

Parameter Type

Attribute Set

Parameters
  • dir: The directory as a nix path.

  • file: The file name to load as a string.

Return

The loaded file data set.

Example
data.about = loadFile {
  dir  = ./pages;
  file = "about.md";
};

Any extra arguments to loadFile will be forwarded to the generated data set.

Setting isDraft to a file
data.drafts = loadFile {
  dir = ./drafts;
  file = "file.md";
  isDraft = true;
};

asciidocToHtml

Description

Convert an asciidoc string to html text.

Parameter Type

Standard

Parameters
  • string: A string in asciidoc format.

Return

string converted to html.

Example
asciidocToHtml "link:https://en.wikipedia.org/wiki/AsciiDoc[AsciiDoc] is fun!"
Results in
<div class="paragraph">
<p><a href="https://en.wikipedia.org/wiki/AsciiDoc">AsciiDoc</a> is fun!</p>
</div>

markdownToHtml

Description

Convert a markdown string to html text.

Parameter Type

Standard

Parameters
  • string: A string in markdown format.

Return

string converted to html.

Example
markdownToHtml "[Markdown](https://en.wikipedia.org/wiki/Markdown) is fun!"
Results in
<p><a href="https://en.wikipedia.org/wiki/Markdown">Markdown</a> is fun!</p>

mkTaxonomyData

Description

Generate a taxonomy data structure.

Parameter Type

Attribute Set

Parameters
  • data: A list of attribute sets to generate the taxonomy data structure from.

  • taxonomies: A list of taxonomies to generate the taxonomy data.

Return

A taxonomy data structure as a property list.

Example
data.taxonomies.posts = mkTaxonomyData {
  data = pages.posts;
  taxonomies = [ "tags" "level" ];
};
Taxonomies are treated in detail in the Taxonomies section.

sortTerms

Description

Sort a list of taxonomy terms by the number of values they hold.

Parameter Type

Standard

Parameters
  • terms: A list of taxonomy terms to sort.

Return

The sorted list of terms.

Example
sortTerms terms

valuesNb

Description

Return the number of values a taxonomy term holds.

Parameter Type

Standard

Parameters
  • term: A taxonomy term.

Return

The number of values the term holds.

Example
sortTerms terms

11.4. Pages

The pages namespace contains functions related to the pages set.


mkSplit

Description

Generate a list of page attributes set by splitting a list of data attribute sets.

Parameter Type

Attribute Set

Parameters
  • baseHref: The base href set to the pages set, the first page href is baseHref.html, following pages href is baseHref-index.html where index is the number of the page.

  • itemsPerPage: The number of items per page set.

  • data: The list of data attribute set to split between the pages.

Return

A list of data / itemsPerPage page attribute set with the href set accordingly to baseHref.

Example
pages.archives = mkSplit {
  baseHref = "archives";
  itemsPerPage = 10;
  data = pages.posts;
};

Any extra arguments to mkSplit will be forwarded to every generated page set.

Set a template with mkSplit
pages.archives = mkSplit {
  baseHref = "archives";
  itemsPerPage = 10;
  data = pages.posts;
  template = templates.archives;
};
For details see the Split pages section.

mkSplitCustom

Description

A more customizable version of mkSplit.

Parameter Type

Attribute Set

Parameters
  • data: The list of data attribute set to split between the pages.

  • head: The settings for the first splitted page.

    • itemsNb: The number of items to display on the first page.

  • tail: Setting for the following pages.

    • itemsNb: The number of items to display per page.

    • baseHref: The base href set to the pages, the href is baseHref-index.html where index is the number of the page.

Return

A list of page attribute set according to the arguments.

Example
pages.archives = mkSplitCustom {
  head = {
    itemsNb = 5;
    template = templates.archives.first;
  };
  tail = {
    itemsNb = 5;
    template = templates.archives.next;
  };
  data = pages.posts;
};

Any extra arguments to mkSplit will be forwarded to every generated page set.
Any extra arguments to head will be forwarded to the first page set.
Any extra arguments to tail will be forwarded to the rest of pages.

For details see the Split pages section.

mkMultipages

Description

Create the list of page set for multipages data set.

Parameter Type

Attribute Set

Parameters
  • subpages: The list of subpages source.

  • baseHref: The base href set to the pages set, the first page href is baseHref.html, following pages href is baseHref-index.html where index is the number of the page.

  • output: all, head or tail. This select which pages set to generate.

Return

A list of page attribute set according to the arguments.

Example
pages.about = mkMultipages ({
  template = templates.generic.full-multipage;
  baseHref = "about";
} // data.about);
Any extra arguments to mkMultipages will be forwarded to every page set.
For details see the Multipages section.

mkPageList

Description

Generate a list of pages attribute sets from a list of data set, but generates only the first page of multipages data set. For a use case see Multipages.

Parameter Type

Attribute Set

Parameters
  • data: The list of data attribute set to use.

  • hrefPrefix (optional): A prefix string to add to the generated page set href.

  • multipageTemplate: The template used for multipage data sets.

Return

A list of page attribute set according to the arguments.

Example
pages.posts = mkPageList {
  data = data.posts;
  hrefPrefix = "posts/";
  template = templates.post.full;
  multipageTemplate = templates.post.full-multipage;
};

Any extra arguments to mkPageList will be forwarded to every generated page set.

For details see the Multipages section.
For the same data set list, baseHref set in mkPageList and in mkMultiTail must be the same.

mkMultiTail

Description

Generate a list of multipages subpages tail page attribute sets from a list of data set. For a use case see Multipages.

Parameter Type

Attribute Set

Parameters
  • data: The list of data attribute set to use.

  • hrefPrefix (optional): A prefix string to add to the generated page set href.

Return

A list of page attribute set according to the arguments.

Example
pages.postsMultiTail = mkMultiTail {
  data = data.posts;
  hrefPrefix = "posts/";
  template = templates.post.full-multipage;
};

Any extra arguments to mkMultiTail will be forwarded to every generated page set.

For details see the Multipages section.
For the same data set list, baseHref set in mkPageList and in mkMultiTail must be the same.

mkTaxonomyPages

Description

Generate the taxonomy related pages for the data list of data sets.

Parameter Type

Attribute Set

Parameters
  • data: The list of data attribute set to use.

  • taxonomyTemplate: The template to use for taxonomies page sets.

  • termTemplate: The template to use for terms page sets.

  • taxonomyHrefFun (optional): A function to generate the href of the taxonomy page.

  • termHrefFun (optional): A function to generate the href of the taxonomy term page.

Return

A list of page attribute set according to the arguments.

Example
pages.postTaxonomies = mkTaxonomyPages {
  data = data.taxonomies.posts;
  taxonomyTemplate = templates.taxonomy.full;
  termTemplate = templates.taxonomy.term.full;
};
Default taxonomyHrefFun
taxonomy: "${taxonomy}/index.html"
Default termHrefFun
taxonomy: term: "${taxonomy}/${term}index.html"
Changing taxonomyHrefFun or termHrefFun will require to also update the taxonomy related template links.
For details see the Taxonomies section.

setDefaultLayout

Description

Set a layout attribute to a page attribute set if does not have any set.

Parameter Type

Standard

Parameters
  • layout: The layout template.

  • page: The page attribute set to set the layout to.

Return

Return a page attribute set with the layout attribute.

Example
setDefaultLayout pages.about templates.layout
This function is mainly used during generateSite argument preparation.

11.5. Generation

The generation namespace contains functions related to the site generation.


generateSite

Description

Generate a static site.

Parameter Type

Attribute Set

Parameters
  • pagesList (optional): A list of page attribute sets to generate.

  • files (optional): A list of folders. All the contents of the folders in this list will be copied to the generated site root.

  • substitutions (optional): A substitution set to apply on every generated text file.

  • preGen (optional): A list of shell commands to run before the site is generated as a string or multiline string.

  • postGen (optional): A list of shell commands to run after the site is generated as a string or multiline string.

Return

The generated static site.

Example
generateSite { pagesList = [ pages.index ]; }

pagesToList

Description

Convert the pages attribute set to a list of pages attribute sets.

Parameter Type

Standard

Parameters
  • pages: The pages attribute set.

Return

A list of pages attribute sets.

Example
pagesList = pagesToList pages;

11.6. Utils

The utils namespace contains generic functions that do not fit in other namespaces.


overrideConf

Description

Override the conf attribute set with another attribute set.

Parameter Type

Standard

Parameters
  • conf: The conf attribute set.

  • override: The attribute set to override conf with.

Return

The attribute set with conf and override merged.

Example
overrideConf mergedConf args
This is similar to the nixpkgs recursiveUpdate function, with the only difference that keys that do not exist in conf are ignored.

chunksOf

Description

Split a list in lists multiple lists of n items.

Parameter Type

Standard

Parameters
  • n: The number of items per list.

  • list: the list to split.

Return

A list of lists.

Example
chunksOf 2 [ 1 2 3 4 5 ]
Results in
[ [ 1 2 ] [ 3 4 ] [ 5 ] ]

sortBy

Description

Sort a list of attribute sets by an attribute value.

Parameter Type

Standard

Parameters
  • attribute: The attribute to use for sorting.

  • order: asc for ascding order, or dsc for descending order.

  • list: the list of attribute sets to sort.

Return

The sorted list of attribute sets.

Example
sortBy "priority" "asc" [ { priority = 5; } { priority = 2; } ]
Results in
[ { priority = 2; } { priority = 5; } ]

11.7. Proplist

The proplist namespace contains functions to manipulate property lists, list of attribute set with only one attribute.

Property lists are used in the taxonomy data structure.

Example of a property list
[ { name = "Alice"; } { age = 26; } ]

propValue

Description

Get the value of a property.

Parameter Type

Standard

Parameters
  • property: A property.

Return

The value of the property.

Example
propValue { name = "Alice"; }
Results in
Alice

propKey

Description

Get the key of a property.

Parameter Type

Standard

Parameters
  • property: A property.

Return

The value of the key.

Example
propKey { name = "Alice"; }
Results in
name

isDefined

Description

Check if a property list has a property with a specific attribute.

Parameter Type

Standard

Parameters
  • attribute: The attribute name.

  • list: The property list.

Return

true is the property exists, false if not.

Example
isDefined "name" [ { name = "Alice"; } { age = 26; } ]
Results in
true

getValue

Description

Get a value from in a property list from an attribute name.

Parameter Type

Standard

Parameters
  • attribute: The attribute name.

  • list: The property list.

Return

The property value.

Example
getValue "name" [ { name = "Alice"; } { age = 26; } ]
Results in
Alice
getValue will trigger an error if there is no property with the attribute in the list.
isDefined function should be used before getValue to be sure the list has the attribute.

getProp

Description

Get a property from a property list by the attribute name.

Parameter Type

Standard

Parameters
  • attribute: The attribute name.

  • list: The property list.

Return

The property.

Example
getProp "name" [ { name = "Alice"; } { age = 26; } ]
Results in
{ name = "Alice"; }
getProp will trigger an error if there is no property with the attribute in the list.
isDefined function should be used before getProp to be sure the list has the attribute.

removeProp

Description

Remove a property from a property list having a specific attribute name.

Parameter Type

Standard

Parameters
  • attribute: The attribute name.

  • list: The property list.

Return

The property list with the property removed.

Example
removeProp "name" [ { name = "Alice"; } { age = 26; } ]
Results in
[ { age = 26; } ]
removeProp will trigger an error if there is no property with the attribute in the list.
isDefined function should be used before removeProp to be sure the list has the attribute.

propFlatten

Description

Flatten a property list where multiple attributes with the same attribute are defined. Works only with property lists where the value is a list.

Parameter Type

Standard

Parameters
  • list: The property list to flatten.

Return

The flattened property list.

Example
propFlatten [ { tags = [ "sports" "technology" ]; } { tags = [ "food" "trip" ]; } ]
Results in
[ { tags = [ "sports" "technology" "food" "trip" ]; } ]

propMap

Description

Map for property lists.

Parameter Type

Standard

Parameters
  • f: A function to apply to the property list.

  • propList: The property list to map.

Return

A list.

Example
propMap (p: v: "${p}: ${v}") [ { name = "Alice"; } { age = 26; } ]
Results in
[ "name: Alice" "age: 26" ]

11.8. nixpkgs

The nixpkgs namespace contains the nixpkgs library and the nix builtins.
This namespace contains many useful functions.

This section will be present a few commonly used function from it.


trace

Description

Display a variable value during site compilation.

Parameter Type

Standard

Parameters
  • variable: The variable to debug.

  • output: The value to output.

Return

output.

Example
Debugging a variable in a template
${trace var ""}

traceSeq

Description

Display a fully evaluated variable value during site compilation.

Parameter Type

Standard

Parameters
  • variable: The variable to debug.

  • output: The value to output.

Return

output.

Example
Debugging a variable in a template
${traceSeq var ""}
traceSeq can be dangerous when used on infinite or recursive data structures so it should be used with care.

map

Description

Apply a function to every element of a list.

Parameter Type

Standard

Parameters
  • function: Function to apply to list elements.

  • list: List.

Return

The list with the function applied to every element.

Example
map (e: e * 2) [ 1 2 3 4 ]
Results in
[ 2 4 6 8 ]
Nix being a functional language recursion is the main way to loop through a list.

filter

Description

Filter a list.

Parameter Type

Standard

Parameters
  • function: Function to filter the list, if the function returns true the element is kept, if false the element is removed.

  • list: List.

Return

The filtered list.

Example
filter (e: e > 3) [ 1 2 3 4 5 6 ]
Results in
[ 4 5 6 ]

12. Release Notes

12.1. Styx 0.4.0 - 2016/12/07

Highlights:

  • Better integration with the Nix ecosystem, styx sites can be called from nix expressions with callPackage

  • Themes can be used from the styx-themes set of packages

  • new manual subcommand to open the HTML documentation in a browser

Breaking Changes

  • Removal of the state variable in site.nix

  • site.nix init section was refactored

This release brings few major breaking changes that make upgrading from 0.3.0 non trivial.
The main changes involve the init section of site.nix.

12.2. Styx 0.3.0 - 2016/10/26

Highlights:

This release brings many major breaking changes that make upgrading from 0.2.0 non trivial.
Fortunately, the new features introduced in this release should make future upgrades easy.

12.3. Styx 0.2.0 - 2016/10/10

Highlights:

New features:

  • cli command

  • new preview subcommand to preview a site locally

  • new live subcommand to preview and automatically reload changes

  • serve subcommands new flags:

  • --detach to launch the server in a background process

  • --server-host to specify the server listening hostname

  • --siteUrl to override conf.siteUrl

  • new -target flag to specify the Styx site folder

  • content substitutions (Substitutions)

  • themes (Themes)

  • metadata (Metadata)

  • 404 error page template

Incompatible changes:

  • default.nix was renamed to site.nix

  • site.nix previewMode was renamed to renderDrafts

  • cli --preview flag has been renamed to --drafts

  • lib.content: getPosts, getDrafts and parsePage arguments have changed

  • lib.generation: generateSite arguments have changed

  • lib.utils: loadTemplateWithEnv function was removed

Bug Fixes:

  • nix link in the default theme layout template

  • styx new is working when called in empty folders

  • default theme archive title is not hardcoded

  • default them pagination is displayed only when there is more than one page

This release bring many major changes that make updating from 0.1.0 non-trivial.

To update, it is recommended to generate a new site, create a new theme with customized templates and static files, and update site.nix accordingly.

12.4. Styx 0.1.0 - 2016/10/07

Initial release of Styx.