与Sinatra一起提供XHTML

时间:2012-10-09 02:27:50

标签: ruby xhtml sinatra mime-types rack

我正在创建一个Sinatra Web应用程序,我想为所有提供的网页提供mime类型application/xhtml+xml。我使用Builder作为模板引擎。请注意,应用程序还将为各种AJAX api接口提供application/xml,也使用Builder模板引擎,以及text/css使用scss模板引擎。

我注意到生成的网页会收到text/html内容类型,而api接口则会获得application/xml内容类型。但是,我不知道如何决定哑剧类型;是否存在html标记?是否使用布局?无论哪种情况,我都希望应用程序发出application/xhtml+xml mimetype而不是text/html mime类型。

我知道我可以使用content_type调用来指定mime类型,但我想在每个路由函数中都不需要这个。有什么办法可以为给定的模板引擎设置默认的mime类型吗?或者可以通过视图的文件名控制mime类型? Tilt是否提供了一种控制哑剧类型的方法?

1 个答案:

答案 0 :(得分:3)

由于您的应用程序被分解为单独的对象,因此将所有AJAX路由引入单独的Sinatra应用程序应该很简单。这将允许您使用Sinatra的钩子后。唯一的要求是你的AJAX调用有一些东西将它们标识为AJAX;例如,通过将请求标头设置为特殊值,或使用特殊格式的路由。以下是唯一路由方法的示例rackup文件:

require 'sinatra/base'

class MainApp

  def get_info params
    # return some data structure
  end

end

class MainAppRoutes < Sinatra::Base

  def initialize mainapp
    super()
    @mainapp = mainapp
  end

  get '/' do # main page
    data = @mainapp.get_info(params)
    # render response from data
  end

end

class AjaxRoutes < Sinatra::Base

  def initialize mainapp
    super()
    @mainapp = mainapp
  end

  get '/getinfo' do # handler for /ajax/getinfo
    data = @mainapp.get_info(params)
    # generate XML response from data
  end

  after do
    content_type 'application/xml'
  end

end

mainapp = MainApp.new

map '/ajax' do
  run AjaxRoutes.new(mainapp)
end
run MainAppRoutes.new(mainapp)

在此示例中,所有以/ ajax开头的路由都由AjaxRoutes类的实例处理。 After hook确保这些响应的内容类型为'application / xml'。非ajax路线不受影响。

要记住的一些事情:

  • Rack :: Builder.map剥离了它匹配的URL部分。所以AjaxRoutes中的'/'路由实际上会回答'/ ajax /'的请求。
  • 始终在Sinatra派生的端点类的初始值设定项中调用super()。对于Sinatra中间件,将第一个参数传递出去(Rack使用下一个机架应用程序调用#new作为第一个参数)。
  • 查看有关Sinatra filters的文档。关于使用后钩修改响应有一个令人沮丧的怪癖。