设置布局的 Sinatra 方法

Posted

技术标签:

【中文标题】设置布局的 Sinatra 方法【英文标题】:Sinatra method to set layout 【发布时间】:2014-09-28 00:52:59 【问题描述】:

我想在 sinatra 中写一个方法来设置布局,比如

def admin_layout
   set :layout, 'admin/layout'
end

我知道我可以执行set :erb, layout: :'main/layout' 之类的操作,或者为每个操作指定布局,例如

get 'admin/login' do
  erb :'admin/login', layout: :'admin/layout'
end

但我想知道是否有一种方法可以将其抽象为一个方法,这样我就不需要为每条路线设置布局。我正在制作一个带有main 站点和admin 站点的应用程序,但管理部分非常轻量级,只需登录并能够编辑帖子,所以我不想太疯狂,而是我当前的文件结构是这样的:

db/
models/
public/
  views/
    admin/
    main/
app.rb
config.ru

【问题讨论】:

【参考方案1】:

定义布局参数:

def admin_layout
  :layout, 'admin/layout'
end

那么你就可以把这个方法当成参数来使用

get 'admin/login' do
  ## do ......
  erb :'admin/login', admin_layout
end

或者如果你想判断它将使用哪种布局,请将admin_layout函数更改为:

def admin_layout
  if request.path.start_with?('/admin')
    :layout, 'admin/layout'
  else
    :layout, 'layout'
  end
end

【讨论】:

【参考方案2】:

我知道我可以这样做:set :erb, layout: :'main/layout'

不,你不能这样做——或者至少 erb 会忽略它,因为它不是一个特定于 erb 的选项。如果你能做到这一点,那不就是你在这里要求的吗:

但我想知道是否有办法将其抽象为 方法,所以我不需要为每条路线设置布局。

方法已经存在--template():

#Templates:

application_layout = <<END_OF_HAML
%html 
  %head
    %title My App
  %body
    =yield
END_OF_HAML

template :layout do  #Creates a template named :layout
  application_layout 
end

template :page1 do
  '%div.greet Hello World!'  #=> <div class="greet">Hello World!</div>
end

template :page2 do
  '%div#first_name John'     #=> <div id="first_name">John</div>
end

#Routes:  -------------------

get '/page1' do
  haml :page1   #If there is a template named :layout, then the :page1 template will be inserted into the :layout template automatically.
end

get '/page2' do
  haml :page2   #If there is a template named :layout, then the :page1 template will be inserted into the :layout template automatically.
end

然后你可以覆盖默认布局,像这样:

admin_layout = <<END_OF_HAML
%html 
  %head
    %title Admin Only
  %body
    =yield
END_OF_HAML

template :special_layout do  #Creates a template named :special_layout
  admin_layout
end

get '/page3' do
  haml :special_layout, :layout => false do  #Don't use default layout, i.e the :layout template, instead use :special_layout template
    haml :page3
  end
end

在此处查看“命名模板”:http://www.sinatrarb.com/intro.html#Named%20Templates

【讨论】:

这仍然需要我为使用该布局的每个视图添加 :special_layout, :layout =&gt; false,这与在每次渲染后添加 , layout: :'admin/layout' 没有太大区别。 @kittyminky2,所以你认为一个解决方案定义了一个你必须在每条路由中调用的方法,并且只返回一个你可以直接在每条路由中编写的哈希值,这会以某种方式为你节省一些工作? 是的,因为它更短。我只是写def admin_layout layout: 'admin/layout' end 然后可以做到get '/admin' do erb :'admin/about', admin_layout end

以上是关于设置布局的 Sinatra 方法的主要内容,如果未能解决你的问题,请参考以下文章

Sinatra 和机架保护设置

为 Sinatra 设置默认 content_type

markdown 使用Active Record设置Sinatra

如何在 Heroku 上托管的 Ruby/Sinatra 应用程序中设置 HTTP 标头?

跨多个域名使用 Sinatra 会话变量?

使用 Sinatra 对端点进行版本控制