Blog tutorial
Create a new site
First, we will use the styx new
command to generate files required for a new site:
$ styx new site my-blog
$ cd my-blog
The styx new site
will generate the following file structure:
my-blog
├── conf.nix
├── data
├── readme.md
├── site.nix
└── themes
The most important file is site.nix
, it contains all the logic to generate our site.
Declare Themes
In site.nix
, find the line declaring the themes:
themes = [
];
And change it to the following to load the Hyde and generic templates themes. (Hyde requires the generic templates theme)
Later themes in the list have higher priority.
themes = [
styx-themes.generic-templates
styx-themes.hyde
];
Create an index page
Next, we will create an index page, in site.nix
find the line declaring the pages
attribute set:
pages = rec {
};
And let’s add an index page, a page is an attribute set defining at least template
, layout
and path
:
pages = rec {
index = {
title = "Home";
path = "/index.html";
template = templates.index;
layout = templates.layout;
};
};
The site can be previewed by running styx preview
:
$ styx preview
The site will be accessible at http://127.0.0.1:8080.
To end the preview, hit Ctrl+C
.
If anything goes wrong during the preview, you can use the --show-trace
flag to make styx print a debug trace:
$ styx preview --show-trace
Create data
Our index page should list our blog posts, so we will need to generate some data and create pages in our new blog.
Then gen-sample-data
command that will generate some data for us:
$ styx gen-sample-data
This generate the following data:
data
└── sample
├── pages
│ └── about.md
└── posts
├── 2016-09-13-drafts.md
├── 2016-09-14-pages.md
├── 2016-09-15-data.md
├── 2016-09-16-themes.md
├── 2016-09-17-media.md
├── 2016-09-18-features.md
└── 2016-09-19-blog-tutorial.adoc
Adding a page
In the sample data, there is an about page. Lets add it to our site.
First we need to load its data, is a single file, so we will use loadFile
:
Find the following line declaring the data
set:
data = {
};
And change it to load the about page data:
data = {
about = lib.loadFile { file = ./data/sample/pages/about.md; inherit env; };
};
And the page in the pages
set:
pages = {
index = {
title = "Home";
path = "/index.html";
template = templates.index;
layout = templates.layout;
};
about = data.about // {
path = "/about.html";
template = templates.page.full;
layout = templates.layout;
};
};
To make the page easily accessible, we can add an entry in the sidebar for the about page by adding a menu
to our data
:
data = {
about = lib.loadFile { file = ./data/sample/pages/about.md; inherit env; };
menu = [ pages.about ];
};
We can preview the site again with the styx preview
command and verify that there is a link for the about page in the sidebar.
Add posts
Next we can add our posts, lets add a posts
attribute to the data
set:
data = {
about = lib.loadFile { file = ./data/sample/pages/about.md; inherit env; };
menu = [ pages.about ];
posts = lib.sortBy "date" "dsc" (lib.loadDir { dir = ./data/sample/posts; inherit env; });
};
loadDir
load all the data inside a directory and sortBy
sort it.
To generate pages, we need to add them to the pages
attribute set.
In the pages
set, add the posts:
pages = rec {
index = {
title = "Home";
path = "/index.html";
template = templates.index;
layout = templates.layout;
};
about = data.about // {
path = "/about.html";
template = templates.page.full;
layout = templates.layout;
};
posts = lib.mkPageList {
data = data.posts;
pathPrefix = "/posts/";
template = templates.post.full;
layout = templates.layout;
};
};
mkPageList
takes a list of data and generate a list of pages.
Lets preview our site again:
$ styx preview
Posts are generated, but are not listed on the index page yet.
Index page revisited
Hyde is designed so the most recent posts appears on the index page, and older posts are on archive pages.
So we need to split our posts between the index and archive pages.
There is a mkSplit
function that does just that.
So we will adapt our index page declaration to use it:
pages = rec {
index = lib.mkSplit {
title = "Home";
basePath = "/index";
itemsPerPage = conf.theme.itemsPerPage;
template = templates.index;
data = posts.list;
layout = templates.layout;
};
...
};
mkSplit
takes a list of data
and make multiple pages of itemsPerPage
item each.
Pages path is automatically generated by using basePath
.
Lets preview our site again:
$ styx preview
Posts are listed on the index page, and archive pages are also generated, all good.
Adding an atom feed
Next step is adding an atom feed.
To do so, we just need to create a page:
pages = {
...
feed = {
path = "/feed.xml";
template = templates.feed.atom;
layout = lib.id;
items = lib.take 10 posts.list;
};
};
Checking the links
Styx have a linkcheck functionality that check internal links of a site:
$ styx linkcheck
Improvements
Customizing our site
The Hyde theme provide some configuration options that can be used to customize our blog.
The following command will generate a documentation for our site, so we can check the avalaible theme options:
$ styx site-doc
To change the theme options, edit conf.nix
at site root and find the following line:
theme = {
};
And change it to:
theme = {
site.title = "My Styx Blog";
colorScheme = "0d";
itemsPerPage = 5;
};
Let’s preview our site and see what changed.
There are a few posts using source code examples, it would be nice to have syntax highlighting.
Syntax highlighting can also be enabled via the configuration interface:
theme = {
site.title = "My Styx Blog";
colorScheme = "0d";
itemsPerPage = 5;
lib.highlightjs = {
enable = true;
style = "monokai";
extraLanguages = [ "nix" ];
};
};
Cleaning up
All of our pages are declaring the same layout
.
It is possible to set attributes to every page when converting our page set to a page list.
In site.nix
find:
pageList = lib.pagesToList { inherit pages; };
Let’s add the default layout here:
pageList = lib.pagesToList { inherit pages; default = { layout = templates.layout; }; };
And remove all the layout
declarations using templates.layout
of our pages:
pages = rec {
index = lib.mkSplit {
title = "Home";
basePath = "/index";
itemsPerPage = conf.theme.itemsPerPage;
template = templates.index;
data = posts.list;
};
posts = lib.mkPageList {
data = data.posts;
pathPrefix = "/posts/";
template = templates.post.full;
};
about = data.about // {
path = "/about.html";
template = templates.page.full;
layout = templates.layout;
};
feed = {
path = "/feed.xml";
template = templates.feed.atom;
layout = lib.id;
items = lib.take 10 posts.list;
};
};