2010-06-27 13 views
9

Estoy trabajando en una gema Ruby que usa "plantillas" configurables para generar HTML. Quiero incluir un conjunto básico de plantillas con la gema, y ​​permitir que los usuarios las anulen con mejores/más personalizadas. Estas plantillas no son código de Ruby, son "solo archivos" que deben leerse desde el disco en algún punto del código.¿Cómo incluir archivos de datos en una Ruby Gem?

Revisé la documentación de RubyGems, pero ellos hacen la suposición (no completamente irracional) de que una gema contiene solo código (OK, con cierta documentación y archivos de metadatos específicos arrojados para mayor información). No hay ninguna referencia sobre cómo crear el equivalente a los archivos "/ usr/share/...".

¿Cuál es la mejor práctica para incluir dichos archivos en la gema? ¿Debería simplemente incluirlos como parte de las "fuentes"? Si es así, ¿cómo descubro su ruta para poder leerlos desde el disco en el procesador de plantillas?

Respuesta

10

Suponga que tiene una estructura de proyecto como este:

bin/ 
|__ foobar* 
lib/ 
|__ foobar/ 
| |__ templates/ 
| | |__ a/ 
| | |__ b/ 
|___|__ meta.rb 
|___|__ utils.rb 

En lib/foobar/teplates directorio que tenga sus directorios de plantillas o archivos.

lib/foobar/meta.rb El archivo contiene el nombre de su proyecto y su versión . Es importante mantenerlos (particularmente un número de versión) sincronizado con el nombre & la versión del proyecto en su especificación gem . (La mejor manera de hacer esto es leído meta.rb de Rakefile para pasar valores de la especificación.)

Por ejemplo, meta.rb puede verse como:

module Foobar 
    module Meta 
    NAME = 'foobar' 
    VERSION = '0.1.2' 
    end 
end 

luego escribir una función que devuelve una ruta completa el directorio lib independientemente de si está probando su proyecto desde el directorio de orígenes o si el proyecto está instalado desde rubygems.

utils.rb:

require_relative 'meta' 

module Foobar 
    module Utils 

    # Return a directory with the project libraries. 
    def self.gem_libdir 
     t = ["#{File.dirname(File.expand_path($0))}/../lib/#{Meta::NAME}", 
      "#{Gem.dir}/gems/#{Meta::NAME}-#{Meta::VERSION}/lib/#{Meta::NAME}"] 
     t.each {|i| return i if File.readable?(i) } 
     raise "both paths are invalid: #{t}" 
    end 

    # [...] 
    end 
end 

Tener Foobar::Utils.gem_libdir función se puede leer siempre sus plantillas en bin/foobar archivo:

require_relative '../lib/foobar/utils' 

puts Dir[Foobar::Utils.gem_libdir + '/*'] 
puts Foobar::Utils.gem_libdir + '/templates/a/blah-blah' 
Cuestiones relacionadas