在Rails应用程序中挂载Sinatra应用程序并共享布局

23

我想在我的Rails应用程序中挂载一个Sinatra应用程序。但是我希望它们共享相同的布局。

IFrame可能可行,但你有其他想法吗?

谢谢

3个回答

37

你基本上需要做两件事情:

你需要告诉Rails路由器,某个特定的URL路径将由另一个Rack应用程序处理(在你的情况下是Sinata应用程序)。这可以通过将以下内容添加到routes.rb来完成:

match "/sinatra" => MySinatraApp, :anchor => false

完成上述步骤后,您可以按照以下方式创建应用程序:

class MySinatraApp < Sinatra::Base
  get "/" do
    "Hello Sinatra World"
  end
end

现在的第二步是告诉你的Sinatra应用程序使用Rails布局,默认情况下,它位于app/views/layouts/application.html.erb中,适用于Rails 3.1。默认情况下,Sinatra使用./views/layout.ext(其中ext是所选模板系统的扩展名)。因此,你需要告诉Sinatra:
  1. 使用另一个目录来查找视图和布局,而不是默认的./views
  2. 使用另一个模板文件作为默认布局。
可以通过在Sinatra应用程序中设置以下内容来实现两者:
set :views, "/path/to/your/railsapp/views"
set :erb, layout => :"layout/application" # or whatever rendering engine you chose

问题在于Sinatra无法处理我在Rails布局中使用的Rails助手(以及各种Rails插件)。 - Mike
2
那么,你可能应该坚持使用Rails。Sinatra的美妙之处在于,在某些环境下,它没有多余的东西。但是,如果你已经拥有了所需的基础设施(辅助工具、插件等),那么抛弃它们就没有什么意义了。将Sinatra用于可以独立完成的领域。 - Holger Just
当然,我只是想构建一个小型扩展程序,可以被多个Rack应用程序重复使用。但我会坚持使用Rails引擎。 - Mike
根据您实际想要实现的目标,您也可以尝试使用机架中间件。您可以让Rails应用程序发出带有特定关键字的页面,然后在过滤器链中稍后由中间件替换。如果您做复杂的事情,这是不干净的,但对于简单的、自包含的事情,这可能是可以接受的。 - Holger Just

3

为了共享相同的布局,您可以将Sinatra指向Rails应用程序中包含布局的文件夹: (摘自这里:http://www.sinatrarb.com/configuration.html)

:views - view template directory A string specifying the directory where view templates are located. By default, this is assumed to be a directory named “views” within the application’s root directory (see the :root setting). The best way to specify an alternative directory name within the root of the application is to use a deferred value that references the :root setting:

  set :views, Proc.new { File.join(root, "templates") }
从您的Rails应用程序中,您可以构建一个方法,您可以从其中调用sinatra应用程序应包含在视图中的操作。 (假设您要使用此操作的索引操作)
def index
  @sinatra_content = get_sinatra
end
# use @sinatra_content in your views for rendering

def get_sinatra
   sinatra_ip = 127.0.0.1;
   sinatra_port = 4567;
   #start a request here
   RestClient.get 'http://#{sinatra_ip}:{sinatra_port}/', {:params => {:id => 50, 'foo' => 'bar'}}
end

查看 rest-client 的使用方法:https://github.com/archiloque/rest-client,并且不要忘记在你的 Rails 应用程序中包含 gem。

在你的 Sinatra 应用程序中使用链接时,你应该决定是否由 Sinatra 处理(指向 Sinatra 应用程序(带端口)或在你的 Sinatra 应用程序中构建链接,由你的 Rails 应用程序处理)。


1
非常棒的技巧,我认为唯一的问题是http可能会很慢。 - Mike

1

我认为在你的Rails应用程序中使用append_view_path会更好一些。只需将Sinatra视图附加到Rails应用程序中,它就会在查找app/views之后查找那里。

José Valim的《Crafting Rails Applications》一书在这个主题(从其他来源呈现视图)上有很多文档,你可以看一下。

此外,这个Railscasts也可以帮助: http://railscasts.com/episodes/222-rack-in-rails-3


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接