Nanoc

Internals

This document describes some of the internal workings of Nanoc. The audience of this document is potential contributors to Nanoc. You do not need to read or understand this document in order to use Nanoc.

This document is a work in progress. It’s highly incomplete, but will gradually be expanded to include more detail.

Outdatedness checking

Nanoc is a smart static-site generator; it avoids recompiling items unless necessary.

Nanoc will recompile an item if it is deemed to be outdated. The class responsible for determining whether or not an item is outdated is the OutdatednessChecker. An item is considered as outdated if any of the following conditions hold:

  • The item’s content has changed
  • The item’s attributes have changed
  • The site configuration has changed
  • The rule for this item has changed
  • Some output files for this item do not exist
  • A dependent item or layout is considered as outdated

The last condition is necessary, because an item might use data of another item or layout.

Dependency tracking

If an item uses data from another item or layout, Nanoc will record a dependency from the former item onto the latter item or layout. This type of dependency is used purely to infer outdatedness of items, and is called a soft dependency. Nanoc records a dependency when the raw content, the compiled content, attributes, or a path of another item or layout is accessed.

For example, the following code snippet will generate dependencies from the item that is currently being compiled, onto other items:

<!-- Creates a dependency on the /about.* page -->
See the <%= @items['/about.*'][:title] %> page.

<!-- Creates a dependency on every item -->
See the <%= @items.select { |i| i[:title] =~ /About/ }.first %> page.

For every dependency, Nanoc remembers which of the following properties are affected by the dependency:

  • the raw content
  • the attributes
  • the compiled content
  • the path

An item will only be considered as outdated due to dependencies when the dependencies’ properties match the outdatedness reason of the targets of the dependency.

For example, an attribute dependency on an item that is marked as outdated due to an attributes change will cause the source of the dependency to be considered as outdated:

Outdated: item has an attribute dependency on an item whose attributes have changed

If, on the other hand, the dependency were a dependency on the raw content rather than the attributes, the source of the dependency would not be considered as outdated:

Not outdated: item has a raw content dependency on an item whose raw content has not changed

Compilation order

The order in which item representations are compiled, depends on the dependencies on compiled content between individual item representations.

Dependencies on compiled content

An item representation can depend on the compiled content of another item representation. For example, blog archive pages typically tend to contain (snippets of) the content of individual blog posts. An item representation which contains the compiled content of another item representation cannot be compiled until the compiled content of the dependent item representation is available. If this compiled content is not available and Nanoc tries to compile the item representation, then the compilation is suspended.

It is normal for the compilation for an item to be suspended. It merely indicates that the dependent item representation should be compiled first. The dependencies of an item representation are not known until Nanoc has finished compiling the item representation, and so Nanoc cannot make an accurate estimation of what a proper order of compilation is. For that reason, compilation suspensions are not only expected, but commonplace.

A dependency from one item representation onto another item representation’s compiled content is called a hard dependency, as opposed to a soft dependency, which is used in outdatedness checking. A compilation suspension always indicates a hard dependency.

Compilation selection

Once Nanoc has selected the items representations that it deems are outdated (see the Outdatedness checking section), it will compile these item reps in the best possible order. The class responsible for determining this order is the ItemRepSelector.

Nanoc will attempt to compile every outdated item representation sequentially. If an item representation cannot be compiled due to a compilation suspension, Nanoc will schedule a continued compilation attempt for this item representation after the dependent item representation has been compiled. If the dependent item representation was not selected for recompilation (which happens when the item representation is not deemed to be outdated), Nanoc will schedule the dependent item representation for recompilation.

A visual representation of the compilation selection process
The term “compile” or “recompile” does not always mean that the item will be recompiled from scratch; Nanoc keeps a cache of compiled content and will reuse cached compiled content if possible.