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 and build determinism to name a few.
Styx was inspired by the NixOS weekly project and the Hugo static site generator.
For users familiar with Nix, Styx is best described as a custom builder for nix-build aimed for static websites.
|
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.
-
Integration with the Nix ecosystem: Styx sites can be deployed with NixOps, and continuous integration can be done with Hydra.
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 styx
For testing purposes, nix-shell can be used to start a temporary environment with styx:
$ nix-shell -p styx
Newer versions of styx are available in the nixpkgs-unstable or nixos-unstable channel, but there might be some delay between a styx release and the time the channel get updated.
It is possible to directly install the latest version of styx by running the following command:
$ nix-env -i https://github.com/styx-static/styx/archive/latest.tar.gz
Or to start a nix-shell with the latest styx stable version:
$ nix-shell -p $(nix-build https://github.com/styx-static/styx/archive/latest.tar.gz)
3. Quick Start
3.1. Preview a styx site
The styx showcase theme example site can be previewed by the following command:
$ styx preview --in $(nix-build --no-out-link -A styx-themes.showcase '<nixpkgs>')/example
This command download the showcase theme in the nix store, build the site also in the nix store and launch the preview from there.
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.
3.2. Create a new site
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. |
A readme.md file will be available in the my-site directory giving basic instructions. Also the styx doc command will launch the documentation in a browser.
It is recommended to read the site.nix section of this documentation to get familiar on how site.nix is structured and works.
Each theme of the styx-themes set provides and example site with a site.nix that can be checked with the following command.
$ less $(nix-build --no-out-link -A styx-themes.showcase '<nixpkgs>')/example/site.nix
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.
{ lib, styx, runCommand, writeText, ... }@args: (1)
rec { (2)
lib = import styx.lib args; (3)
index = { (4)
layout = template: "<html><body>${template}</body></html>"; (5)
template = page: '' (6)
<h1>Styx example page</h1>
${page.content}
'';
content = "<p>Hello world!</p>"; (7)
path = "/index.html"; (8)
};
site = lib.generateSite { pagesList = [ index ]; }; (9)
}
| 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. @args refers to the whole argument set. |
| 2 | { is starting a set. rec makes the set recursive, meaning that attributes can refers each other. |
| 3 | This imports the styx library in a lib attribute. |
| 4 | This declare an index attribute as an attribute set. An attribute set is a basic key-value structure. index will be the only page generated. |
| 5 | To generate a page, styx requires a few attributes to be set, namely layout, template and path. 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). |
| 6 | 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. |
| 7 | 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. |
| 8 | This declare a path attribute. The path attribute is used to specify the path of the page to be generated. |
| 9 | 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.
$ 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.path for every page in pagesList.That is the reason layout, template and path 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. Files
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 file, 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 site.nix 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 a styx site is totally free and can be changed according to needs. 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. A standard site.nix is usually more structured.
A complex example of a site.nix if the showcase theme example site.nix that use almost every feature available.
A standard site.nix is divided in multiple sections, each section handling a particular topic.
Standard sections are:
4.3.1. Init
This section is the basic setup of styx, it should not be changed and used as is for most setups.
/*-----------------------------------------------------------------------------
Init
Initialization of Styx, should not be edited
-----------------------------------------------------------------------------*/
{ lib, styx, runCommand, writeText
, styx-themes
, extraConf ? {}
}@args:
rec {
/* Styx library
*/
styxLib = import styx.lib args; (1)
| 1 | Load the styx library, library functions are documented in Library. |
4.3.2. Themes
The theme section is responsible for loading themes assets (configuration, library, static files, and templates).
Themes are detailed in the Themes section.
/*-----------------------------------------------------------------------------
Themes setup
-----------------------------------------------------------------------------*/
/* list the themes to load, paths or packages can be used
items at the end of the list have higher priority
*/
themes = [ (1)
styx-themes.generic-templates
];
/* Loading the themes data
*/
themesData = styxLib.themes.load {
inherit styxLib themes;
templates.extraEnv = { inherit data pages; }; (2)
conf.extra = [ ./conf.nix extraConf ]; (3)
};
/* Bringing the themes data to the scope
*/
inherit (themesData) conf lib files templates; (4)
| 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 lower priority.Themes can be paths like ./themes/my-site or packages from the styx-themes set. |
| 2 | Extra variables to add to the template environment. |
| 3 | Extra configuration sets to merge with the themes configurations, can be files or paths, head of the list have lower priority. |
| 4 | Bringing the themesData attributes in the scope. |
4.3.3. Data
The data section is responsible for loading the data used in the site.
The Data section explains in detail how to manage data.
/*-----------------------------------------------------------------------------
Data
This section declares the data used by the site
-----------------------------------------------------------------------------*/
data = {
about = loadFile { dir = ./pages; file = "about.md"; }; (1)
};
| 1 | Example of loading a markdown file with the loadFile function. |
4.3.4. 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 path attribute defined.
The Pages section explains in detail how to create pages.
/*-----------------------------------------------------------------------------
Pages
This section declares the pages that will be generated
-----------------------------------------------------------------------------*/
pages = {
about = {
path = "/about.html";
template = templates.page.full;
layout = templates.layout;
} // 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. |
path must start with a /.
|
4.3.5. Site
This is the final part and shortest section of site.nix. This section consists in a call to generateSite.
/*-----------------------------------------------------------------------------
Site
-----------------------------------------------------------------------------*/
/* Converting the pages attribute set to a list
*/
pagesList = pagesToList { inherit pages; }; (1)
site = generateSite { inherit files pagesList; }
}
| 1 | generateSite requires pages as a list, so pagesToList convert the pages attribute set to a list. |
files is generated in the theme section using enabled themes.inherit is a shorthand for writing sets, { inherit a; } is equivalent to { a = a; }.
|
4.3.6. site.nix in a nutshell
site.nix is a function:
-
taking at least nixpkgs
lib,styx,runCommandandwritetextattributes. -
returning an attribute set with a
siteattribute using thegenerateSitefunction.
generateSite is a function:
-
taking at least a list of pages to generate as the
pagesListargument. -
that evaluate each page set by evaluating
page.layout (page.template page)and output the result inpage.path. -
returning a generated static site directory.
generateSite is a wrapper for nixpkgs runCommand function.
|
5. Configuration
In a standard site.nix, configuration is generated by merging multiple configuration sources (lower to higher priority):
-
Themes default configuration / configuration interface (every used theme
conf.nix). -
conf.nixin the site root directory, the main configuration of a styx site. -
site.nixfunction headextraConfargument, used by the styx cli to override configuration keys according to passed options, mainlysiteUrlandrenderDrafts.
Configuration loading is done in site.nix theme section and can be adapted to fit needs.
5.1. conf.nix
conf.nix is the central configuration file of a styx site, its default location is at the site root.
This file consist in an attribute set, or a function returning an attribute set, that defines configuration options.
In case of a conf.nix is a function, it will be called with { lib = lib; } agument.
Theme configuration is made through themes via the theme attribute, every theme defines a configuration interface that can be used in conf.nix.
siteUrl is the only required field, and must not end with a slash.
It can be a domain like http://www.domain.org or a domain and a path like http://www.domain.org/styx-site.
{ lib }:
{
# 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";
};
}
conf.siteUrl must not end with a /.
|
6. Themes
Themes are a central concept in styx and are used to manage a site assets, like static files and templates. They can also provide a configuration interface and a function library.
6.1. Getting themes
Styx themes that are part of the styx-themes package set are documented in the styx-themes documentation.
6.2. Creating a new theme
A new theme file structure can be created by running the styx new theme command.
$ styx new theme my-theme --in ./themes
This command will generate the following files in ./themes/my-theme:
├── conf.nix (1) ├── meta.nix (2) ├── files/ (3) └── templates/ (4)
| 1 | Theme configuration interface, see Configuration interface for details. |
| 2 | Theme meta data, see Metadata for details. |
| 3 | Directory to store theme static files, see Files for details. |
| 4 | Directory to store theme templates, see Templates for details. |
See Structure for details.
Site and themes both have conf.nix files, their purpose is different and should not be confused.Theme conf.nix define the configuration interface, and site conf.nix settings use this interface to customize the theme.
|
6.3. Using themes
Declaring used themes is done in the theme section of site.nix.
Path or packages can be used.
/* list the themes to load, paths or packages can be used
items at the end of the list have higher priority
*/
themes = [
styx-themes.generic-templates
./themes/my-theme
];
Items at the beginning of the themes list have lower priority.
|
6.4. Structure
Themes are usually stored in a themes directory, or used from the styx-themes package set.
Every theme is stored in its own directory, and themes are expected to follow a certain structure.
themes
└── NAME (1)
├── conf.nix (2)
├── meta.nix (3)
├── lib.nix (4)
├── files/ (5)
└── templates/ (6)
| 1 | Theme directory. |
| 2 | conf.nix defines the theme configuration interface options (optional). |
| 3 | meta.nix defines the theme meta information, this is file is required and must define a id attribute. |
| 4 | lib.nix defines the theme extra library as a set (optional). |
| 5 | files is a directory holding static files for the themes. All the files in this directory will be copied in the generated site (optional). |
| 6 | templates is a directory storing all the templates files (optional). |
6.5. Configuration interface
A theme can provide a configuration interface by having a conf.nix file at the theme root directory.
In its simplest form, conf.nix should be an attribute set defining theme options with default values.
{
site = {
title = "The Agency";
author = "Your name";
description = "Your description";
};
}
This configuration is merged in the conf variable theme key after theme loading, and can be used from the site configuration (site conf.nix).
{
theme.site.title = "My Agency";
}
6.5.1. Typing
conf.nix can leverage NixOS module system like typing, and declare options with the mkOption function.
See NixOS manual option declaration chapter for mkOption usage details.
This have two benefits:
-
Site configuration, site root
site.nix, will be type checked. -
Documentation will be automatically generated for the configuration interface.
On the other hand, typing a theme configuration interface is verbose and can be an overkill for a private theme.
Typing is not required, but should be done for themes that are part of the styx-themes theme set or meant to be shared.
types.submodule type is not supported.
|
{ lib }:
with lib;
{
/* General settings
*/
site = {
title = mkOption {
default = "The Agency";
type = types.str;
description = "Title of the site.";
};
author = mkOption {
default = "Your name";
type = types.str;
description = "Content of the author `meta` tag.";
};
description = mkOption {
default = "Your description";
type = types.str;
description = "Content of the description `meta` tag.";
};
};
}
Options can then be used in the site conf.nix in the same manner than non-typed ones.
{
theme.site.title = 2;
}
$ styx preview
error: The configuration option `theme.site.title' is not a string.
(use ‘--show-trace’ to show detailed location information)
---
Error: Site could not been built, fix the errors and run the command again.
The '--show-trace' flag can be used to show debug information.
6.6. Metadata
Theme metadata is declared in the meta.nix file as an attribute set. Themes must define a meta.nix with an id attribute so the theme configuration is correctly processed.
Other attributes of the meta set are totally optional and can be set at will to provide information about the theme (e.g. license, description, author, homepage, …).
meta attributes used for the generated documentation are:
-
name: Theme name, can contain any character. -
license: A license fromlib.licenses. -
demoPage: Url of the theme example site live demo. -
homepage: Url of the theme. -
screenshot: Path to a screenshot of the theme example site. -
description: A single line theme description, asciidoc markup can be used. -
longDescription: Free length site description, asciidoc markup can be used. -
documentation: Theme documentation, asciidoc markup should be used.
{
id = "showcase";
}
{ lib }:
{
id = "showcase";
name = "Showcase";
license = lib.licenses.mit;
demoPage = https://styx-static.github.io/styx-theme-showcase;
homepage = https://github.com/styx-static/styx-theme-showcase;
screenshot = ./screen.png;
description = "A theme to show Styx main functionalities.";
}
Themes must define a meta.nix with an id attribute.
|
meta.nix can be an attribute set or a function, if it is a function it will be called with an attribute set argument containing lib.
|
6.7. Files
The files directory holds the static files provided by 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.8. Library
Themes can provide a function library that can be used in site.nix or in templates.
To provide a library, a theme must have a lib.nix file containing an attribute set of functions.
To be sure a theme library functions will not override default functions it is best practice to put the functions in a dedicated namespace, theme.ID where ID is the theme id as a natural choice.
{ lib }:
{
theme.my-theme = {
foo = x: "foo called with ${builtins.toString x}";
};
}
lib.nix can be an attribute set or a function, if it is a function it will be called with an attribute set argument containing lib.
|
6.9. 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.
├── archive.nix
└── post
├── full.nix
└── list.nix
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, they must return text (page attribute set
layoutkey). -
Normal templates, responsible for preparing a page for the layout template, this kind of templates usually return a page attribute set (page attribute set
templatekey). -
Partial templates, includes that can be used in normal or layout templates.
The template evaluation flow is:
generatePage :: Page -> String
generatePage page = page.layout (page.template page)
Where:
-
pageis a page attribute set. -
page.templateis a function taking the page attribute set, and returning an updated version of it (Page → Page). -
page.layoutis a function taking the page attribute set, and returning the page text source (Page → String).
| This example consider templates environment already evaluated. |
6.9.1. Text handling basics
Most of the work in template is done by manipulating text.
This section 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
''.'' Hello world! Hello Styx! '' -
single-line or multi-line text, delimited by
"."Hello world!"
Nix expressions can be included in text in enclosed in ${…}.
let name = "world"; in
"Hello ${name}!"
6.9.2. Layout templates
Layout templates are responsible for rendering the final source of a page.
A layout template function takes a template environment, and usually 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 html tag contents.
env:
page:
''
<html>
...
<body>
...
${page.content}
...
</body>
</html>
''
Layout templates are just functions, in case the normal template return the full page source like in a rss feed case, it is possible to set the page layout to the lib.id function. This will make the layout evaluation transparent and return the template result.
|
6.9.3. Normal templates
Normal templates are similar to the layout templates, with the only difference that their result will be evaluated by a layout template.
A standard normal template will 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.
env:
page:
let
content =
''
<h1>${page.title}</h1>
'';
in
page // { inherit content; }
|
In some cases, it is useful to have the normal template to return the final source of the page. By setting the page layout to the lib.id function, it is possible to bypass the layout template and have the normal template result being the final source source of the page.
|
This pattern of updating the page set content attribute and returning page set is very common so there is a normalTemplate function that abstract it.
{ lib, ... }:
with lib;
normalTemplate (page: "<h1>${page.title}</h1>")
6.9.4. Partial templates
Partials templates are templates that can be used in any other template.
They can be used as simple includes or to apply a template to a list of data.
6.9.5. Template environment
The template environment is the environment common to every template.
It is passed as 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 library functions. -
templates: The templates attribute set. -
data: The data attribute set. -
pages: The pages attribute set.
The template environment is set in site.nix themes loading section and can be easily modified upon needs.
conf, lib are templates automatically set, but data and pages are explicitly set via the templates.extraEnv parameter of the lib.themes.load function.
/* Loading the themes data
*/
themesData = styxLib.themes.load {
inherit styxLib themes;
templates.extraEnv = { inherit data pages; foo = "bar"; }; (1)
conf.extra = [ ./conf.nix extraConf ];
};
| 1 | Adding a foo variable to the template environment. |
6.9.6. Template environment in templates
There are two ways of writing the template environment in the template, as a variable or as a deconstructed set.
env: (1)
page:
''
${env.conf.theme.site.title}
''
| 1 | env is used as a set, and its key can be accessed with .. |
{ conf, lib, ... }: (1)
page:
''
${conf.site.theme.site.title}
''
| 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.9.7. Calling templates in templates
It is possible to call templates in a template by accessing to the templates attribute of the template environment.
{ templates, ... }:
page:
''
${templates.partials.head}
''
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.10. Combining Themes
In site.nix, themes are declared as a list. If multiple themes in the list provide the same file or template, the last theme in the list to declare it will be used.
This allows to build new themes based on other themes, like the showcase theme is built on the base of the generic-templates theme.
To combine a theme it is just needed to declare multiple themes in site.nix. If multiple themes define the same asset, asset from the later theme in the list will be used.
themes = [
styx-themes.generic-templates
./themes/my-theme
];
If generic-templates and my-theme both defines templates/partials/content.nix, the one from my-theme will be used.
Any used asset that is not defined in my-theme, will be used from generic-templates.
| There is no limit in the number of theme that can be combined. |
7. Data
Data refers to the data fetched or declared in the data section of site.nix.
Data is included in the default template environment and can be used in the pages section of site.nix to attach data to page attribute sets.
7.1. Creating data
Data can be created by directly defining a nix data structure.
An example of such usage is a navbar declared as a list of page attributes sets.
data.navbar = [ pages.about pages.contact ];
7.2. Importing data
The styx data library provides functions to import external data:
The data loading functions return a set per file loaded and do a few things:
-
A
fileDatafield 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,basenameandextfield combined with a..
-
-
Metadata is automatically parsed and merged to the set.
-
Data with introduction gain a
introattribute containing the introduction and the introduction is removed from the content. -
Multipages data gain a
pagesattribute, a list containing each page content. -
Converted markup is inserted in a
contentattribute. -
If the file basename begins in a
YYYY-MM-DD-orYYYY-MM-DDThh:mm:ssformat, this value will be inserted in adateattribute.
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.
= 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.
# 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.
[
{ name = "Alice"; interests = [ "science" "writing" ]; }
{ name = "Bob"; interests = [ "sports" "reading" ]; }
]
It is possible to make nix data a function and pass arguments from site.nix such as lib for more flexibility.
|
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 ---}.
{---
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.
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 subpages by using the <<< separator.
# 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 pages field that will hold the list of subpages content in format [ { content = …; } ].
|
The data section is only responsible for generating the data attribute set. Transforming a data attribute set in a page attribute set is done in 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 uses 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
tagsit will the values tags can take, for examplesportsortechnology. -
Values: Objects grouped by a taxonomy term, for example all the posts with the
technologytag.
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
taxonomyfield will be looked for.
data.taxonomies = mkTaxonomyData {
data = pages.posts;
taxonomies = [ "tags" "categories" ];
};
This will generate a taxonomy data structure where:
-
tagsandcategoriesare taxonomies. -
terms would be all the values of
tagsorcategoriesset inpages.posts. -
values would be all the pages in the
pages.postsdeclaringtagsorcategories.
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 path 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.
[
{
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.
{---
tags = [ "foo" "bar" ];
---}
# Lorem ipsum
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean dapibus aliquet justo ac lacinia.
| Tiaxonomy terms must be a list of strings. |
8. Pages
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 are passed to the generateFunction through the pagesList argument that turn each page into a text file.
| 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 thetemplateresult 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. -
path: The path of the page to generate, must start with a/.
These attributes are the strict minimum, but many templates will require extra attributes like content or title.
|
path must start with a /, else site generation will fail.
|
Hello world! contains an example of a simple page attribute set.
pages.index = {
path = "/index.html";
layout = template: "<html><body>${template}</body></html>";
template = page: "<h1>Hello world!</h1>";
};
In an standard site.nix, template and layout would be attributes from the templates set like templates.page.full or templates.layout.
Page attribute sets are often augmented by various attributes or merged with data sets.
generateSite evaluate page.layout (page.template page) and output the result in page.path 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 "site" section with lib.generation.pagesToList default parameter.Usually, only pages that use a different layout explicitly declares it in pages.The following examples will omit the layout attribute like often done in a normal site.nix.
|
8.3. Simple pages
Generating a simple page is trivial as it is just declaring the required attributes.
pages.e404 = {
path = "/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 can be done with the // operator.
pages.about = {
path = "/about.html";
template = templates.page.full;
} // data.about;
The // operator will merge the data.about data set in the pages.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 lib.id function, a function that return its parameter without changing it can be used as a "transparent" layout.
pages.feed = {
path = "/feed.xml";
template = templates.feed.atom;
items = lib.take 10 posts;
layout = lib.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, where the posts are listed through multiple 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.
pages.archives = lib.mkSplit {
basePath = "/archives";
template = templates.archives;
itemsPerPage = 5;
data = pages.posts;
};
This will create a list of pages attribute sets with the following extra attributes:
path-
Set accordingly to
basePath.basePath.htmlfor the first page, andbasePath-i.htmlfor the following pages whereiis 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 basePath, 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 pages attribute containing a list of pages in the pages attribute set.
Multipages are usually generated by importing Multipage data, data attribute set with a pages attribute.
Multipage 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 page
Multipages can be generated with the mkMultipages function.
pages.about = lib.mkMultipages ({
template = templates.page.full;
basePath = "/about";
} // data.about);
mkMultipages only requires basePath and pages 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 is different.
If mkMultipages is naively used, every multipage page 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 multipages post.
That way, multipage post subpages will not end up in posts archives list or in the web feed.
So for multipages in a list, the generation will be separated in two steps.
-
Generate the page list with single page data and multipage first page data.
-
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.
pages.posts = lib.mkPageList {
data = data.posts; (1)
template = templates.post.full;
};
| 1 | data is a list of data attribute set to generate pages attribute set from. |
It is possible to render multiPages with a different template by setting the multipageTemplate parameter.
Next step is to generate the tail of the multipages posts.
mkMultiTail is a function that generate page sets for the multipages tail in a list of data sets.
pages.multiPostsTail = lib.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 path attribute of mkPageList and mkMultiTail function with the pathPrefix argument.If the pathPrefix 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 = lib.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. Atermsattribute 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. Avaluesattribute will be added to the page attribute set containing all the values that use the term.
If required mkTaxonomyPages generated pages path can be changed with the taxonomyPathFun and the termPathFun, for details see mkTaxonomyPages.If any of these functions is changed, the templates should be updated accordingly. |
9. Site Generation
Site generation consists in a call to generateSite, and the preparation of its arguments.
pagesList = pagesToList { inherit pages; }; (1)
site = generateSite { inherit conf files pagesList; } (2)
| 1 | Convert the pages attribute set to a list of pages. |
| 2 | Generate the site. |
It is possible to set default attributes to every page set during the pages attribute by using the default argument of the pagesToList function.
A typical example is setting a default layout to every page set that do not declares one.
pagesList = lib.pagesToList {
inherit pages;
default.layout = templates.layout;
};
Styx expects the site to be rendered in the site attribute of the main set.
|
9.1. Substitutions
Subtitutions are a way to pass variables from site.nix in markup or static files.
Substitutions are a set that is passed to the generateSite function. Any value of set will be replaced in the markup or static files that generateSite outputs.
substitutions = {
siteUrl = conf.siteUrl;
};
site = lib.generateSite {
inherit files pagesList substitutions;
};
To be replaced, the variable as to be surrouded by @, for example @siteUrl@.
Learn more in the [Styx 0.1.0 Documentation](@siteUrl@/documentation-v0-1-0.html).
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.
9.4. Site derivation
Styx creates the static site as a standard nix derivation.
It is possible to set the derivation metadata by passing a meta set to the generateSite function.
site = with lib; generateSite {
inherit files pagesList substitutions;
meta = {
license = licenses.mit;
name = "foo-1.0.0";
};
};
10. Debugging
The nix-repl utility can be used to debug a styx site.
It can be installed with nix-env or used in a temporary environment with nix-repl.
$ nix-shell -p nix-repl --run nix-repl
10.1. Inspecting site.nix attributes
conf configuration setnix-repl> site = (import <nixpkgs> {}).callPackage (import ./site.nix) {}
nix-repl> site.conf
{ siteUrl = "https://styx-static.github.io/styx-theme-showcase"; theme = { ... }; }
10.2. Using lib functions
nix-repl> site = (import <nixpkgs> {}).callPackage (import ./site.nix) {}
nix-repl> with (site.lib.parseDate "2016-05-18T12:40:21"); "${date.lit}, ${time}"
"18 May 2016, 12:40:21"
10.3. Rendering a page source
nix-repl> showcase = (import <nixpkgs> {}).callPackage (import "${pkgs.styx-themes.showcase}/example/site.nix") {}
nix-repl> with showcase; lib.generatePage (pages.about // { layout = templates.layout; }) (1)
"<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"utf-8\">...."
nix-repl> with showcase; templates.layout (templates.page.full pages.about) (2)
"<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"utf-8\">...."
| 1 | Rendering a page with the generatePage function. |
| 2 | Rendering a page by running directly layout (template page). |
10.4. Building a site
It is possible to generate the site in the nix store from nix-repl.
nix-repl> showcase = (import <nixpkgs> {}).callPackage (import "${pkgs.styx-themes.showcase}/example/site.nix") {}
nix-repl> :b showcase.site
...
this derivation produced the following outputs:
out -> /nix/store/ak6h49a9h7asysv91nf31nhd5h7fgzhi-styx-site
11. Deployment
11.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)
11.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-pagesdirectory -
add the
gh-pagesfolder to.gitignore -
clone the repository in the
gh-pagesfolder -
create a new empty
gh-pagesbranch in thegh-pagesfolder
11.1.2. Update the gh-pages branch
styx deploy --gh-pages command will build the site, and update the gh-pages folder with the generated static site and commit it to the gh-pages branch.
Then changes can be pushed with the following commands:
$ (cd gh-pages && git push -u origin gh-pages) (1)
$ git push -u origin gh-pages (2)
| 1 | Push the gh-pages folder gh-pages branch to the root repository. |
| 2 | Push the root repository gh-pages branch to the remote repository. |
11.2. NixOps
NixOps is a deployment tool for NixOS configurations, and can be used to deploy styx sites.
{
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 {}).site}; (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. |
Then the site 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. |
12. Command line interface
The Styx provides a command line program styx.
12.2. Common flags
--in DIR-
Run the command in
DIR. --file FILE-
Use
FILEinstead ofsite.nix. --drafts-
Process and render drafts.
--show-trace-
Show debug output when styx command fails. (Nix flag)
--arg NAME VALUE-
Pass an argument
NAMEtosite.nixmain function. --argstr NAME VALUE-
Pass a string argument
NAMEtosite.nixmain function. -I PATH-
Add
PATHto to the Nix expression search path, useful to use custom versions of nixpkgs.
12.3. New
The new command is used to create a site or a theme.
12.4. Build
The build command is used to build a Styx site.
styx build-
Build the Styx site and write the output in the
publicdirectory. styx build --out DIR-
Build the nix site and write the output in the
DIRdirectory.
The nix-build --show-trace, --arg NAME VALUE, --argstr NAME VALUE and -I PATH flags can be used with the build command.
|
12.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 extraConf.renderDrafts as true to site.nix.
|
12.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.
|
12.7. Doc
The doc command can be used to launch styx HTML documentation in the default browser ($BROWSER).
styx doc-
Open the HTML help in the default browser.
BROWSER=firefox styx doc-
Open the HTML help in firefox.
12.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
8080and run the server on background, process can be found by runningps 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.
|
12.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 in the current directory to the
gh-pagesbranch in the./gh-pagesfolder. styx deploy --gh-pages --in ./example --out ./-
Commit the Styx site in
./exampleto thegh-pagesbranch in the./gh-pagesfolder.
13. 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.
13.1. Themes
This namespace contains functions related to themes.
load
- Description
-
Load themes data.
- Parameter Type
-
Attribute Set
- Parameters
-
-
styxLib: Styx library. -
themes: A list of themes paths or packages to load data from, head of the list have lower priority. -
conf(optional): configuration loading parameters:-
extra(optional): A list of base configuration attribute sets or paths, head of the list have lower priority.
-
-
templates(optional): templates loading parameters:-
extraEnv(optional): An attribute set that will be merged with the template environment.
-
-
- Return
-
An attribute set containing:
-
conf: The merged themes configuration. -
lib: The merged themes library. -
files: List of static files folder. -
templates: The merged themes template set. -
themes: List of themes attribute sets.
-
- Example
-
themesData = styxLib.themes.load { inherit styxLib themes; templates.extraEnv = { inherit data pages; }; conf.extra = [ ./conf.nix extraConf ]; };
loadData
- Description
-
Load a themes data.
- Parameter Type
-
Attribute Set
- Parameters
-
-
styxLib: Styx library. -
theme: A themes path or package to load data from.
-
- Return
-
A list of themes attribute sets containing:
-
lib: Theme function library. -
meta: Theme meta information. -
id: Theme id. -
path: Theme path. -
decls: Theme configuration interface declarations. -
defs: Theme configuration interfaces definition. -
docs: Theme configuration interface documentation. -
types: Theme configuratoin interface types. -
templates: Theme templates functions (environment not applied). -
files: Theme static files path.
-
- Example
-
lib.themes.loadData { inherit styxLib; theme = styx-themes.showcase; };
13.2. Template
The template namspace contains functions useful in templates.
normalTemplate
- Description
-
Abstract the normal templates pattern.
- Parameter Type
-
Mixed
- Parameters
-
Parameters can be a:
-
String: The parameter will be added to the page setcontent, and the page set will be returned. -
Attribute Set: The parameter will be merged to the page set, and the page set will be returned. -
Page Attribute Set → String: TheStringparameter will be added to the page setcontent, and the page set will be returned. -
Page Attribute Set → Attribute Set: TheAttribute Setparameter will be merged to the page set, and the page set will be returned.
-
- Return
-
A normal template function in the form
Page Attribute Set → Page Attribute Set. - Examples
-
String parameter
normalTemplate "Sample content"Results inpage: page // { content = "Sample content"; }
Attribute Set parameternormalTemplate { content = "Sample content"; title = "Sample"; };Results inpage: page // { content = "Sample content"; title = "Sample"; }
Page Attribute Set → String parameternormalTemplate (page: "Page path: ${page.path}" )Results inpage: page // { content = "Page path: ${page.path}"; }
Page Attribute Set → Attribute SetnormalTemplate (page: { content = "Page path: ${page.path}"; title = "Sample"; })Results inpage: page // { content = "Page path: ${page.path}"; title = "Sample"; }
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 inclass="foo bar"
htmlAttrs
- Description
-
Create html tag attributes from an attribute set.
- Parameter Type
-
Standard
- Parameters
-
-
attrs: Attribute set to generate tag attribute to generate.
-
- Return
-
A string of the attributes.
- Example
-
htmlAttrs { class = [ "foo" "bar" ]; id = "baz"; }Results inclass="foo bar" id="baz"
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
|
Using a function with mapTemplate
Results in
|
mapTemplateWithIndex
- Description
-
Similar to
mapTemplatebut 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
-
mapTemplateWithIndex (index: item: "<li>${toString 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 2Results in1
isEven
- Description
-
Check if a number is even.
- Parameter Type
-
Standard
- Parameters
-
-
number: The number to check.
-
- Return
-
trueifnumberis even,falseif not. - Example
-
isEven 2Results intrue
isOdd
- Description
-
Check if a number is odd.
- Parameter Type
-
Standard
- Parameters
-
-
number: The number to check.
-
- Return
-
trueifnumberis odd,falseif not. - Example
-
isOdd 2Results infalse
parseDate
- Description
-
Parse a date.
- Parameter Type
-
Standard
- Parameters
-
-
date: A date in the formatYYYY-MM-DDorYYYY-MM-DDThh:mm:ss, e.g.2012-12-21or2012-12-21T12:00:00.
-
- Return
-
An attribute set containing date parts.
- Example
-
with (parseDate "2012-12-21"); "${D} ${b} ${Y}"Results in21 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. hh-
The hour in 2 digit format (08, 12).
h-
The hour in 1 digit format (8, 12).
mm-
The minuts in 2 digit format (05, 55).
ss-
The seconds in 2 digit format (05, 55).
time-
The time in the
mm:hh:ssformat (12:00:00). date.num-
The date in the
YYYY-MM-DDformat (2012-12-21). date.lit-
The date in the
D B YYYYformat (21 December 2012). T-
The date and time combined in the
YYYY-MM-DDThh:mm:ssZformat (2012-12-21T12:00:00Z).
13.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 Setting isDraft to every file in a folder
|
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 Setting isDraft to a file
|
asciidocToHtml
- Description
-
Convert an asciidoc string to html text.
- Parameter Type
-
Standard
- Parameters
-
-
string: A string in asciidoc format.
-
- Return
-
stringconverted 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
-
stringconverted 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. |
13.4. Conf
This namespace contains functions related to configuration.
extract
- Description
-
Extract a keys from
mkOptiondeclarations in a set. - Parameter Type
-
Attribute Set
- Parameters
-
-
key: Key to extract. -
set: Set to extract keys from. -
nullify(optional): Set every non extracted key value tonull.
-
- Return
-
An attribute set where
mkOptiondeclaration have been replaced. - Example
-
extract { key = "default"; set = { a.b.c = mkOption { default = "abc"; type = types.str; }; x.y = 1; }; };Results in{ a.b.c = "abc"; x.y = 1; }
13.5. 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
-
-
basePath: The basepathset to the pages set, the first pagepathisbasePath.html, following pagespathisbasePath-index.htmlwhere 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/itemsPerPagepage attribute set with thepathset accordingly tobasePath. - Example
-
pages.archives = mkSplit { basePath = "archives"; itemsPerPage = 10; data = pages.posts; };
|
Any extra arguments to Set a template with mkSplit
|
| 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. -
basePath: The basepathset to the pages, thepathisbasePath-index.htmlwhere index is the number of the page. -
pathFn: Function to generate tail page path of typeInt → Path, default implemetation isi: "${tail.basePath}-${toString i}.html".
-
-
- 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 |
| For details see the Split pages section. |
mkMultipages
- Description
-
Create the list of page set for multipages data set.
- Parameter Type
-
Attribute Set
- Parameters
-
-
pages: The list of subpages. -
basePath: The basepathset to the pages set, the first pagepathisbasePath.html, following pagespathisbasePath-index.htmlwhere index is the number of the page. -
output:all,headortail. This select which pages set to generate.
-
- Return
-
A list of page attribute set according to the arguments, the
pagesis inherited. - Example
-
pages.about = mkMultipages ({ template = templates.generic.full-multipage; basepath = "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. -
pathPrefix(optional): A prefix string to add to the generated page setpath. -
multipageTemplate: The template used for multipage data sets.
-
- Return
-
A list of page attribute set according to the arguments, the subpages list is added in the
pagesattribute of each page if subpages are present. - Example
-
pages.posts = mkPageList { data = data.posts; pathPrefix = "posts/"; template = templates.post.full; multipageTemplate = templates.post.full-multipage; };
|
Any extra arguments to |
| For details see the Multipages section. |
For the same data set list, basepath 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. -
pathPrefix(optional): A prefix string to add to the generated page setpath.
-
- Return
-
A list of page attribute set according to the arguments.
- Example
-
pages.postsMultiTail = mkMultiTail { data = data.posts; pathPrefix = "posts/"; template = templates.post.full-multipage; };
|
Any extra arguments to |
| For details see the Multipages section. |
For the same data set list, basePath set in mkPageList and in mkMultiTail must be the same.
|
mkTaxonomyPages
- Description
-
Generate the taxonomy related pages for the
datalist 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. -
taxonomyPathFn(optional): A function to generate thepathof the taxonomy page with typeTaxonomy → String.Default implementationta: "/${ta}/index.html" -
termPathFn(optional): A function to generate thepathof the taxonomy term page with typeTaxonomy → Term → String.Default implementationta: te: "/${ta}/${te}/index.html"
-
- 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; };
taxonomy: "/${taxonomy}/index.html"
taxonomy: term: "/${taxonomy}/${term}index.html"
Changing taxonomyPathFun or termPathFun will require to also update the taxonomy related template links.
|
| For details see the Taxonomies section. |
13.6. Generation
The generation namespace contains functions related to the site generation.
generatePage
- Description
-
Generate a page source by applying the
templateand thelayoutto a page attribute set.
This is how styx generate pages ingenerateSite, simply evaluatepage.layout (page.template page). - Parameter Type
-
Standard
- Parameters
-
-
page: A page attribute set defining at leasttemplateandlayout.
-
- Return
-
The generated static site.
- Example
-
generatePage { layout = template: "<html><body>${template}</body></html>"; template = page: '' <h1>Styx example page</h1> ${page.content} ''; content = "<p>Hello world!</p>"; };Results in<html><body><h1>Styx example page</h1> <p>Hello world!</p></body></html>
generateSite
- Description
-
Generate a static site.
- Parameter Type
-
Attribute Set
- Parameters
-
-
name(optional): The derivation name, defaults tostyx-site. -
meta(optional): The derivation meta attributes, defaults to{}. -
files(optional): A list of folders. All the contents of the folders in this list will be copied to the generated site root. -
pagesList(optional): A list of page attribute sets to generate. -
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. -
genPageFn(optional): Function to generate the page with typePage → String, defaults togeneratePage. -
pagePathFn(optional): Function to generate the page path with typePage → String.Default implementationpage: page.path
-
- Return
-
The generated static site.
- Example
-
generateSite { pagesList = [ pages.index ]; }
pagesToList
- Description
-
Convert the
pagesattribute set to a list of pages attribute sets. - Parameter Type
-
Attribute Set
- Parameters
-
-
pages: Thepagesattribute set. -
default(optional): An attribute set containing default page values, defaults to{}.
-
- Return
-
A list of pages attribute sets.
- Example
-
pageslist = pagestolist { inherit pages; };pageslist = pagestolist { inherit pages; default.layout = templates.layout; };
13.7. Utils
The utils namespace contains generic functions that do not fit in other namespaces.
merge
- Description
-
Recursively merge a list of attribute sets. Sets at the beginning of the list have lower priority.
- Parameter Type
-
Standard
- Parameters
-
-
confs: A list of attribute sets.
-
- Return
-
The merged attribute set.
- Example
-
conf = lib.utils.merge [ (lib.themes.loadConf { inherit themes; }) (import ./conf.nix) extraConf ];
chunksOf
- Description
-
Split a list in lists multiple lists of
nitems. - 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 ] ]
dirContains
- Description
-
Check if a path exists in a directory.
- Parameter Type
-
Standard
- Parameters
-
-
dir: A directory. -
path: A path.
-
- Return
-
trueif the path exists,falseif not. - Example
-
lib.utils.dirContains styx-themes.showcase "lib.nix";
setDefault
- Description
-
Set default values to a list of attribute sets.
- Parameter Type
-
Standard
- Parameters
-
-
list: A list of attribute sets. -
default: default values as a set.
-
- Return
-
A list of sets.
- Example
-
setDefault [ { foo = 1; } { bar = 2; } ] { foo = 0; bar = 0; }Results in[ { foo = 1; bar = 0; } { foo = 0; bar = 2; } ]
sortBy
- Description
-
Sort a list of attribute sets by an attribute value.
- Parameter Type
-
Standard
- Parameters
-
-
attribute: The attribute to use for sorting. -
order:ascfor ascding order, ordscfor 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; } ]
13.8. 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.
[ { 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 inAlice
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 inname
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
-
trueis the property exists,falseif not. - Example
-
isDefined "name" [ { name = "Alice"; } { age = 26; } ]Results intrue
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 inAlice
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" ]; } ]
13.9. 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. |
14. Release Notes
14.1. Styx 0.5.0 - 2017/01/18
Highlights:
-
New theme: generic-templates. The generic-templates theme provide a template framework and basic templates for common components.
-
Showcase and Hyde themes have been ported to use generic-templates.
-
Theme configuration interface can be typed, and site configuration is type-checked.
-
styx-themesthemes full documentation. -
Interactive debugging with
nix-repl. -
Simpler and shorter
site.nix
Breaking Changes:
-
Many, among others:
-
site.nixwas refactored -
Themes
theme.nixwas removed, its functionality is divided in two files,conf.nixandmeta.nix.conf.nixfor configuration interface andmeta.nixfor theme metadata. -
Themes
meta.nixfile must be present and must declare aidattribute specifying the theme id. -
lib.pages.setDefaultLayoutwas removed (default pages values can be set with thedefaultargument of pagesToList). -
all occurences of
hrefin function names / parameters and template variables has been replaced withpath, pagespathattribute must start with a/.
-
Upgrading:
This release brings many incompatible changes that requires to refactor site.nix to upgrade.
Changes involve, among others, the init section of site.nix, site.nix returning a set instead of a generateSite call and href occurrences replaced by path (path attributes must start with a /).
Comments:
This is the first close to stable release of styx. Please test and send any bug or question to the bug tracker.
14.2. 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-themesset of packages -
new
manualsubcommand to open the HTML documentation in a browser
Breaking Changes
-
Removal of the
statevariable insite.nix -
site.nixinit 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.
14.3. Styx 0.3.0 - 2016/10/26
Highlights:
-
Styx library is automatically bundled
-
Easier updates
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.
14.4. Styx 0.2.0 - 2016/10/10
Highlights:
-
Live preview mode for the cli command (Live)
-
Introduction of themes (Themes)
-
Content substitutions (Substitutions)
-
Content metadata (Metadata)
New features:
-
cli command
-
new
previewsubcommand to preview a site locally -
new
livesubcommand to preview and automatically reload changes -
servesubcommands new flags: -
--detachto launch the server in a background process -
--server-hostto specify the server listening hostname -
--siteUrlto overrideconf.siteUrl -
new
-targetflag to specify the Styx site folder -
content substitutions (Substitutions)
-
themes (Themes)
-
metadata (Metadata)
-
404 error page template
Incompatible changes:
-
default.nixwas renamed tosite.nix -
site.nixpreviewModewas renamed torenderDrafts -
cli
--previewflag has been renamed to--drafts -
lib.content:getPosts,getDraftsandparsePagearguments have changed -
lib.generation:generateSitearguments have changed -
lib.utils:loadTemplateWithEnvfunction was removed
Bug Fixes:
-
nix link in the default theme layout template
-
styx newis 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.