我正在尝试解决辛特拉的respond_with和respond_to,路线等等。 doco似乎确实谈到了将代码移到某一点,但我无法弄清楚如何去做。
我有一系列路由都返回Json或XML,例如:
respond_with :index, data do |f|
f.xml { XmlSimple.xml_out(data, {'XmlDeclaration' => true}) }
f.on('application/json') { data.to_json }
end
XmlSimple调用可能会有一些不同的选项。在一种情况下,路由会执行自己的XML呈现(因为它很复杂)。接下来,我想添加可选的“漂亮”输出,也可以添加某种HTML模板化输出。
我想做的是让我的所有路由都返回哈希或字符串。如果它是一个字符串,那么我们可以将它传递给Sinatra,以便像往常一样输出。如果路由返回一个哈希值,那么它将以与上面类似的方式呈现,具体取决于请求或查询字符串参数。
我的问题是:如何在路由输出上配置某种“defualt”输出过滤器?
答案 0 :(得分:1)
根据Sinatra文档,“在相同上下文中的每个请求之后评估过滤器后,还可以修改请求和响应。”因此,你可以编写一个全局的后置过滤器,根据它的类别,或者你想要的任何验证,以不同的方式处理这些数据。在路由中访问的实例变量可以在Before / After路由中使用。
get '/foo' do
data = some_data
end
after do
data if data.class == String
data.do_more_things if data.class == Hash
end
如果这不起作用,我相信您可以简单地编写一个方法并在路径末尾的数据上调用它:
def format_for_response(data)
data if data.class == String
data.do_more_things if data.class == Hash
end
get '/foo' do
format_for_response(data)
end
答案 1 :(得分:0)
回答我自己的问题......
在@ sean-larkin的帮助下,我在Sinatra Extension(http://www.sinatrarb.com/extensions.html)中使用了一种方法。这个想法是帮助者可以访问“参数”,“请求”,“响应”等,因此可以对所需的输出格式做出决策。
这是一个示例渲染方法(保存到lib / sinatra / render.rb中),除非在请求的查询字符串中指定“?pretty = true”,否则它将输出缩小的XML / JSON:
require 'sinatra/base'
require 'xmlsimple'
module Sinatra
module OutputRender
module Helpers
def render_output(data, xml_opts = {})
if data.class == String
# If it's already rendered, then just output it
return data
end
pretty = (params['pretty'] && params['pretty'] == 'true') ? true : false
respond_with :index, data do |f|
f.on(:xml) { XmlSimple.xml_out(data, xml_opts) }
f.on(:json) { pretty ? ::JSON.pretty_generate(data) : data.to_json }
end
end
end
def self.registered(app)
app.helpers OutputRender::Helpers
end
end
register OutputRender::Helpers
end
...然后在有路径的文件中(例如lib / banana.rb)我有这个:
require "sinatra/base"
require "sinatra/render"
get '/banana', :provides => [:xml, :json] do
x = Hash.new()
x['one'] = two
render_output x
end
所以我留下了一个我希望避免的'渲染功能',但这似乎是一种干净的方式来做我想要的事情。我现在要添加数据的HTML呈现,这样如果你使用浏览器来查找路径就有很好的浏览器输出,并且努力使XML输出始终有一个声明,总是低于特定的根节点等等。