简体   繁体   中英

Rails 4: properly using content_for/rendering partials

I have never used content_for before but it seems quite helpful.

I'm probably making this more difficult then it has to be, but the goal is:

Have a custom header on a products#index page.

Currently, I have that header set up as a partial ( _header.html.erb ) in the products folder. I was calling

<%= render "header" %> on the products index page, but there was a slight margin above the header: so upon using Inspect Element there seemed to be a margin linked within the body of the products.css.scss page: there in fact is a margin-top value of 40px in products.css.scss, but why on earth is that being transferred over to the header partial in app/views/products/ ?

I'm trying to understand this the clean way so I don't have a whole disgusting whirlwind of CSS. It seems using content_for approach here is viable (but maybe overcomplicated for something like this?), but I feel since my _header.html.erb file has the following it should be ok

  <%= stylesheet_link_tag "header" %>
  <div id="transparent-box">
    <div class="logo-red"></div>
    <div class="banner-items">
      <%= link_to 'About', '#', :class => 'banner-item' %>
      <%= link_to 'Shop', '/products', :class => 'banner-item' %>
      <%= link_to 'Contact', '#', :class => 'banner-item' %>
      <%= link_to 'Cart', '/products/current', :class => 'banner-item' %>
    </div>
  </div>

content_for :____ basically stores a set of HTML which can be called in another part of the layout (an elaborate variable), as described in the documentation :

Calling #content_for stores a block of markup in an identifier for later use. In order to access this stored content in other templates, helper modules or the layout, you would pass the identifier as an argument to content_for

In my experience, content_for is indifferent from a code perspective - it only stores what you tell it to. Therefore your CSS issue is not really a problem from the use of content_for , but a problem with how you're calling your header file I think


Fix

From your description, I think your calling of render partial: "header" could be interfering with the CSS you have throughout your document. Remember, just because you're calling a partial doesn't mean it has no CSS styling -- your classes will still have styling, which are likely defined in your CSS somewhere

Why not try this:

#app/layouts/application.html.erb
<%= content_for :header %>

#app/controllers/application_controller.rb
include ApplicationHelper

#Content_For
def view_context
    super.tap do |view|
        (@_content_for || {}).each do |name,content|
            view.content_for name, content
        end
    end
end

def content_for(name, content) # no blocks allowed yet
    @_content_for ||= {}
    if @_content_for[name].respond_to?(:<<)
        @_content_for[name] << content
    else
        @_content_for[name] = content
    end
end

def content_for?(name)
    @_content_for[name].present?
end

#app/controllers/products_controller.rb
def index
    content_for :header, render partial: "products/header" #-> not sure if syntax is right
end

This will load the header content_for block if there is content inside

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM