在Rails中嵌套布局时,如何防止我的application.css文件被包含两次?

时间:2016-06-27 21:02:28

标签: css ruby-on-rails-4 layout include

我正在使用Rails 4.2.3。嵌套布局时,如何防止application.css.scss文件被包含两次?在我的“app / views / layouts / application.html.erb”文件中,我有

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= content_for?(:title) ? yield(:title) : "Runtrax" %></title>
    <meta name="description" content="<%= content_for?(:description) ? yield(:description) : "Runtrax" %>">
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags %>
  </head>
  <body>

    <% if !current_user.nil? %>
    <div id="container">
    <header>
      <%= render 'layouts/navigation' %>
    </header>
    <main role="main">
      <%= render 'layouts/messages' %>
      <%= yield %>
    </main>
    </div>
    <% else %>
      <%= yield %>
    <% end %>

  </body>
</html>

然后在我的用户布局中,app / views / layouts / user.html.erb,我有

<%= javascript_include_tag "countries" %>
<%= javascript_include_tag "users" %>

<%= yield %>

<% parent_layout "application" %>

然而,当我的一个用户页面被渲染时,它出现在&lt; head&gt;中。元素......     

并且在呈现用户布局时也存在(在&lt; main&gt;部分中)......

<link rel="stylesheet" media="all" href="/assets/application.self-97ad5c0b00e27e03a2a434530385915aee55c42b8f0ae090c1a2abf4507ff7d8.css?body=1" />

我只希望它出现一次。我需要做什么才能实现这一目标?如果重要,那就是我正在使用的app / helpers / layout_helper.rb模块

# Place this in app/helpers/layouts_helper.rb
module LayoutHelper
  def parent_layout(layout)
    @view_flow.set(:layout, output_buffer)
    output = render(:file => "layouts/#{layout}")
    self.output_buffer = ActionView::OutputBuffer.new(output)
  end
end

1 个答案:

答案 0 :(得分:0)

对于多个布局,我只是在layouts文件夹中创建一个额外的布局,然后在所需的控制器操作结束时:

render layout: "user" # for your case it is "user"

因此实际上您不会创建嵌套布局,而是创建单独的布局。您可以将current_user逻辑移动到控制器操作中,以选择要呈现的布局。为了使您的布局视图代码DRY使用partials。

以下是拆分布局的示例:

<!-- application layout -->
<!DOCTYPE html>
<html>
  <head>
    <%= render "layouts/head_section" %>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  </head>
  <body>

    <%= yield %>

  </body>
</html>

<!-- user layout -->
<!DOCTYPE html>
<html>
  <head>
    <%= render "layouts/head_section" %>
    <%= javascript_include_tag "countries" %>
    <%= javascript_include_tag "users" %>
  </head>
  <body>
    <div id="container">
      <header>
        <%= render 'layouts/navigation' %>
      </header>
      <main role="main">
        <%= render 'layouts/messages' %>
        <%= yield %>
      </main>
    </div>
  </body>
</html>

<!-- _head_section.html.erb -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= content_for?(:title) ? yield(:title) : "Runtrax" %></title>
<meta name="description" content="<%= content_for?(:description) ? yield(:description) : "Runtrax" %>">
<%= csrf_meta_tags %>

# controller
def some_action
  ...
  render layout: (current_user.present? ? "user" : "application")
end

但是,如果要在两种布局中使用turbolink,则需要考虑在应用程序布局或清单文件中仅包含nessesary js和css文件,例如jquery,turbolinks和其他常用功能。其余部分应包含在您的自定义布局中,因此您的布局将如下所示:

<!-- application layout -->
<!DOCTYPE html>
<html>
  <head>
    <%= render "layouts/head_section" %>
    <%= javascript_include_tag "none_users" %>
  </head>
  <body>

    <%= yield %>

  </body>
</html>

<!-- user layout -->
<!DOCTYPE html>
<html>
  <head>
    <%= render "layouts/head_section" %>
    <%= javascript_include_tag "countries" %>
    <%= javascript_include_tag "users" %>
  </head>
  <body>

    <div id="container">
      <header>
        <%= render 'layouts/navigation' %>
      </header>
      <main role="main">
        <%= render 'layouts/messages' %>
        <%= yield %>
      </main>
    </div>

  </body>
</html>

<!-- _head_section.html.erb -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= content_for?(:title) ? yield(:title) : "Runtrax" %></title>
<meta name="description" content="<%= content_for?(:description) ? yield(:description) : "Runtrax" %>">
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>

通常,您希望最大限度地降低布局的复杂性并避免使用if-else逻辑,因为这种逻辑会随着时间的推移而变得非常混乱。