Help » Manual »
Chapter 2: Using nanoc
« Back to the Manual Table of Contents
The commandline tool ¶
Interacting with nanoc happens through a commandline tool aptly named nanoc. nanoc has a few sub-commands, which you can invoke like this:
> nanoc command
Here, command obviously is the name of the command you’re invoking. A very useful command is the help command, which will give you a detailed description of a given command. You can use it like this:
> nanoc help command
For example, this is the help for the create_site command:
> nanoc help create_site
nanoc create_site [path]
aliases: cs
create a site
Create a new site at the given path. The site will use the filesystem
data source (but this can be changed later on). It will also include
a few stub rakefiles to make adding new tasks easier.
options:
-d –datasource specify the data source for the new site
If you want general help, such as a list of available commands and global options, omit the command name, like this:
> nanoc help
So, if you’re ever stuck, consult the the commandline help which (hopefully) will put you back on track.
Sites ¶
A site managed by nanoc is a directory with a specific structure. A site consists of pages, assets, layouts, templates, and more.
The way the data in a site is stored depends on the data source that is being used. However, unless you’ve explicitly told nanoc to use a different data source, the filesystem one will be used. This manual assumes that this filesystem data source is used. For details, see the Data Sources section.
Creating a Site ¶
To create a site, use the create_site command. This command takes the site name as its first and only argument, like this:
> nanoc create_site site_name
This will create a directory with the given site name, with a bare-bones directory layout.
Site Configuration ¶
The site configuration is defined by the config.yaml file at the top level of the site directory. The file is in YAML format.
data_source- Defines the data source that should be used for this site. Possible values are the identifiers for the data sources. It defaults to filesystem. See the Data Sources section for details.
index_filenames- Defines the list of filenames that should be stripped off paths. This list will usually contain only “index.html”, but depending on the production web server used, this may differ. Defaults to a list containing only “index.html”.
output_dir- Defines the path to the output directory. If the path does not start with a slash, it is assumed to be a path relative to the nanoc site directory. It defaults to output.
router- Defines the router that should be used for this site. Possible values are the identifiers for the routers. It defaults to default (surprisingly). See the Routers section for details.
Custom data sources, filters and routers may use other configuration attributes. Check their documentation for details.
(Auto)compiling a Site ¶
To compile a site to its final form, the nanoc compile or simply nanoc co command is used. This will write the compiled site to the output directory as specified in the site configuration file. For example:
> nanoc co
It is possible to let nanoc run a local web server that serves the nanoc site. Each request will cause the requested page to be compiled on the fly before being served. To run the autocompiler, use nanoc autocompile or nanoc aco.
The autocompiler will run on port 3000 by default. To change the port number, use the -p or --port commandline switch, like this:
> nanoc aco -p 8080
Note that this autocompiler should only be used for development purposes to make writing sites easier; it is quite unsuitable for use on live servers.
Pages ¶
The basic building blocks of a nanoc-powered site are obviously the pages. A page consist of content and metadata attributes. There are two kinds of attributes:
- extra information about the page, such as the page title, the e-mail address of its author, …
- processing information, such as the list of filters to run, the layout that should be used, …
Pages are structured hierarchically. A page has a path, which reflects this hierarchy. There is one “root” or “home” page which has path /; other pages will have paths such as /journal/2008/some-article/.
Pages have an output path or disk path which is the path where the compiled page will be written to. It includes the terminating “index.html”. The web path is the disk path with the trailing index filenames removed (usually index.html). The hierarchy of outputted pages does not have to be the same as the hierarchy of uncompiled, raw pages; see the Routers section for details.
Creating a Page ¶
Pages can easily be created manually: simply create the page directory along with its meta-file and content-file items.
To create a page using the commandline, use nanoc create_page or nanoc cp. This command takes one argument: the page name. This page name is relative to the webroot. For example, to create a page named “bar” with “foo” as parent page, do this:
> nanoc create_page foo/bar
To specify a custom template for creating this page (see the Templates section for details), use the -t or --template commandline switches. The following example will make a page with the “article” template:
> nanoc create_page blog/2007/new-article --template=article
Representations ¶
Pages (and assets) can have multiple representations. Each representation (or “rep”) corresponds to a single output file. Each representation has a name, which may be used by routers for determining a page rep’s path.
Each representation can have its own set of built-in attributes. Attributes that are not specified in the representation will be inherited from the page this rep belongs to. Each representation can have custom attributes as well.
Each page always has at least one representation. If no explicit list of representations is given, there will still be a representation named “default”. It is therefore possible to ignore the multiple representations feature completely; simply add the attributes to the page instead of the default rep.
A page’s representations are specified in the reps hash of the page itself. The keys of this hash are the representation names, while the values are a hash containing this representation’s attributes, which are very similar to the attributes of a page with only an implicit default representation.
For example, this page will have two representations: a “default” one (which inherits its list of filters, its layout, … from the page defaults), and a “raw” one (no filters, no layout):
reps:
default: {}
raw:
filters_pre: []
filters_post: []
layout: none
extension: 'txt'
Compilation ¶
Compiling a page involves compiling all of its representations, which in turn involves performing the following steps on each representation:
- Running the pre-layout filters
- Laying out
- Running the post-layout filters
A page representation does not need to have a layout: it can be set to “none” in its attributes, which will skip the layout step. Similarly, a page rep’s list of pre-layout and post-layout filters can be empty.
The following diagram illustrates page compilation by giving a few examples of how pages can be filtered and laid out.
Pages have dependencies on other pages when one page requires the content of another page. Such dependencies are resolved automatically by nanoc. Circular dependencies (page “A” requiring the content of page “B” and vice versa) are detected.
By default, page representations will not be recompiled unless they are outdated. This provides a noticeable speedup, especially for large sites. The commandline tool’s compile and autocompile commands accept a -a or --all switch, which recompiles pages even if they are not outdated. A page rep is deemed to be outdated when any of the following conditions are true:
- the compiled page doesn’t exist
- the source page has been modified
- a layout has been modified
- the page defaults have been modified
- the site code been modified
Dependencies between pages cannot, however, be resolved without recompiling all pages. If page “A” contains the content of page “B”, and “B” is deemed to be outdated but “A” is not, then even though page “B“‘s content will have changed, page “A“‘s content will not. It is therefore a good idea to force recompile all pages before deploying.
Attributes ¶
Each page has attributes (also called “meta-data”) associated with it. This metadata consists of key-value pairs, which are stored in YAML format (although this may vary for different data sources).
There are two kinds of attributes. Processing attributes are used by nanoc to determine how this page should be compiled (for example: the list of filters to run). Informative attributes are not used by nanoc itself, but the site can make use of them (for example: a list of keywords for a page).
There are no separate namespaces for processing attributes and informative attributes. Therefore, you should be careful not to use a processing attribute name as an informative attribute.
The processing attributes are:
- custom_path
- A custom path to which the file will be compiled to, starting with a slash. For example, a Sitemaps file could have a custom path of /sitemaps.xml. Defaults to
nil(no custom path). - extension
- The extension of the compiled page. Defaults to
"html". - filename
- The base filename for the generated page. Useful on web servers where the default filename is not “index.html” but “default.html”, for example. Defaults to
"index". - filters_pre
- A list of filters to run before laying out the page. Defaults to
[](no filters). - filters_post
- A list of filters to run after laying out the page. Defaults to
[](no filters). - is_draft
- Whether this page is a draft or not. Draft pages are ignored during compilation; it is as if they never existed. Can be
trueorfalse. Defaults tofalse. - layout
- The name of the layout to use for this page. This is the filename of the layout file, minus the erb extension. Use
"none"when you don’t want a layout. Defaults to"default"(surprisingly). - skip_output
- Whether this page will be outputted or not. Pages with skip_output set to
truewill not be written. Can betrueorfalse. Defaults tofalse.
Some filters may use other attributes. When using these filters, be sure to check their documentation (see below) to see what attributes they use, if any.
Variables ¶
When compiling pages with filters that support adding code to the page or the layout (such as ERB and Haml), several variables are made available. These variables are:
- @page_rep
- The page representation that is currently being compiled.
- @page
- The page that is currently being compiled.
- @pages
- The list of all pages, including ones that have not yet been compiled.
- @assets
- The list of all assets, including ones that have not yet been compiled.
- @layouts
- The list of all layouts.
- @config
- The site configuration as a hash.
- @site
- The site.
To get a page attribute, access it as if it were a method, e.g. @page.author. Boolean variables can have a trailing question mark appended, e.g. @page.display_sidebar?.
Pages have the following attributes available at compile time:
- mtime
- The time when the page was last modified.
- parent
- The parent of this page. The root page will have a
nilparent. - children
- A list of child pages. This may be an empty array.
- content
- The compiled but not yet laid out content of the page. If the page is not yet available, nanoc will compile the requested page first.
- path
- The page’s path relative to the web root, with leading and trailing slashes, e.g. /blog/.
To get a page representation with a specific name, use the #reps method with the rep name as argument. For example, to get the “raw” representation:
raw_rep = @page.reps(:raw)
Assets ¶
Assets are content elements that are not pages, such as images, stylesheets, movies, sounds, etc. There are two kinds of assets: binary and textual; both have their own kinds of filters. Assets are not laid out.
Assets are only filtered and not laid out. Textual assets use normal textual filters, while binary assets use binary filters.
Assets can have multiple representations. Multiple asset representations work exactly like multiple page representations, and is therefore not documented here.
Attributes ¶
Assets have the following built-in attributes:
- binary
- A flag indicating whether the asset is binary or not.
- filters
- A list of filters to run before laying out the page. Defaults to
[](no filters).
Layouts ¶
On itself, a page’s content is not valid HTML yet: it lacks the structure a typical HTML document has. A layout is used to add this missing structure to the page.
For a layout to be useful, it must output the page’s content at a certain point. This is done by outputting @page.content. This extremely minimal layout show an example of how this is usually done:
<html>
<head>
<title><%= @page.title %></title>
</head>
<body>
<%= @page.content %>
</body>
</html>
As Partials ¶
Layouts can also be used as partials: a specific layout can be rendered into a page or a layout by using the render function, which takes the layout name as an argument. For example:
<%= render 'head' %>
It is also possible to pass custom variables to rendered partials by putting them into a hash passed to render. The following example will make a @title variable (set to “Foo” in this example) available in the “head” layout:
<%= render 'head', :title => 'Foo' %>
Templates ¶
Templates are basic page skeletons used when creating a page. For example, an article template could have the basic content file and meta file structure laid out to make it easier to write an article.
When a page is created using a custom template, nanoc will create the page and copy the template’s meta and content files to the page’s meta and content files, respectively. The page’s content file will have the same extension as the template’s content file.
To create a page using a custom template, use the -t or --template commandline switch. For example, this will create a page using the article template:
> nanoc create_page blog/new-article --template=article
Templates can be created by using the create_template command.
Filters ¶
Filters are used for transforming a page’s content. For example, the ERB filter interprets the page’s content as text with embedded Ruby, executes the embedded Ruby and returns the result.
Filters can be both pre-filters and post-filters. Pre-filters are run before the page is laid out, while post-filters are run after a page has been laid out. Pre-filters and post-filters are specified by the filters_pre and filters_post attributes in a page’s metadata, respectively.
Each filter has one or more identifiers, as specified in the list below. To use a filter, put its identifier in the list of filters in a page’s attributes.
List of Built-in Filters ¶
bluecloth- for Markdown (uses BlueCloth)
discount- for Markdown (uses Discount)
erb- for embedded Ruby (uses ERB)
erubis- for embedded Ruby (uses Erubis)
haml- for Haml
markaby- for Markaby
maruku- for Markdown (uses Maruku)
rdoc- for RDoc’s Simple Markup
redcloth- for Textile (uses RedCloth)
rubypants- for SmartyPants (uses RubyPants)
The Haml filter uses the haml_options page attribute, which will be converted to a hash and passed to Haml::Engine when a page is filtered.
Plugins ¶
nanoc will load all Ruby source files in the lib directory before it starts compiling. All method definitions, class definitions, etc. will be available during the compilation process. This directory is therefore quite useful for putting in site-wide helper methods.
The lib/ is also the place where you should put site-specific filters and routers. Simply drop the Ruby source files in there, and you’re set.
Helpers ¶
nanoc comes with a handful of useful helpers which provide methods that can be called in pages and layouts.
These helpers have to be activated manually, except for the HTMLEscape and Render helpers, which are activated by default for backward compatibility reasons. To activate a helper, include it, like this:
include Nanoc::Helpers::Blogging
Here is a list of helpers bundled with nanoc:
Nanoc::Helpers::Blogging- provides blogging and Atom feed features (documentation)
Nanoc::Helpers::Capturing- provides functionality for capturing content and reusing it elsewhere (documentation)
Nanoc::Helpers::HTMLEscape- provides a HTML escaping function (documentation)
Nanoc::Helpers::LinkTo- provides
link_toandlink_to_unless_currentfunctions (documentation) Nanoc::Helpers::Render- provides functionality for rendering layouts as partials (documentation)
Nanoc::Helpers::Tagging- provides functionality for printing a page’s tags (documentation)
Nanoc::Helpers::XMLSitemap- provides functionality for creating XML sitemaps (documentation)
Routers ¶
Routers determine the disk paths of page representations. Given a page rep, the router will return both its disk and web paths. Each site has a router; chosing a router for a site is done in the site configuration.
nanoc comes with three routers by default:
default- The default router creates a directory for every page. The representation name is appended to non-default reps. Assets do not get their own directory. Read documentation.
versioned- The versioned router behaves similarly to the default router, but appends a version number. Read documentation.
no_dirs- The no-dirs router does not create directories unless necessary. For example, a page with path /about/ will be written to /about.html instead of /about/index.html.Read documentation.
See the Writing Routers section of Chapter 3 for information about writing custom routers.
Data Sources ¶
Each site has a data source—a plugin that determines where to read the data for the site from, and where to write new pages and page templates. By default, nanoc uses the filesystem data source, which means pages, layouts, etc. are stored as flat files on disk.
It is not possible to create a site with a specific data source. It is possible, however, to switch an existing site to a new data source. How to do this is specific for each data source, so check out the documentation for the data source you want to switch to.
Filesystem Data Source ¶
The filesystem data source is the default data source. New nanoc-powered sites automatically use it. This data source does not require any special configuration.
This manual assumes that the filesystem data source is used. The differences between the filesystem and the filesystem-combined data source are listed in the database data source section.
For more information, see the Filesystem RDoc documentation.
FilesystemCombined Data Source ¶
The filesystem-combined data source is similar to the filesystem one, except that metadata is stored inside the content files, therefore making it unnecessary for pages to be stored in separate directories. This makes the number of files and directories quite a bit lower than with the filesystem data source.
The metadata for a page is embedded into the file itself. It is stored at the top of the file, between five dashes. For example:
-----
filters_pre: [ 'redcloth' ]
-----
h1. Hello!
For more information, see the FilesystemCombined RDoc documentation.
Tasks ¶
The tasks directory contains rakefiles (see the Rake documentation) that will be accessible to rake when you run rake in the site’s directory. The rakefiles’ names must end with .rake in order to be recognised correctly.