6. Tuneando nanoc

Como ya comentamos, una de las grandes cualidades de nanoc es que podemos automatizar tareas y modificar su comportamiento.

Para eso, tenemos dos métodos a nuestra disposición

Rake, el amigo de los vagos

Rake es una herramienta que nos permite crear y automatizar tareas con Ruby.

En este taller vamos a utilizar la forma más simple de tareas en Rake. Para definir una tarea, sólo tenemos que añadir en el fichero Rakefile un bloque de código como este:

desc "Descripción de nuestra tarea"
task :nombre_de_la_tarea do
  # código de la tarea
end

Podemos definir tantas tareas como queramos. Para ejecutar una tarea, desde la línea de comandos ejecutaremos

$ rake nombre_de_la_tarea

Si tienes una tarea que se llame :default, se ejecutará si no especificas ningún nombre de tarea en la línea de comandos. Es decir

$ rake

es equivalente a

$ rake default

Una de las ventajas de Rake es que puedes ejecutarlo desde cualquier directorio dentro del proyecto.

Simplificando los comandos de nanoc

Si te hartas de ejecutar

$ nanoc compile
$ cd output
$ heel

puedes crear una tarea de Rake que haga esto. Edita el fichero Rakefile de la raiz de tu proyecto y añade lo siguiente:

desc "Compila el site y lo prueba con heel"
task :default do
  %x(nanoc compile)
  %x(heel -r output)
end

Si ahora vas a la raiz de tu proyecto y ejecutas

$ rake

verás como tu site se compila y se prueba :)

Si hay tareas que quieras ejecutar antes de compilar el site, puedes añadirlas a los prerequisitos de otra tarea usando

task :default => [:prerequisito_uno, :prerequisito_dos] do
  # lo que sea
end

con lo que las tareas :prerequisito_uno y :prerequisito_dos se ejecutarán antes que la tarea :default

El directorio lib, abriendo la caja de los truenos

La otra forma de extender nanoc es usando plugins en Ruby.

Esto, que suena tremendamente complicado, en realidad es muy fácil.

nanoc incluirá por defecto todos los ficheros .rb que haya en la carpeta lib. Puedes separar tus plugins por ficheros (agrupando la funcionalidad común por fichero) o poner todo tu código en un sólo fichero.

Vamos a crear un fichero plugin.rb que contenga lo siguiente:

def plugin_test
  "Hola, soy un plugin de nanoc"
end

y en nuestra plantilla por defecto (layouts/default.erb) pondremos esto:

<html>
  <head>
    <title><%= @page.title %></title>
  </head>
  <body>
    <%= @page.content %>
    <%= plugin_test %>
  </body>
</html>

Si ahora compilamos y testeamos (con nuestra glamourosa tarea :default de rake) veremos el resultado de la operación...

Un plugin útil: "breadcrumbs"

A poco que hayas trabajado maquetando sitios complejos, uno de los elementos que habrás encontrado es el famoso "breadcrumb", o "rastro de migas".

Maquetar un breadcrumb no tiene mucho misterio. Lo que es un auténtico coñazo es cambiar el breadcrumb de 80 páginas, sobre todo cuando te están cambiando constantemente los nombres de las páginas.

Para hacer nuestra vida más fácil, vamos a programarnos un plugin que nos construya un breadcrumb pseudo automático.

Primero, vamos a crear un plugin que nos devuelva una página a partir de un id fijo. Con esto conseguiremos hacer referencia a una página con independencia de cómo se llame o dónde esté.

Este es el código del plugin get_page que añadiremos en lib/plugins.rb:

def get_page(page_id)
  return @pages.select { |p| p.page_id == page_id.to_s }.first
end

Lo siguiente que necesitamos es un plugin que nos construya un enlace en HTML a una página determinada.

def link_to(text, page_id, attributes='')
  page = get_page(page_id)
  att = []
  attributes.each do |k,v|
    att << "#{k}='#{v}'"
  end
  "<a href='#{page.path}' title='#{page.title}' #{att.join(' ')}>#{text}</a>"
end

Ahora vamos con la parte final, el plugin que nos generará el breadcrumb.

def breadcrumb(route_array)
  links = route_array.map { |p|
    if get_page(p).nil?
      p
    else
      if(@page.page_id.to_s == get_page(p).page_id.to_s)
        attr = {:class => 'current'}
      else
        attr = ''
      end
      link_to(get_page(p).title,p)
    end
  }
  "<div id='breadcrumb'>#{links.join(" » ")}</div>"
end

Con esto podemos añadir en el fichero meta.yaml de cada página la ruta del breadcrumb tal que así:

breadcrumb:
  - home
  - servicios
  - internet
  - maquetación

Si el nombre de la miga existe como página, se mostrará el título de la página en el breadcrumb. Si no existe, se mostrará literalmente.

Para usarlo en una página, ponemos esto en el contenido:

<%= breadcrumb(@page.breadcrumb) %>

haciendo que nanoc entienda Rails, y viceversa

Usando el sistema de plugins de nanoc, podemos hacer que nanoc "entienda" los helpers de Rails, con lo que podemos:

  • usar plantillas de Rails en nanoc
  • usar plantillas de nanoc en Rails

Esto lo veremos en la siguiente sección, "nanoc on Rails"

changed September 24, 2007