Nanoc, Routes and File Extensions


So I’ve encoun­tered my first major nui­sance in using nanoc. In nanoc, the file­names of source files are treated rather unin­tu­itively and it can be con­fus­ing why one can’t have mul­ti­ple files with the same name but dif­fer­ent exten­sions at first. I haven’t found a lot of infor­ma­tion about this so I’ll put down a quick writup on this.

Nanoc treats each source file as a dif­fer­ent atomic “item” (in nanoc speak.) Each item is iden­ti­fied by the path to that item from the source (“con­tent”) root, plus the name of the item, minus any exten­sion. So, a file in “con­tent/­post­s/­some­sil­ly­post.erb” would be iden­ti­fied by nanoc with “/post­s/­some­sil­ly­post/”. Notice that the exten­sion “.erb” is dropped. Nanoc treats all file with the same name as part of the same item regard­less of exten­sion. This makes sense from nanoc’s per­spec­tive because an item can have mul­ti­ple files asso­ci­ated with it (usu­ally a source file with an “.html” or “.erb” exten­sion and a meta­datafile withe a “.yaml” exten­sion.) The con­se­quence of this is that if you have two files with the same name and dif­fer­ent exten­sions, for exam­ple, “re­sume.html” and “re­sume.pdf,” then nanoc will throw an error because it sees the two as con­flict­ing resources.

Work­ing around this is sim­ple, if unin­tu­itive. You can’t have mul­ti­ple source file with the same name and dif­fer­ent exten­sion, but you can have mul­ti­ple out­put files with the same name and dif­fer­ent exten­sion. You just have to name your files some­thing like “re­sume_html” and “re­sume_pdf” and cre­ate the cor­rect routes in the Rules file to trans­form them:

route '/resume_html/' do
  "/resume.html"
end
route '/resume_pdf/' do
  "/resume.pdf"
end

In this exam­ple, the source files with names like “file_html” are con­verted to out­put file with names like “file.htm­l”.

You can actu­ally gen­er­al­ize this so that final under­scores are always con­verted to “.”

route '*' do
  *filename, extension = item.identifier.split "_"
  filename.join("_") + "." + extension
end

So now any file named “/just_a_sam­ple/htm­l_­file_html” will be out­put as “/just_a_sam­ple/htm­l_­file.html”

The key points to take away here are that

  1. nanoc treates its source, not as a collection of files, but as a collection of ‘items’ which each can consist of more than one file.
  2. Items are identified by their paths, including filename sans extension, which nanoc uses for other things.
  3. You can’t have multiple files of the same name but with different extensions because nanoc will conflate them, but you can have multiple output files with the same name and different extensions if you just use the correct routes in the Rules file.

    Last update: 24/8/2011

    blog comments powered by Disqus