1. Introduction
Styx is a functional static site generator written in Nix expression language.
Styx is aimed to be flexible and easy to customize. It is based on the Nix package manager, so it get many of its advantages: caching system, determinism to name a few. External applications can be used in Styx in a very easy way without having to install them by using the Nix package manager.
1.1. Styx Overview
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.
-
Flexibility: 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 preview (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 | Start a preview the site on a local server. |
Your styx site will be available at http://127.0.0.1:8080.
Now, take a look at the site.nix
to see how the site is defined. There are many comments, but in doubt check the site.nix section, it explains site.nix
in details.
4. Command line interface
The Styx provides a command line program styx
.
4.2. New
The new
command is used to create a new Styx site.
styx new
-
Create a Styx site in "styx-site" directory in current path.
styx-new -o "myblog"
-
Create a Styx site in
myblog
directory in current path. styx-new -o "myblog" --target /tmp
-
Create a Styx site in
myblog
directory in/tmp
.
4.3. 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.4. 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.
4.5. Live
The live
is similar to preview, with the unique difference that 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 preview --port 9090
-
Start a live preview server on 127.0.0.1:9090.
styx preview --port 9090 --drafts
-
Start a live preview server on 127.0.0.1:9090 with drafts rendered.
If the live mode is not quitted by pressing q, there is a possibility that the server process will stay alive in backgroud. The server process can be found by running ps aux | grep caddy and killed with the kill command.
|
4.6. 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 --detach
-
Will serve on the localhost on port
8080
and run the server on background, process can be found by runningps aux | grep caddy
.
The nix-build --show-trace , --arg NAME VALUE and --argstr NAME VALUE flags can be used with the serve command.
|
4.7. 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.
{
# Directory where templates are located
pagesDir = ./pages;
# Directory where posts are located
postsDir = ./posts;
# Directory where drafts are located
draftsDir = ./drafts;
# Directory where the themes are located
themesDir = ./themes;
# Directory where static files are located
staticDir = ./static;
# URL of the site, must be set to the url of the domain the site will be deployed
siteUrl = "http://yourdomain.com";
# Site title, used in the site header and the atom feed
siteTitle = "Styx Sample Site";
# Site description used in the base template
siteDescription = "Write a description for your new site here.";
# Maximum number of posts on the index page
postsOnIndexPage = 3;
# Maximum number of posts per archive page
postsPerArchivePage = 5;
}
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.
themesDir
-
Directory where themes are located.
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)
├── site.nix (2)
├── drafts/ (3)
├── lib/ (4)
├── pages/ (5)
├── posts/ (6)
├── templates/ (7)
└── themes/ (8)
1 | conf.nix is the main configuration, see Configuration for details. |
2 | site.nix is the main file for site generation, see site.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 | templates/ is the default directory containing templates files, see Templates for details. |
8 | themes/ is the default directory containing themes, see Themes for details. |
5.3. site.nix
site.nix
is the central file of a Styx site and is responsible for generating the website.
site.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.
|
The following sections will explain site.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.
It is not required to understand how the skeleton work to make a Styx site, so this section can be safely skipped.
site.nix
skeleton{ pkgs ? import <nixpkgs> {} (1)
, renderDrafts ? 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 files pagesList; } (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 | renderDrafts ? false means that renderDrafts 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 site.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 site.nix head: pkgs , renderDrafts , 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:
The order of declarations in the main logic part is not important and can be changed to fit preference.
Also the main logic part being in a let
block, it is possible to refer any of its variables at any position. (It is possible to use a variable before declaring it)
Setup
This part contains some boiler-plate code. New 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)
themes = [ "default" ]; (2)
state = { inherit lastChange; }; (3)
templates = lib.themes.loadTemplates { (4)
inherit themes defaultEnvironment customEnvironments;
themesDir = conf.themesDir;
};
files = lib.themes.loadFiles { (5)
inherit themes;
themesDir = conf.themesDir;
};
1 | Loading the main configuration file, conf.nix in a conf local variable. |
2 | Setting used themes, themes should be a list of theme names. |
3 | Setting a state local variable containing "impure" values. It contains only the lastChange variable coming from site.nix main function head. (Skeleton point 1)
lastChange value is automatically set by the Styx command. |
4 | Loading themes templates. |
5 | Loading themes static files. |
Templates declaration
Templates are automatically loaded via the theme system.
This section is reposible for setting custom template environments to specific templates. For more details on template environments, see Template environment.
defaultEnvironment = { inherit conf state lib templates; }; (1)
navbar = [ (head pages.archives) pages.about ]; (2)
customEnvironments = { (3)
layout = defaultEnvironment // { inherit navbar; feed = pages.feed; }; (4)
};
1 | This initialize a default 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. |
2 | This define a navbar local variable containing pages to include in the NavBar. For more details about Navbar setting, see the NavBar section. |
3 | customEnvironments should be a set with a similar structure to templates , but with keys that defines a custom environment for the template. Any template that is not part of customEnvironments will use the defaultEnvironment . |
4 | The environment passed to the layout template is the default 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. |
// 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, see the Breadcrumbs for details. |
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)
substitutions = { inherit conf; }; (4)
posts = getPosts { inherit substitutions; from = conf.postsDir; to = "posts"; }; (5)
drafts = optionals renderDrafts (getDrafts { inherit substitutions; from = conf.draftsDir; to = "drafts"; }); (6)
preparePosts = p: p // { template = templates.post.full; breadcrumbs = with pages; [ index (head archives) ]; }; (7)
in sortPosts (map preparePosts (posts ++ drafts)); (8)
};
pagesList =
let list = (pagesToList pages); (9)
in map (setDefaultLayout templates.layout) list; (10)
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 | Adding conf to the substitutions, see Substitutions for details. |
5 | Fetching the posts and setting their output path to posts . |
6 | Fetching the drafts only if renderDrafts is true . (by using the Styx command --drafts flag) |
7 | Declaring a preparePost function that take a post and extends it by setting a template and breadcrumbs. |
8 | 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. |
9 | generateSite needs a list of pages, so we convert the pages attribute set to a pagesList list with the pagesToList function. |
10 | 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 { dir = conf.pagesDir; file = "about.md"; });
parsePage return a set with title and content , the converted HTML source of the page.
|
6.2. Posts
Posts are a special type of pages that defines some extra attributes.
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:
-
title
: Post title -
content
: Post content in HTML format. -
href
: Relative URL to the post. -
timestamp
: Timestamp of the post in theYYYY-MM-DD-TITLE
format. -
id
: Name part of the post file name.
The getPosts function does not set template and layout keys. So posts generated by it are imcomplete pages, but these keys can be set afterwards.
|
6.3. Drafts
Drafts are a special type of posts that are generated when the --drafts
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:
-
title
: Post title -
content
: Post content in HTML format. -
href
: Relative URL to the post. -
timestamp
: Timestamp of the post in theYYYY-MM-DD-TITLE
format. -
id
: Name part of the post file name. -
isDraft
: set totrue
.
The only difference between posts and drafts is the presence of the isDraft attribute.
|
6.4. Substitutions
Subtitutions are a way to use some variables of site,nix
in mardown files.
Substitutions are a set that must be passed to the getPosts
, getDrafts
or parsePage
arguments.
default.nix
posts = let
substitutions = { inherit conf; }; (1)
posts = getPosts { inherit substitutions; from = conf.postsDir; to = "posts"; }; (2)
drafts = optionals renderDrafts (getDrafts { inherit substitutions; from = conf.draftsDir; to = "drafts"; }); (3)
preparePosts = p: p // { template = templates.post.full; breadcrumbs = with pages; [ index (head archives) ]; };
in sortPosts (map preparePosts (posts ++ drafts));
1 | Creating a subtitution set containing conf . { inherit conf; } is a shorhand for { conf = conf; } . |
2 | Pass the substitutions to getPosts argument set. |
3 | Pass the substitutions to getDrafts argument set. |
In the markdown file, substitutions are used by surround it by @
.
It impossible to use any nix expression in the substitution. |
Learn more in the [Styx 0.1.0 Documentation](@conf.siteUrl@/documentation-v0-1-0.html). (1)
1 | As conf is in the substitution set, it is possible to access any of its values by surrounding it by @ . |
7. Themes
Themes are used handle templates and static files and are the main way to customize Styx sites.
Styx comes with a simple default
theme.
7.1. Structure
Themes are stored in conf.themesDir
, themes
by default, and every theme is stored in its own directory.
themes
└── NAME (1)
├── files (2)
└── templates (3)
1 | Name of the theme. The name should be a valid folder name. |
2 | files is a folder holding static files for the themes. All the files in this folder will be copied in the generated site. |
3 | templates is a folder storing all the templates files. |
Every template in the templates
will be accessible by its file basename in the templates
attribute set.
Folders are converted to nested sets.
├── archive.nix
└── post
├── full.nix
└── list.nix
templates = {
archive = ./archive.nix;
posts = {
full = ./posts/full.nix;
list = ./posts/list.nix;
};
};
7.2. Themes in site.nix
Themes are declared as a list in the themes
variable.
themes = [ "default" ]; (1)
1 | The themes variable is a list of theme names, it is possible to set multiple themes. In that cases, themes at the head of the list have a higher priority. |
Themes related files are automatically loaded in site.nix
via the lib.themes.loadTemplates
and lib.themes.loadFiles
functions.
templates = lib.themes.loadTemplates { (1)
inherit themes defaultEnvironment customEnvironments;
themesDir = conf.themesDir;
};
files = lib.themes.loadFiles { (2)
inherit themes;
themesDir = conf.themesDir;
};
themes = [ "default" ];
1 | Load themes templates. See loadFiles for details. |
2 | Load themes files. See loadTemplates for details. |
7.3. Combining Themes
In site.nix
, themes are declared as a list. If multiple themes in the list provide the same file or template, the one from the first theme to declare it will be used.
This allows to "extends" themes without modifying them.
For example, to use the default theme but only change the layout
template. It is possible to create a new theme, and copy the layout.nix
template in the new theme templates
folder and change only this file.
$ mkdir themes/foo (1)
$ mkdir themes/foo/{templates,files} (2)
$ cp themes/{default,foo}/templates/layout.nix (3)
1 | Create the theme directory. |
2 | Create the theme required directories. |
3 | Copying default theme layout.nix to foo theme. |
After a new theme has been created, it must be load in the site.nix
to be used.
site.nix
themes = [ "foo" "default" ]; (1)
1 | This will use foo and default theme, with foo having a higher priority than default. |
8. 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 and generates 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.
8.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}!"
8.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.
|
8.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; }
In some cases, it is useful to have the partial template to return the final source of the page.
By setting the page layout to the id function, it is possible to bypass the layout template and have the partial template result being the final source source of the page.
|
8.4. Template environment
The template environment is the first parameter of the template function.
It is defined when loading the template in site.nix
.
The default template environment consists in:
-
conf
: the configuration attribute set -
lib
: the library attribute set, it contains Styx and nixpkgs functions. -
state
: the state attribute set, by default it only holds the timestamp of the generation -
templates
: the templates attribute set
It is possible to extend the default template environment to fit custom needs.
It is possible to set a specific template environment to a specific template by declaring it in the customTemplateEnvironments
set.
customEnvironments = {
layout = defaultEnvironment // { inherit navbar; feed = pages.feed; }; (1)
};
1 | The environment passed to the layout template is the default environment extended with feed and navbar variables. |
8.4.1. Template environment in templates
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. |
8.5. 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. |
9. 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.
9.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
site.nix
. - Parameter Type
-
Set
- Parameters
-
-
files
: A list of folders to copy in the site. -
pagesList
: 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 pagesList; }
pagesToList
-
- Description
-
Convert an attribute set of pages to a list of pages. Useful to convert the
pages
attribute set insite.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"); }; pagesList = 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"; };
9.2. nixpkgs
This namespace include the nixpkgs library and builtins functions.
9.3. content
This namespace contains functions to manipulate content, especially posts.
getPosts
-
- Description
-
Fetch all the posts from a
postDir
. - Parameter Type
-
Attribute Set
- Parameters
-
-
from
: Path to the folder containing the posts. -
to
: Part before the name of the post attribute sethref
. Should not contain leading and trailing/
. -
substitutions
: An attribute set containing substitutions (Optional). For details, see Substitutions.
-
- Return
-
A list of post attribute sets.
- Example
posts = getPosts { from = conf.postsDir; to = "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
-
Attribute Set
- Parameters
-
-
from
: Path to the folder containing the posts. -
to
: Part before the name of the post attribute sethref
. Should not contain leading and trailing/
. -
substitutions
: An attribute set containing substitutions (Optional). For details, see Substitutions.
-
- Return
-
A list of draft attribute sets.
- Example
posts = getDrafts { from = conf.draftsDir; to = "drafts"; };
parsePage
-
- Description
-
Parse a markdown file to a partial page attribute set.
- Parameter Type
-
Attribute Set
- Parameters
-
-
dir
: Path to the folder containing the page. -
file
: Page file name. -
substitutions
: An attribute set containing substitutions (Optional). For details, see Substitutions.
-
- Return
-
An attribute set containing
content
(the page HTML source) andtitle
. - Example
about = { href = "about.html"; template = templates.about; breadcrumbs = [ index ]; } // (parsePage { dir = conf.pagesDir; file = "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");
9.4. template
This namespace contains functions useful in 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"
9.5. themes
This namespace contains functions to load themes data.
loadFiles
-
- Description
-
Load a themes set static files.
- Parameter Type
-
Attribute set
- Parameters
-
-
themes
: List of themes names to load static files from. -
themesDir
: Directory of the themes.
-
- Return
-
List of static files folders.
- Example
files = lib.themes.loadFiles { themes = [ "default" ]; themesDir = conf.themesDir; };
loadTemplates
-
- Description
-
Load a theme set templates.
- Parameter Type
-
Attribute set
- Parameters
-
-
themes
: List of themes names to load static files from. -
themesDir
: Directory of the themes. -
defaultEnvironment
: The default environment to load templates with. -
customEnvironments
: A set of with a similar structure to the template set which values are environment to pass to the template. Any template that is not incustomEnvironments
will use thedefaultEnvironment
.
-
- Return
-
List of static files folders.
- Example
templates = lib.themes.loadTemplates rec { themes = [ "default" ]; themesDir = conf.themesDir; defaultEnvironment = { inherit conf state lib templates; }; customEnvironment = { layout = defaultEnvironment // { inherit navbar; feed = pages.feed; }; }; };
9.6. 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;
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
pagesList = 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)
10. Cookbook
10.1. NavBar
There is an example of NavBar setting in the default site.nix
.
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
site.nix
:navbar = let (1) archive = (head pages.archives) // { title = "Archives"; }; (2) in [ archive pages.about ]; (3) customEnvironments = { (4) layout = defaultEnvironment // { inherit navbar; feed = pages.feed; }; (5) };
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 Declares custom template environments. Custom environements are a set mimicking the templates atteibute set, ut where the value is the environment to apply to the template. 5 defaultEnvironment
is the default template environment, but as we want to pass thenavbar
variable to the template, we extends the environment withnavbar
.{ 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.
10.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.
The pagination is only displayed if there is more than one page to display. |
10.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.
11. Deployment
11.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)
|
12. Release Notes
12.1. 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
preview
subcommand to preview a site locally -
new
live
subcommand to preview and automatically reload changes -
serve
subcommands new flags: -
--detach
to launch the server in a background process -
--server-host
to specify the server listening hostname -
--siteUrl
to overrideconf.siteUrl
-
new
-target
flag to specify the Styx site folder -
content substitutions (Substitutions)
-
themes (Themes)
-
metadata (Metadata)
-
404 error page template
Incompatible changes:
-
default.nix
was renamed tosite.nix
-
site.nix
previewMode
was renamed torenderDrafts
-
cli
--preview
flag has been renamed to--drafts
-
lib.content
:getPosts
,getDrafts
andparsePage
arguments have changed -
lib.generation
:generateSite
arguments have changed -
lib.utils
:loadTemplateWithEnv
function was removed
Bug Fixes:
-
nix link in the default theme layout template
-
styx new
is working when called in empty folders -
default theme archive title is not hardcoded
-
default them pagination is displayed only when there is more than one page
This release bring many major changes that make updating from 0.1.0 non-trivial.
To update, it is recommended to generate a new site, create a new theme with customized templates and static files, and update site.nix
accordingly.