1. Introduction

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

Styx is aimed to be flexible and easy to customize, also Styx is using the Nix package manager so it has a very effective caching system. External applications can be used in Styx in a very easy way without having to install them.

1.1. Why use Styx

Pros:

  • Uniformity: The same language is used in templates and logic.

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

  • Light weight: Styx has very few dependencies.

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

Cons:

  • Performance: Some parts of Styx like the posts conversion can be very 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 Nix with the following command:

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

To only test Styx, it is recommended to use the nix-shell command to start a temporary environment including Styx:

$ nix-shell -p `nix-build https://github.com/ericsagnes/styx/archive/latest.tar.gz`

3. Quick Start

A Styx site can be created and locally served with the following set of commands:

$ nix-shell -p $(nix-build https://github.com/styx-static/styx/archive/latest.tar.gz) (1)
[nix-shell]$ styx new myblog (2)
[nix-shell]$ cd myblog (3)
[nix-shell:~/myblog]$ styx serve (4)
1 Enter a nix-shell with Styx.
2 Generate a new site in the myblog directory.
3 Enter the Styx site root folder.
4 Serve the site on a local server.

4. Command line interface

The Styx provides a command line program styx.

4.1. Generic commands

styx --help

Display the help message.

styx --version

Display the version.

4.2. Build

The build command is used to build a Styx site. It must be used in a Styx site root file.

styx build

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

styx build -o FOLDER

Build the nix site and write the output in the FOLDER folder.

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

4.3. Serve

The serve command is used to build a site and launch a local server. This allow to check the site without having to deploying 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 --preview

Enable preview mode. In preview mode drafts are displayed.

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

4.4. 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.

5. 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.

5.1. Configuration

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

conf.nix
include::../sample/conf.nix[]

The configuration is an attribute set, and new configuration attributes can be added at will.

pagesDir

Directory where pages are located.

postsDir

Directory where posts are located.

draftsDir

Directory where drafts are located.

templatesDir

Directory where templates are located.

staticDir

Directory where static files are located.

siteId

Site id, used in the caching scheme. Should composed of lowercase letters, numbers, - and _. Spaces are not allowed.

siteURL

URL of the site, must be set to the URL of the domain the site will be deployed. Must not contain a trailing /.

siteTitle

Site title, used in the site header and the atom feed.

siteDescription

Site description used in the base template.

postsOnIndexPage

Maximum number of posts on the index page.

postsPerArchivePage

Maximum number of posts per archive page.

5.2. Directory Structure

├── conf.nix (1)
├── default.nix (2)
├── drafts/ (3)
├── lib/ (4)
├── pages/ (5)
├── posts/ (6)
├── static/ (7)
└── templates/ (8)
1 conf.nix is the main configuration, see Configuration for details.
2 default.nix is the main file for site generation, see default.nix for details.
3 drafts/ is the default directory containing drafts, see Drafts for details.
4 lib/ is the directory holding Styx library functions, see Library for details.
5 pages/ is the default directory containing pages, see Pages for details.
6 posts/ is the default directory containing drafts, see Drafts for details.
7 static/ is the default directory containing static files, see Static files for details.
8 templates/ is the default directory containing templates files, see Templates for details.

5.3. default.nix

default.nix is the central file of a Styx site and is responsible for generating the website.

default.nix consists in a single function that generate a site when evaluated.

Functions in the Nix expression language are declared in a head: body syntax, for example a: b: a + b is a function adding two numbers.

Sample site default.nix show many of the Styx possibilities, so might feel a little complicated for a new user.

A standard site default.nix can be lot simpler than the sample one.

The following sections will explain default.nix parts by parts.

5.3.1. Skeleton

The skeleton is the boiler-plate code of Styx, it should be edited at own risks as any change in it might lead to unexpected results.

default.nix skeleton
{ pkgs ? import <nixpkgs> {} (1)
, previewMode ? false (2)
, siteUrl ? null
, lastChange ? null
}@args: (3)

let lib = import ./lib pkgs; (4)
in with lib; (5)

let (6)

# Main Logic (7)

in generateSite { inherit conf; pages = pageList; } (8)
1 This is a function head declared as a deconstructed set, ? righthand set the default value for the lefhand argument. This line is importing the default system nixpkgs.
2 previewMode ? false means that previewMode default value is false.
3 The { …​ }@args pattern provide a way to refer to the full parameter attribute set via args.
4 let is a construction to declare local variables, a let block finish by a in. Any variable defined in a let is available in the let scope and in the scope right after the in. let a = 1; 1 + a will result in 2. let are used to structure code in an easier to understand manner. This line import the lib/default.nix file and set it to a lib variable. The lib variable is an attribute set containing Styx library functions.
5 The in section of the previous let. The with coming next is a way to put all the top-level attributes of an attribute set in the scope. with { a = 1; b = 2; }; a + b result in 3. So in the previous line lib is imported in the lib local variable, and in this line all the top-level lib functions are inserted in the local scope.
6 Another let to start a scope inheriting lib and all its attributes (top-level functions).
7 Contains the main logic, and will be explained in the next section.
8 This is what the whole default.nix function return. generateSite is a function that generate the site. All the logic in the "Main Logic" part is meant to prepare generateSite arguments.
The default parameters in default.nix head: pkgs, previewMode, siteUrl and lastChange are set and expected by Styx. Removing or changing them will break the site generation process.

5.3.2. Main Logic

Main logic part can be divided in three parts: setup, template declaration and pages declaration. The order of declarations in the main logic part is not important and can be changed to fit preference.

Setup

This part contains some boiler-plate code. Variables can be declared at will to fit any special needs. (Comments removed in favor of call-out explanations)

Setup section in default.nix
  conf = overrideConf (import ./conf.nix) args; (1)

  state = { inherit lastChange; }; (2)

  genericEnv = { inherit conf state lib templates; }; (3)

  loadTemplate = loadTemplateWithEnv genericEnv; (4)

  navbar = [ (head pages.archives) pages.about ]; (5)
1 Loading the main configuration file, conf.nix in a conf local variable.
2 Setting a state local variable containing "impure" values. It contains only the lastChange variable coming from default.nix main function head. (Skeleton point 1) lastChange value is automatically set by the Styx command.
3 This initialize a generic template environment. Most of templates expect to have access to conf, state, lib and templates. It is not recommended to remove any of these. On the other hand it is fine to add new attributes to the default environment to fit special needs.
4 Defining a helper function loadTemplate that loads a template with the default environment. This function is defined taking advantage of η-reduction so its argument is not specified. loadTemplate is actively used during template declaration.
5 This define a navbar local variable containing pages to include in the NavBar. For more details about Navbar setting, see the NavBar section.
η-reduction is the process to drop a function abstraction. For example, x: a x is equivalent, and can be reduced to a.
Templates declaration

The template declaration part consists in declaring all the templates that will used. Templates are grouped in a single attribute set.

Template environment used to load templates can be extended on a per template basis to fit special needs.

The sample site contains many similar templates declarations, so this section will only present interesting examples.

Templates declaration
  templates = { (1)
    index   = loadTemplate "index.nix"; (2)
    layout  = loadTemplateWithEnv  (3)
                (genericEnv // { inherit navbar; feed = pages.feed; }) (4)
                "layout.nix"; (5)
    navbar = { (6)
      main = loadTemplate "navbar.main.nix";
      brand = loadTemplate "navbar.brand.nix";
    };
  };
1 Declaring a templates attribute set where all the templates will be declared.
2 Declaring an index variable that holds the index.nix template loaded with the generic template environment.
3 Declaring a layout template that holds the layout template, this use the loadTemplateWithEnv function so a custom environment can be passed as the first argument.
4 The environment passed to the template is the generic environment extended with a variable feed that holds the feed page (pages.feed) and the navbar variable that holds the list of pages to show in the NavBar. The base template is managing the main layout of the site and the head section of the HTML document. As we want to have a link to the feed in it, we add the feed page to a variable so it can be used in the template. Similar for the NavBar.
5 The template file to load, layout.nix.
6 Declaring templates in a sub attribute set. Templates in a subset can be accessed with ., for example the navbar main template is accessed by templates.navbar.main.
// is the operator to merge attribute sets. If the two sets have a same key, the right hand set value will be set. The merge is not recursive.
Pages declaration

The pages declaration consists in declaring all the pages of the site in an attribute set. The sample site contains many similar pages declarations, so this section will only present interesting examples.

A page is an attribute set with a few constraints, to learn more about how it should be structured see the Pages section.

A page attribute set must consist at least of template, href and title attributes. The feed page is an exception as it use the site title from conf and then does not need a title attribute.
Pages declaration 1/2
  pages = rec { (1)
    index = { (2)
      title = "Home";
      href = "index.html";
      template = templates.index;
      inherit feed; (3)
      posts = take conf.postsOnIndexPage posts; (4)
      archivePage = head archives; (5)
    };

    about = {
      href = "about.html";
      template = templates.about;
      breadcrumbs = [ index ]; (6)
    } // (parsePage conf.pagesDir "about.md"); (7)
1 Declaring the pages attribute set. It is important that this set holds only valid pages or list of pages. The rec keyword make the set recursive, so it is possible to refer set attributes in other attributes.
2 Declaring an index page containing the basic title, href and template attributes.
3 Inheriting the feed page, this is equal to feed = feed;. feed is a non-standard page attribute and is declared to fit contents needs.
4 This also set a non-standard attribute, posts set to the first conf.postsOnIndexPage items of the post page list.
5 Another non-standard attribute, archivePage set to the first page of the archives page list.
6 Setting page breadcrumbs, for details on the breadcrumbs system see the Breadcrumbs section.
7 Fetching page content and title from a markdown.
Pages declaration 2/2
    archives = splitPage { (1)
      baseHref = "archives/posts";
      template = templates.archive;
      items = posts;
      itemsPerPage = conf.postsPerArchivePage;
      title = "Posts";
      breadcrumbs = [ index ];
    };

    feed = { (2)
      posts = take 10 posts;
      href = "feed.xml";
      template = templates.feed;
      layout = id;
    };

    posts = let  (3)
      posts = getPosts conf.postsDir "posts"; (4)
      drafts = optionals previewMode (getDrafts conf.draftsDir "drafts"); (5)
      preparePosts = p: p // { template = templates.post.full; breadcrumbs = with pages; [ index (head archives) ]; }; (6)
    in sortPosts (map preparePosts (posts ++ drafts)); (7)
  };

  pageList =
    let list = (pagesToList pages); (8)
    in map (setDefaultLayout templates.layout) list; (9)
1 Declaring an archives list of pages by splitting items trough multiple pages. See [splitPage] for details.
2 A simple page declaration. As the feed template is using conf.siteTitle in place of title, it is not required to set a title in this special case. Also, as the feed page does not need a layout, the layout function is set to id, see Layout templates for details.
3 Declare the list of posts, this is the most complex page declaration presented in this section.
4 Fetching the posts and setting their output path to posts.
5 Fetching the drafts only if previewMode is enabled. (by using the --preview flag to the Nix command)
6 Declaring a preparePost function that take a post and extends it by setting a template and breadcrumbs.
7 Finally merging the posts and drafts in a list, setting the template and breadcrumbs to each, and sorting the list so the posts are in chronological order.
8 generateSite needs a list of pages, so we convert the pages attribute set to a pageList list with the pagesToList function.
9 Then, setDefaultLayout is used to set a layout template to all the pages that don’t set the layout attribute.

6. Content

6.1. Pages

Pages is the most basic content unit. Every content in Styx is a page (posts and drafts are a special types of pages).

A page in Styx is an attribute set following a set of rules:

  • It must define at least the href, title, layout and the template keys.

  • The template key is a function that take the page attribute set as a parameter and return the page attribute set augmented with a content key representing the result of the template.

  • The layout key is a function take a page attribute set with a content key, returned by the the template key, and render the final page source.

  • The href key is the path of the generated page relative to site root.

It is possible to extend a page attribute set at will for more complex use cases.

Page definition example
  pages.about = {
    href = "about.html";
    template = templates.about;
    title = "About";
    layout = templates.layout;
  };
The layout being common to most of the pages, the default layout is usually set with a map function when the page attribute set is converted to a list of pages.
Extending a page attribute set
  pages.about // { breadcrumbs = [ pages.index ]; }

Page content can be directly set in the template, or imported from an external file with the parsePage function:

Loading a markdown file
  about = {
    href = "about.html";
    template = templates.about;
    breadcrumbs = [ index ];
  } // (parsePage conf.pagesDir "about.md");
parsePage return a set with title and content. content is the converted HTML source of the page.

6.2. Posts

Posts are a special type of pages. By default, Styx read files in markdown format from conf.postsDir, but it is possible to specify a custom directory to the getPosts function.

Post files should follow the YYYY-MM-DD-TITLE.md convention to be loaded. During build, Styx with display a message if it cannot load a post file.

Post attribute sets generated by the parsePost function have the following attributes:

  • timestamp: Timestamp of the post in the YYYY-MM-DD-TITLE format.

  • href: Relative URL to the post.

  • title: Post title

  • id: Name part of the post file name.

  • content: Post content in HTML format.

The getPosts function does not set a template and a layout key, so posts generated by it are imcomplete pages. These keys can be set afterwards.

6.3. Drafts

Drafts are a special type of posts that are only generated when the --preview flag is passed to the Styx command. By default, Styx read files in markdown format from conf.draftsDir, but it is possible to specify a custom directory to the getDrafts function.

Drafts attribute sets generated by the parseDraft function have the following attributes:

  • timestamp: Timestamp of the post in the YYYY-MM-DD-TITLE format.

  • href: Relative URL to the post.

  • title: Post title

  • id: Name part of the post file name.

  • content: Post content in HTML format.

  • isDraft: set to true.

The only difference between posts and drafts is the presence of the isDraft attribute.

6.4. Custom content

There is no limitation in the type of content Styx can generate. The page attribute and the template environment can be extended to include any key that could fit special needs.

It is also possible to use any program provided in the nixpkgs packages in library functions.

Using an external program
  title = readFile (pkgs.runCommand "${timestamp}-${id}.title" {} ''
    ${pkgs.xidel}/bin/xidel ${html} -e "//h1[1]/node()" -q > $out (1)
    echo -n `tr -d '\n' < $out` > $out
  '');
1 Using the Xidel program to fetch the first title text of the post.

6.5. Static files

Static files are the files that are added to the generated site folder. Static files should be in the conf.staticDir directory.

7. Customization

This section explains how to customize a Styx site.

7.1. Templates

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

Templates are divided in two types:

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

  • Partial templates responsible for the partial rendering of a page, it should return a page attibute set, but in some special cases can return text. (page attribute set template key)

The template evaluation flow is:

  • The partial template evaluate the page attribute set, this generate a partial result that is stored in the page attribute set content key.

  • The layout template evaluate the page attribute set returned by the partial template and produce the final source of the page.

7.1.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:

  • multi-line text, delimited by ''.

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

    Multi-line text
    "Hello world!"

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

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

7.1.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. (There are exceptions)

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.

Simple layout template.
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 the 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.

7.1.3. Partial templates

Partial templates are similar to the layout templates, with the only difference that their result will be evaluated by the layout template. The partial template should set or update the content attribute of the page attribute set so the layout template can render the final source. Partial templates can also add other attributes to the page attribute to fit any special need.

{ templates, ... }:
page:
let
  content =
    ''
      <h1>${page.title}</h1>
    '';
in
  page // { inherit content; }

7.1.4. Template environment

The template environment is the first parameter of the template function. It is defined when loading the template in default.nix.

The default template environment consists in:

  • conf: the configuration attribute set

  • templates: the templates attribute set

  • state: the state attribute set, by default it only holds the timestamp of the generation

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

It is possible to extend the template environment at will.

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.

7.2. Calling templates in templates

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

Calling a template in a template
{ templates, ... }:
page:
''
  ${templates.foo}
''
The loadTemplateWithEnv function, or calling the loadTemplate with an environment 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.

7.3. 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
${mapTemplate templates.post.list page.posts}

8. Library

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

8.1. generation

This namespace contains functions related to content generation.


generateSite
Description

Generate a site with a list of pages. This is the function returned by default.nix.

Parameter Type

Set

Parameters
  • conf: The configuration set.

  • pages: A list of pages to generate.

  • preGen (optional): A set of commands to execute before generating the site.

  • postGen (optional): A set of commands to execute after generating the site.

Return

A static site.

Example
generateSite { inherit conf; pages = pageList; }

pagesToList
Description

Convert an attribute set of pages to a list of pages. Useful to convert the pages attribute set in default.nix to a page list for generateSite. Parameter Type: Standard

Parameters
  • pages: An attributes which every key value is a page attribute set or a list of page attribute sets.

Return

A list of pages.

Example
pages = {
  about = {
    href = "about.html";
    template = templates.about;
  } // (parsePage conf.pagesDir "about.md");
};

pageList = pagesToList pages;

splitPage
Description

Split a page in multiple pages according to parameters. Used for pagination like pages.

Parameter Type

Set

Parameters
  • baseHref: The href of the archive pages, the first page href will be baseHref.html, following pages href will be baseHref-i.html where i is the index number of the page.

  • items: Items to be split through the pages.

  • template: The template used by the split pages.

  • itemsPerPage: Maximum number of items displayed on each page.

  • Any extra arguments will be included in the split pages attribute set.

Return

A list page attribute sets.

Example
archives = splitPage {
  baseHref = "archives/posts";
  template = templates.archive;
  items = posts;
  itemsPerPage = conf.postsPerArchivePage;
  title = "Posts";
};

8.2. nixpkgs

This namespace include the nixpkgs library and builtins functions.

8.3. content

This namespace contains functions to manipulate content, especially posts.


getPosts
Description

Fetch all the posts from a postDir.

Parameter Type

Standard

Parameters
  • postsDir: Path to the folder containing the posts.

  • outDir: Part before the name of the post attribute set href. Should not contain leading and trailing /.

Return

A list of post attribute sets.

Example
posts = getPosts conf.postsDir "posts";
The posts attribute sets href depends on the post file name and the outDir. For a post in a file 2016-09-12-welcome-to-styx.md and an outDir set to posts, the generated post href will be posts/2016-09-12-welcome-to-styx.html.

getDrafts
Description

Fetch all the posts from a postDir. This function is similar to getPosts, but add a isDraft = true attribute to every draft attribute set.

Parameter Type

Standard

Parameters
  • draftsDir: Path to the folder containing the drafts.

  • outDir: Part before the name of the draft attribute set href. Should not contain leading and trailing /.

Return

A list of draft attribute sets.

Example
posts = getDrafts conf.draftsDir;

parsePage
Description

Parse a markdown file to a partial page attribute set.

Parameter Type

Standard

Parameters
  • pageDir: Path to the folder containing the page.

  • filename: Page file name.

Return

An attribute set containing content (the page HTML source) and title.

Example
  about = {
    href = "about.html";
    template = templates.about;
    breadcrumbs = [ index ];
  } // (parsePage conf.pagesDir "about.md");

parsePost
Description

Convert a post file into a post attribute set.

Parameter Type

Standard

Parameters
  • postDir: Path to the folder containing the post.

  • filename: Post file name.

Return

A post attribute set.

Example
myPost = parsePost conf.postsDir "2016-09-12-welcome-to-styx.md";
parsePost is also used for drafts as posts and drafts have similar structures.

sortPosts
Description

Sort a list of posts chronologically.

Parameter Type

Standard

Parameters
  • postList: A list of posts to sort.

Return

The sorted list of posts.

Example
sortedPosts = sortPosts (getPosts conf.postsDir "posts");

8.4. template

This namespace contains functions to manipulate templates.


htmlAttr
Description

Generate an HTML attribute.

Parameter Type

Standard

Parameters
  • attrName: The attribute name.

  • value: The attribute value, can be a list.

Return

An HTML attribute.

Example
htmlAttr "class" "foo"
=> class="foo"

htmlAttr "class" [ "foo" "bar" ]
=> class="foo bar"

mapTemplate
Description

Map a template to a list of items.

Parameter Type

Standard

Parameters
  • template: The template function.

  • list: A list of items passed to the template function.

Return

Resulting HTML.

Example
mapTemplate templates.post.list page.posts

prettyTimestamp
Description

Convert a timestamp to a prettier format.

Parameter Type

Standard

Parameters
  • timestamp: A timestamp in the format YYYY-MM-DD.

Return

A timestamp in format DD MMM YYYY.

Example
prettyTimestamp "2016-09-26"
=> "26 SEP 2016"

8.5. utils

This namespace contains various utility functions.


overrideConf
Description

Extend the configuration attribute set.

Parameter Type

Standard

Parameters
  • conf: The configuration attribute set.

  • override: The override configuration set.

Return

Overridden configuration.

Example
conf = overrideConf (import ./conf.nix) args;

loadTemplateWithEnv
Description

Load a template with a template environment.

Parameter Type

Standard

Parameters
  • env: The template environment set.

  • template: The template file to load, relatively to conf.templatesDir.

Return

The template function.

Example
index = loadTemplateWithEnv { inherit conf state lib templates; } "index.nix";

setDefaultLayout
Description

Set a layout to a page attribute set. Does nothing if the page attribute set has already a layout.

Parameter Type

Standard

Parameters
  • layout: The layout template.

  • page: A page attribute set.

Return

A page attribute set with layout set.

Example
  pageList =
    let list = (pagesToList pages);
    in map (setDefaultLayout templates.layout) list;

setTemplate
Description

Set a template to a page attribute set.

Parameter Type

Standard

Parameters
  • template: The template function.

  • page: A page attribute set.

Return

The template function partially evaluated.

Example
map (setTemplate templates.post.full) (posts ++ drafts)

9. Cookbook

9.1. NavBar

The sample default.nix is setting a NavBar. Because the NavBar is a site wide feature is should be applied to the layout template (layout.nix).

Setting a Navbar consists in two steps:

  1. Extending the base template environment to include a list of pages that should be in the NavBar.

    Example from default.nix:

      navbar = let (1)
                 archive = (head pages.archives) // { title = "Archives"; }; (2)
               in [ archive pages.about ]; (3)
    
      templates.layout = loadTemplateWithEnv (4)
                         (genericEnv // { inherit navbar; feed = pages.feed; }) (5)
                         "layout.nix"; (6)
    1 Declaring a navbar variable.
    2 Declare an archive variable in the local scope. pages.archives is a list of pages so we extract the first page with head pages.archive, then we extends this page by setting a title using the // operator.
    3 The navbar value is a list containing the first archive page and the about page.
    4 Loading the templates.layout template file.
    5 The first parameter of the loadTemplateWithEnv must be an environment attribute set. genericEnv is the generic template environment, but as we want to pass the navbar variable to the template, we extends the environment with navbar.
    6 The template file to load.
    { inherit navbar; } is a shortcut to { navbar = navbar; }
  2. Using the NavBar template.

    Styx provides a template for generating the Navbar, navbar.main.nix.

    Example, calling the NavBar template in a template:

    ${templates.navbar.main navbar} (1)
    1 navbar must be a list of pages as showed in the previous section.
    The brand part of the NavBar displays conf.siteTitle by default. To set the NavBar brand to something different than conf.siteTitle, it is recommended to directly edit and change the navbar.brand.nix template.

9.2. Pagination

The pagination.nix template provide a generic way to generate a pagination.

Using in a page generated by the splitPage function
templates.pagination { pages = page.pages; index = page.index; }

The Styx library provide a splitPage function that can be used to split a page in multiple pages according to a list of items and a number of items to display per page.

Its arguments are:

  • baseHref: href of the archive pages, the first page href will be baseHref.html, following pages href will be baseHref-i.html where i is the index number of the page.

  • template: template used by the split pages.

  • items: items to be split through the pages.

  • itemsPerPage: maximum number of items displayed on each page.

Splitting posts into multiple archive pages
archives = splitPage {
  baseHref = "archives/posts";
  template = templates.archive;
  items = posts;
  itemsPerPage = conf.postsPerArchivePage;
  title = "Posts";
};

It is then possible to use the previous snippet in the used template to add a pagination.

9.3. Breadcrumbs

Breadcrumbs are enbaled by adding a breadcrumbs attribute with the list of pages to include in the breadcrumbs to a page attribute set. A page attribute set without a breadcrumbs attribute will not display breadcrumbs.

Adding breadcrumbs to a page
about = {
  href = "about.html";
  template = templates.about;
  title = "About";
  breadcrumbs = [ index ];
};

Breadcrumbs are generated with the breadcrumbs.nix template. The default base template include this template.

The text of the breadcrumb will be the page title. To set a breadcrumb title that is different of title, it is possible to use the breadcrumbTitle attribute.

10. Deployment

10.1. GitHub pages

Styx support basic deployment to github pages.

This is a two step process, initialization og the gh-pages branch and update of the gh-branch with the built site.

Setting a Styx site for GitHub pages
$ styx new mysite && cd mysite (1)
$ git init && git add . && git commit -m "Initializing Styx site" (2)
$ styx deploy --init-gh-pages (3)
$ styx deploy --gh-pages (4)
1 Creating a new styx site and entering the new site folder.
2 Initializing a git repository with all the files and commiting.
3 Creating an empty gh-pages branch.
4 Building the Styx site and commiting the changes to gh-pages

Then it is just a matter to push the gh-pages branch to your GitHub repository and the site will be published.

styx deploy --init-gh-pages and styx deploy --gh-pages involve git checkouts. Every time git make a checkout, the files timestamp change. This means that two successive styx deploy --gh-pages will create changes, namely every part of the Styx site that depends on the lastChange argument. (Feed by default)

10.2. 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. Release Notes

11.1. Styx 0.1.0 - 2016/10/7

Initial release of Styx.