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.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.
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)
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 = { (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 = 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. |
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 thetemplate
keys. -
The
template
key is a function that take thepage
attribute set as a parameter and return the page attribute set augmented with acontent
key representing the result of the template. -
The
layout
key is a function take a page attribute set with acontent
key, returned by the thetemplate
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.
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. |
pages.about // { breadcrumbs = [ pages.index ]; }
Page content can be directly set in the template, or imported from an external file with the parsePage
function:
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 theYYYY-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 theYYYY-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 totrue
.
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.
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. |
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 ${…}
.
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.
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: (1)
page:
''
${environment.conf.siteTitle}
''
1 | environment is used as a set, and its key can be accessed with . . |
{ 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.
{ 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. |
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 indefault.nix
to a page list forgenerateSite
. 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
: Thehref
of the archive pages, the first pagehref
will bebaseHref.html
, following pageshref
will bebaseHref-i.html
wherei
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 sethref
. 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 togetPosts
, but add aisDraft = 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 sethref
. 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) andtitle
. - 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 formatYYYY-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 toconf.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:
-
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 withhead pages.archive
, then we extends this page by setting atitle
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 thenavbar
variable to the template, we extends the environment withnavbar
.6 The template file to load. { inherit navbar; }
is a shortcut to{ navbar = navbar; }
-
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 thanconf.siteTitle
, it is recommended to directly edit and change thenavbar.brand.nix
template.
9.2. Pagination
The pagination.nix
template provide a generic way to generate a pagination.
splitPage
functiontemplates.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 pagehref
will bebaseHref.html
, following pageshref
will bebaseHref-i.html
wherei
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.
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.
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.
$ 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)
|