如何在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
答案 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