Search code examples
ruby-on-railscaptureblock

Rails weird capture block error


I have a helper method 'default_content_for' which can be used to provide default content for yield sections. However when I'm using it, I get weird output from the helper.

I'm pretty sure I'm probably missing something simple, but still not sure what is wrong.

The title ends up full of stuff above the beginning of the block. Like so:

<title>   Default Title&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt;      &lt;title&gt;   Default Title   </title>

application.html.erb

<!DOCTYPE html>
<html>
<head>

  <title>
  <% default_content_for :title do %>
    Default Title
  <% end %>
  </title>

  <%= stylesheet_link_tag :all %>
  <%= javascript_include_tag :defaults %>
  <%= csrf_meta_tag %>
</head>
<body>


<%= yield %>

</body>
</html>

<!DOCTYPE html>
<html>
<head>

  <title>
  <% default_content_for :title do %>
    Default Title
  <% end %>
  </title>

  <%= stylesheet_link_tag :all %>
  <%= javascript_include_tag :defaults %>
  <%= csrf_meta_tag %>
</head>
<body>


<%= yield %>

</body>
</html>

helper method

module ApplicationHelper
    def default_content_for(name, &block)
      name = name.kind_of?(Symbol) ? ":#{name}" : name
      out = eval("yield #{name}", block.binding)
      out = (out ? (out.empty? ? false : out): false) || capture(&block)
      concat(out)
    end
end

output

<!DOCTYPE html>
<html><head>

  <title>   Default Title&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt;      &lt;title&gt;   Survey Builder   </title>


  <script type="text/javascript" src="/javascripts/prototype.js?1314309079"></script>
<script type="text/javascript" src="/javascripts/effects.js?1314309079"></script>
<script type="text/javascript" src="/javascripts/dragdrop.js?1314309078"></script>
<script type="text/javascript" src="/javascripts/controls.js?1314309078"></script>
<script type="text/javascript" src="/javascripts/rails.js?1314309079"></script>
<script type="text/javascript" src="/javascripts/application.js?1314309078"></script>
  <meta content="authenticity_token" name="csrf-param">
<meta content="oG4mVUt5wy6aWdhbxmXa3tYh3DUgXVUQy9d6uxng6a0=" name="csrf-token">
</head>
<body>

<div id="user_nav">
        Logged in as KARL KIRCH
        <a href="/log_out">Log out</a>
</div>


<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>




</body></html>

Solution

  • Okay so I should read things. In rails 3 blocks are supposed to use the following form:

    <%= default_content_for :title do %>
    <% end %>
    

    Also helper methods are supposed to only return a string not a concat, so I changed my helper method like so (with suggestion from agmcleod

      module ApplicationHelper
        def default_content_for(name, &block)
          name = name.kind_of?(Symbol) ? ":#{name}" : name
          out = eval("yield #{name}", block.binding)
          if out && !out.empty?
            out
          else
            capture(&block)
          end
        end
      end