Help » Tutorial

(If you already have a bit of experience with nanoc, you may find the Manual a very useful resource in addition to this tutorial.)

Installing nanoc

nanoc requires Ruby (1.8.5 or higher required). nanoc also requires RubyGems. You may already have RubyGems installed, but if you don’t, get it here.

Once you have RubyGems, installing nanoc is easy. Simply write this in your terminal:

> sudo gem install nanoc

Requirements for this Tutorial

This tutorial requires BlueCloth. BlueCloth is a Ruby implementation of Markdown, which allows you to write HTML in a easy-to-use plain text format (if you haven’t used Markdown before, don’t fear—it’s easy). To install BlueCloth, jump to your terminal and type:

> sudo gem install BlueCloth

Creating your First nanoc-powered Site

nanoc is a command-line application. This means that in order to use nanoc, you have to type geeky commands into a terminal all day. Hey, that’s the way all cool apps work (or maybe not).

A nanoc-powered site is a directory with a specific structure. In this tutorial, we’ll create a site named nanoc_test. To create this site, type into the terminal:

> nanoc create_site nanoc_test

If you did that right, you should have seen this appear on the screen:

create  config.yaml
create  Rakefile
create  tasks/default.rake
create  content/content.yaml
create  content/content.html
create  asset_defaults.yaml
create  page_defaults.yaml
create  layouts/default/default.yaml
create  layouts/default/default.html
create  templates/default/default.yaml
create  templates/default/default.html
create  lib/default.rb

The nanoc-powered site named nanoc_test has now been created. Go into the directory and list the files there. You should see something like this:

-rw-r--r--  1 ddfreyne  ddfreyne  123 16 Jul 19:13 Rakefile
-rw-r--r--  1 ddfreyne  ddfreyne   63 16 Jul 19:13 asset_defaults.yaml
drwxr-xr-x  2 ddfreyne  ddfreyne   68 16 Jul 19:13 assets
-rw-r--r--  1 ddfreyne  ddfreyne   71 16 Jul 19:13 config.yaml
drwxr-xr-x  4 ddfreyne  ddfreyne  136 16 Jul 19:13 content
drwxr-xr-x  3 ddfreyne  ddfreyne  102 16 Jul 19:13 layouts
drwxr-xr-x  3 ddfreyne  ddfreyne  102 16 Jul 19:13 lib
drwxr-xr-x  2 ddfreyne  ddfreyne   68 16 Jul 19:13 output
-rw-r--r--  1 ddfreyne  ddfreyne  136 16 Jul 19:13 page_defaults.yaml
drwxr-xr-x  3 ddfreyne  ddfreyne  102 16 Jul 19:13 tasks
drwxr-xr-x  3 ddfreyne  ddfreyne  102 16 Jul 19:13 templates

What all those directories are for, will be explained in just a minute, step by step.

Compiling the Site

Before doing anything else, make sure the current working directory is the site you just created. All nanoc commands, except for create_site, require the current working directory to be a nanoc site. So, if you haven’t done it before:

> cd nanoc_test

Every new nanoc site already has a bit of content. It comes with one simple page with some simple “getting started” instructions. Before you can view the site, it needs to be compiled. To compile the site, do this:

> nanoc compile

This is what’ll appear in the terminal when nanoc is done compiling:

Compiling site...
    create  [0.00s] output/index.html

Site compiled in 0.00s.

A file named index.html has been created in the output directory. Open it in your favourite web browser (mine is Safari); what you’ll see is something like this:

Screenshot of what a brand new nanoc site looks like

You can also open the output/index.html file in your favourite text editor, where you’ll find that the file is just a normal HTML page. No big surprise there.

Editing the Home Page

The first step in getting to know how nanoc really works will involve editing the content of the home page. First, though, a quick explanation of how uncompiled pages are stored.

The pages in a nanoc site are stored in the content directory. Currently, that directory has only two files: content.html and content.yaml. These two files together form the home page. The file ending with .yaml contain the page’s attributes (or metadata, or properties, or whatever you want to call it), while the other file contains the actual page content. This may sound confusing, but it’ll make more sense once more pages are added to the site. Patience, young padawan.

Let’s change the content of the home page. Open content.txt and add a paragraph somewhere in the file. I recommend something like this:

<p>This is a brand new paragraph which I've just inserted into this file!
Gosh, I can barely control my excitement!</p>

To view the changes, the site must be recompiled first. So, do this:

> nanoc compile

And this is what you’ll see:

Compiling site...
  update  [0.00s] output/index.html

Site compiled in 0.00s.

Note the numbers: the entire site was compiled in 0 seconds. No big surprise, considering there’s barely any content. Also note how nanoc prints the time spent compiling for each individual page as well.

Open index.html in the output directory in your web browser and your text editor again, and verify that the page has indeed been updated.

One thing that hasn’t changed is the page title—the title that appears in the browser’s title bar. The page title is defined in the page’s meta file. Such a meta file contains all metadata about the page, e.g. the layout that should be used for this page, the page title, the page’s author, when this page was created, … The homepage meta file, content.yaml, looks like this right now:

# Built-in

# Custom
title: Home

This file is split into two sections: Built-in and Custom. In the Built-in section, you can put metadata that is used by nanoc itself. For example, the layout attribute is used to determine which layout this page uses. (There’s a full list of built-in attributes in chapter 2 of the manual, which you definitely should check out at some point.)

The Custom section is for custom metadata that isn’t used by the nanoc compiler. Any attributes that aren’t built-in are custom. Custom metadata could include the page title, keywords relevant to this page, the name of the page’s author, the language the page is written in, etc.

The homepage’s meta file currently has one attribute, title. Change this to something cooler, like this:

title: "The Guild of nanoc: a fan website dedicated to nanoc"

Recompile the site and open index.html in your browser. You will see that the browser’s title bar displays the page’s title now. If you’re wondering how exactly nanoc knew that it had to update the stuff between the <title> and </title> tags: don’t worry. There’s no magic involved. It’ll all become crystal clear in a minute. (If you want to be spoiled: take a peek at layouts/default/default.html.)

Adding a Page

To create a new page in the site, use the create_page command. Let’s create an “about” page like this:

nanoc create_page about

You should see this:

create  content/about/about.yaml
create  content/about/about.html

There is now a content/about directory, with two files in it: the content file and the meta file. Open the content file (content/about/about.html) and put some text in it, like this:

<h1>My cute little "About" page</h1>

<p>This is the about page for my new nanoc site.</p>

Edit the meta file (the YAML one) so it looks like this:

# Built-in

# Custom
title: "The Guild of nanoc -- About the Guild"

Recompile the site, and notice that a file output/about/index.html has been created. Open that file in your web browser, and admire your brand new about page. Shiny!

Customizing the Layout

The default home page recommended editing the default layout, so let’s see what we can do there.

As you probably have noticed already, the page’s content files are not really HTML files—they are partial HTML files. A page needs <html>, <head>, <body>, … elements before it’s valid HTML. This doesn’t mean you’ve been writing invalid HTML all along, though, because nanoc layouts each page as a part of the compilation process.

Take a look in the layouts directory. It contains a directory default with two files, one called default.html and the other called default.yaml. These two files form the default layout of the web site, and is also the layout used by the home page and the about page.

Open default.html in your favourite text editor. It almost looks like a HTML page, with the exception of this piece of code:

...
<div id="main">
<%= @page.content %>
</div>
...

The odd construct in the middle of that piece of code is an embedded Ruby instruction. The <%= @page.content %> instruction will be replaced with the page’s compiled content when compiling.

If you are not familiar with embedded Ruby (also known as eRuby), take a look at the eRuby article on Wikipedia, or the Embedding Ruby in HTML section of the Ruby and the Web chapter of the online Programming Ruby book.

In fact—maybe you’ve noticed it already—there’s another important piece of embedded Ruby code near the top of the file:

<title>A Brand New nanoc Site - <%= @page.title %></title>

This is where the page’s title is put into the compiled document.

Every page can have arbitrary metadata associated with it. For example, you can set the author_name attribute to your own name, quite similar to how the title attribute is set. Some attribute names are reserved though, such as the content one (mentioned above), the path (which contains the page’s path), and a few others. Chapter 2 of the manual has a full list.

To demonstrate this, add the following line to the Custom section of the meta file (you could also add it to the Built-in section, but really, why would you want to do that?):

author: "John Doe"

Now output the author name in the layout. Put this piece of code somewhere in your layout (somewhere between the <body> and </body> tags, please, or you won’t see a thing):

<% unless @page.author.nil? %>
<p>This page was written by <%= @page.author %>.</p>
<% end %>

Recompile the site, and open the output/index.html and output/about/index.html pages in your browser. You’ll see that the about page has a line saying This page was written by John Doe, while the home page does not—as expected!

Writing Pages in Markdown

You don’t have to write pages in HTML. Sometimes, it is easier to use another language which can be converted to HTML instead. In this example, we’ll use Markdown to avoid having to write HTML. nanoc calls these text transformations filters.

Let’s get rid of the contents of the home page and replace it with some Markdown-formatted text. Open content/content.txt and put this in instead:

A First Level Header
====================

A Second Level Header
---------------------

Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.

The quick brown fox jumped over the lazy
dog's back.

### Header 3

> This is a blockquote.
> 
> This is the second paragraph in the blockquote.
>
> ## This is an H2 in a blockquote

Now open the homepage’s meta file and add this line to the “built-in” section:

filters_pre:
- "bluecloth"

filters_pre is an attribute with a list of filters to run before laying out the page. You can also run filters after laying out the page, in which case you’d use filters_post.

Now that we’ve told nanoc to filters this page using BlueCloth, let’s recompile the site. (If you are getting errors at this point, make sure you have BlueCloth installed, as described at the beginning of this tutorial). The output/index.html page source should now contain this text (header and footer omited):

<h1>A First Level Header</h1>

<h2>A Second Level Header</h2>

<p>Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.</p>

<p>The quick brown fox jumped over the lazy
dog's back.</p>

<h3>Header 3</h3>

<blockquote>
    <p>This is a blockquote.</p>

    <p>This is the second paragraph in the blockquote.</p>

    <h2>This is an H2 in a blockquote</h2>
</blockquote>

The BlueCloth filter is not the only filter you can use. For a list of filters included in the standard nanoc distribution, see chapter 2 of the manual. You can also write your own filters—read the Writing Filters section of chapter 3 in the manual for details.

Writing some Custom Code

There is a directory named lib in your nanoc site. In there, you can throw Ruby source files, and they’ll be read and executed before the site is compiled. This is therefore the ideal place to define helper methods.

As an example, let’s add some tags to a few pages, and then let them be displayed in a clean way using a few lines of custom code. Start off by giving the “about” page some tags. Open about.yaml and add this to the end of the “custom” section:

tags:
  - "foo"
  - "bar"
  - "baz"

Next, create a file named tags.rb in the lib directory (the filename doesn’t really matter). In there, put the following function:

def tags
  if @page.tags.nil?
    '(none)'
  else
    @page.tags.join(', ')
  end
end

This function will take the current page’s tags and return a comma-separated list of tags. If there are no tags, it returns “(none)”. To put this piece of code to use, open the default layout and add this line right above the <%= @page.content %> line:

<p>Tags: <%= tags %></p>

Recompile the site, and take a look at both HTML files in the output directory. If all went well, you should see a list of tags right above the page content.

Writing your own functions for handling tags is not really necessary, though, as nanoc comes with a tagging helper by default. To enable this tagging helper, first delete tags.rb and create a helper.rb file (again, the filename doesn’t really matter) and put this inside:

include Nanoc::Helpers::Tagging

This will make all functions defined in the Nanoc::Helpers::Tagging module available for use. You can check out the RDoc documentation for the Tagging helper, but there is only one function we’ll use: tags_for. It’s very similar to the tags function we wrote before. Update the layout with this:

<p>Tags: <%= tags_for(@page) %></p>

nanoc comes with quite a few useful helpers. The RDoc documentation describes each one of them.

Watch out for Paths

There’s one tricky thing involving paths that you need to know. To show you what can go wrong, let’s create a stylesheet named style.css in the output directory. Here’s what I put in there:

h1, h2, h3 { color: red; }

To link the stylesheet to the web site, open the layout (default.erb) and put this in:

<link href="style.css" rel="stylesheet" type="text/css">

When you compile the site now and open index.html, you’ll see that all headers are red. about/index.html’s headers, however, are not styled—the web browser looks for a about/style.css which doesn’t exist.

The most elegant solution is to use an absolute path, like this (note the new slash):

<link href="/style.css" rel="stylesheet" type="text/css">

The compiled files in the output directory will definitely not be styled now if you open them by double-clicking, but that’s okay—when the site is put on your web server, web browsers will find the stylesheet.

This would mean that you can’t preview your site locally anymore, but there’s a neat solution for that too. nanoc comes with an auto-compiler, which is a web server that compiles pages on-the-fly. More importantly, the output directory is its web root, so absolute paths are no issue anymore. To start it:

> nanoc aco

This starts a server on localhost, port 3000 (you can customize the port with -p if you want). Now you can go to http://localhost:3000/ and absolute paths will pose no problem anymore.

That’s it!

This is the end of the tutorial. I hope that this tutorial both whet your appetite, and gave you enough information to get started with nanoc.

There’s more reading material. It’s definitely worth checking out the Manual—it’s rather big, but it contains everything you need to know about nanoc.