1

这里的问题是问如何将Rails view helper 函数提取到gem 中,accept 的回答还不错。

我想知道 - 如何为 Sinatra 做同样的事情?我正在制作一个在模块中定义了一堆帮助函数的 gem,我想让这些函数可用于 Sinatra 视图。但是无论我尝试什么,我似乎都无法访问这些功能,我只是得到一个undefined local variable or method错误。

到目前为止,我的 gem 结构看起来像这样(省略了 gemspec 等其他内容):

cool_gem/
  lib/
    cool_gem/
      helper_functions.rb
      sinatra.rb 
  cool_gem.rb

cool_gem.rb中,我有:

if defined?(Sinatra) and Sinatra.respond_to? :register
  require 'cool_gem/sinatra'
end

helper_functions.rb中,我有:

module CoolGem
  module HelperFunctions

    def heading_tag(text)
      "<h1>#{text}</h1>"
    end

    # + many more functions
  end
end

sinatra.rb中,我有:

require 'cool_gem/helper_functions'

module CoolGem
  module Sinatra

    module MyHelpers
      include CoolGem::HelperFunctions
    end

    def self.registered(app)
      app.helpers MyHelpers
    end

  end
end

这行不通。我哪里错了?

(如果您想知道,是的,我需要将辅助函数放在一个单独的文件中。我计划使 gem 也与 Rails 兼容,所以如果可能的话,我想保持函数的隔离/解耦)。

4

1 回答 1

2

您主要只是错过了对Sinatra.register(in cool_gem/sinatra.rb) 的调用:

require 'sinatra/base'
require 'cool_gem/helper_functions'

module CoolGem
  # you could just put this directly in the CoolGem module if you wanted,
  # rather than have a Sinatra sub-module
  module Sinatra

    def self.registered(app)
      #no need to create another module here
      app.helpers CoolGem::HelperFunctions
    end

  end
end

# this is what you're missing:
Sinatra.register CoolGem::Sinatra

现在,任何需要的经典风格 Sinatra 应用程序cool_gem都将提供可用的助手。如果您使用模块化样式,您还需要register CoolGem::SinatraSinatra::Base子类中调用。

在这种情况下,如果您只是提供一些辅助方法,则更简单的方法可能是只使用该helpers方法(再次在 中cool_gem/sinatra.rb):

require 'sinatra/base'
require 'cool_gem/helper_functions'

Sinatra.helpers CoolGem::HelperFunctions

现在这些方法将在经典风格的应用程序中可用,而模块化风格的应用程序将需要调用helpers CoolGem::HelperFunctions. 这有点简单,但是如果您要向 DSL 上下文添加方法,则需要registered像上面那样使用。

于 2013-07-09T17:08:44.307 回答