Sinatra - 在模块中渲染“erb”

时间:2015-05-13 07:50:31

标签: ruby sinatra

如何在Sinatra的模块中使用erb?以下是完整应用的示例,其中erb在模块中失败。

require 'sinatra'

get '/yes' do
  erb "<%= Time.now %>" #works
end

get '/no' do 
  MyMod.foo #fails
end

module MyMod
  extend self

  def foo
    erb "<%= Time.now %>" #fails: undefined method `erb' for MyMod:Module
  end
end

4 个答案:

答案 0 :(得分:3)

erb方法在Sinatra::Templates中定义。所以人们会认为他能够使用那个

module MyMod
  extend Sinatra::Templates
  extend self

  def foo
    erb Time.now.to_s
  end
end

然而,事情并非如此简单。现在找到了erb方法,但仍然无法正常工作

  

NameError at / no

     

未定义的局部变量或方法`settings&#39;对于MyMod:模块

如果你关注那个兔子洞,你需要让你的模块成为一个完整的sinatra应用程序(不知道这是否可能)。

为什么不使用模块化的sinatra应用程序样式(创建一个继承自Sinatra::Base的类)并将您的模块包含到应用程序中?通过这种方式,我非常有信心,只是工作&#34;。

答案 1 :(得分:2)

这可能不是您正在寻找的答案。这是我的另一个版本。可能这与你想要达到的目标很接近。

module MyMod  
  extend self

  def foo
    ERB.new("<%= Time.now %>").result   
  end
end

get '/' do
   MyMod.foo
end

或帮助者?

module Sinatra
    module MyMod  
        def foo
            erb "<%= Time.now %>"
        end
    end
    helpers MyMod
end

get '/' do
    foo
end

答案 2 :(得分:0)

解决方案 - 在Sinatra :: Application实例上调用erb,如下所示(两种方式调用它,第二种方式更好)。

require 'sinatra'

get '/yes' do
  erb "<%= Time.now %>" #works
end

get '/foo' do 
  MyMod.foo #works
end

get '/foo2' do
  MyMod.foo2 #works 
end

module MyMod 
  extend self

  def foo
    ObjectSpace.each_object(Sinatra::Application).first.erb "<%= Time.now %>"
  end

  def foo2
    @app ||= Sinatra::Application.new.instance_variable_get :@instance
    @app.erb "<%= Time.now %>"
  end 
end

答案 3 :(得分:0)

扩展@Sergio Tulentsev的答案: 要模仿Sinatra控制器的渲染行为,您可以创建如下模块:

module ErbRender

  include Sinatra::Templates
  include Sinatra::Helpers
  include Sinatra::ContentFor

  def settings
    @settings ||= begin
      settings = Sinatra::Application.settings
      settings.root = "#{ROOT}/app"
      settings
    end
  end

  def template_cache
    @template_cache ||= Tilt::Cache.new
  end

end

您可能需要调整settings.root

用法示例:

class ArticleIndexingPostBody

  include ErbRender

  def get_body
    erb :'amp/articles/show', layout: :'amp/layout'
  end

end

这将正确呈现包含content_for

等布局的模板