2010-06-27 49 views
9

我正在使用可配置「模板」生成HTML的Ruby gem。我想包含一組基本的模板和gem,並允許用戶使用更好/更自定義的模板覆蓋它們。這些模板不是Ruby代碼,它們是需要在代碼中的某處從磁盤讀取的「只是文件」。如何將數據文件包含在Ruby Gem中?

我查看了RubyGems文檔,但他們做出(並非完全不合理)的假設,即gem只包含代碼(好吧,有一些文檔和特定的元數據文件引發了很好的措施)。沒有提及如何創建相應的「/ usr/share/...」文件。

將這些文件包含在gem中的最佳做法是什麼?我是否應該將它們作爲「來源」的一部分?如果是這樣,我如何發現他們的路徑,以便我可以從磁盤讀取它們到模板處理器中?

回答

10

假設你有一個項目的結構是這樣的:

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

lib/foobar/teplates目錄中你有你的模板目錄或文件 。

lib/foobar/meta.rb文件包含您的項目名稱及其 版本。保持它們(特別是版本號) 與名稱&與您的寶石 規範中的項目版本同步非常重要。 (要做到這一點,最好的辦法是從Rake文件 讀meta.rb將值傳遞到規格)

例如,meta.rb可能看起來像:

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

然後編寫返回一個完整路徑的功能lib目錄 無論您是從源 目錄測試項目還是從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 

Foobar::Utils.gem_libdir功能,您可以隨時在bin/foobar文件中讀取您的 模板:

require_relative '../lib/foobar/utils' 

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