我正在开发一个Ruby gem,它使用可配置的“模板”来生成HTML。我想在gem中包含一组基本模板,并允许用户使用更好/更自定义的模板覆盖它们。这些模板不是Ruby代码,它们只是需要在代码中的某个时刻从磁盘读取的“文件”。
我查看了RubyGems文档,但是他们做出了(并非完全不合理)的假设,即gem只包含代码(好的,带有一些文档和特定的元数据文件)。没有提及如何创建等效的“/ usr / share / ...”文件。
在gem中包含此类文件的最佳做法是什么?我应该简单地将它们作为“来源”的一部分吗?如果是这样,我如何发现它们的路径,以便我可以将它们从磁盘读入模板处理器?
答案 0 :(得分:10)
假设你有一个这样的项目结构:
bin/
|__ foobar*
lib/
|__ foobar/
| |__ templates/
| | |__ a/
| | |__ b/
|___|__ meta.rb
|___|__ utils.rb
在lib/foobar/teplates
目录中,您有模板目录或
文件。
lib/foobar/meta.rb
文件包含项目名称及其名称
版。保留它们(特别是版本号)很重要
与名称&同步宝石中项目的版本
规格。 (执行此操作的最佳方法是从Rakefile读取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'