Rails rendering content_for not working for partials - ruby-on-rails

I am using a Rails 2.3.8 application. I have a layout file that contains
<%= yield :head %>
I called the following code in different parts of my application:
<% content_for :head do %>
<meta name="keywords" content="" />
<% end %>
I tried to add that code in a view file home it worked. I called it from patial _abc that is called from home it also worked as expected by adding the meta code in the head part. But when I added the code inside partial _def that is called from _abc which is called from home the meta tag did not show up!!!
I didnt usderstand what is going on... and how can bypass this problem
UPDATE: The case that did not work was:
home.html.erb:
<%= render :partial=>"_abc"%>
_abc.html.erb:
<%= render :partial=>"_def"%>
_def.html.erb:
<% content_for :head do %>
<meta name="keywords" content="" />
<% end %>
Thanks a lot

This is an old question, but I got here with a similar issue. Figured I'd post my issue/solution in case someone else lands here.
Which file is <%= yield :head %> in? I had this issue and it turned out my yield was in the "/layouts/application.html.erb" file... But the view being called was using a different layout file i.e. "/layouts/listings.html.erb". once I moved the yield into the correct file, everything worked fine, and I had pretty much the same setup you described.

Related

Dynamic canonical tag

Lately, I've been making my site more SEO friendly. Everything has been fun and games
until the canonical tag came along.
My site index is structured like the following.
example.com/all show all products.
example.com/all?brand=levis shows all products from Levi's.
example.com/jeans shows all jeans.
I would want to have dynamic canonical tags that refer to mysite.com/all, mysite.com/all?brand=current-brand and mysite.com/current-category.
The site also has a filter option for color and brands which produces slugs like mysite.com/hoodies?color=grey and mysite/hoodies?brand=nike&color=green. In both cases, I would want to have a canonical referring to mysite.com/hoodies
I made an attempt to fix this with an if else solution without success.
How it's set up now is like the following:
views/layouts/application.html.erb
<%= yield :canonical %>
views/pages/about
<%= content_for :canonical do %>
<link rel="canonical" href="example.com/about/" />
<% end %>
views/products/show
<% content_for :canonical do %>
<link rel="canonical" href="<%="example.com/#{#product.id}/"%>" />
<% end %>
These two works fine but when it comes to the index page it becomes trickier.
First I tried
<% content_for :canonical do %>
<link rel="canonical" href="<%="example.com/#{#category.slug}/"%>" />
<% end %>
This solution works fine when you go by category but crashes when you go to mysite.com/all or mysite.com/all?brand=levis.
I tried to experiment with some if else statements where I tried to target the current slug but it all ended up with crashes.
Do you guys have any suggestions of what I can do?
I somewhat solved the problem by placing
<% content_for :canonical do %>
<link rel="canonical" href="<%="example.com/#{#category.slug}/"%>" />
<% end %>
Under
<% if #category %>
It does not work exactly as I described in the questing since there is no canonical for example.com/all?brand=levis nor example.com/all. But that might even be better for SEO since google might take /all and /jeans for duplicate content, I'm not 100% sure. If you have another better solution, share and I would be more than happy!

content_for are not rendering in partial views

I have a rails app which uses a layout
The simplified version looks like this:
<html>
<head>
<%= render 'layouts/head' # renders the "layouts/_head.html.erb" partial correctly
# the most head (css/js) content gets implemented here %>
</head>
<body>
<%= yield # renders the current action %>
<!-- implement alls scripts which should be exectued on the bottom of the page -->
<%= content_for :scripts_bottom %>
</body>
</html>
in my `layouts/_head.html.erb' I use
<%= content_for :scripts_head %>
<!-- it seems `content_for` instead of `yield` appends content -->
In my partials I place the following snippets to append them :scripts_head. (some of my partials should put javaScripts
<% content_for :scripts_head do %>
<%= javascript_include_tag 'some_script' %>
<% end %>
The content_for in the `layouts/head' renders nothing
How can I resolve that?
It looks like that partials are not able to append their content_for content when the content_for :blah do is placed BEHIND the echoing content_for / yield tag.
If I try try content_for :scripts_bottom it will get rendered at the bottom of the page.
Thanks in advance
Rails 3.2.14
ruby 2.0.0p247
instead of provide, try <%= content_for :scripts_head %>
If you want to use content_for then you need to yield it in your head instead of render.
So your header would look like:
<%= yield :scripts_head %>
Alternatively you can remove the content_for in your partial and just have the JS by itself like this:
<%= javascript_include_tag 'some_script' %>
Then you wouldn't have to change your layout file.
In your layouts/head partial, use yield :scripts_head not content_for

Yield layout in rails

I'm trying to add a layout to the application layout. I having trouble trying to figure out all the different layout solutions. First I tried just a layout inside a layout because I didn't fully grasp what partials are or if they are layouts also? Maybe I can start with that question. What is the difference between a layout and a partial.
Here is what I have right now. I'm trying to just separate out my header code which has a navigation and some other elements into a separate layout. I want this layout to be on all views. Meaning it should be a layout inside the applications layout along with other views that are been called when their controllers are called. Which is covered in my code with the <%= yield %>. That yeild works but the :header one does not.
Application Layout app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>home</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<div id="header"><%= yield(:header) %></div>
<%= yield %>
</body>
</html>
Header layout app/views/layouts/application.html.erb
<% content_for :header %>
<p>HEADER TEXT</p>
<% end %>
Why would the code above not work?
I also saw code like this that I tried but it gave me an error.
<%= render layouts/header %>
Can someone please explain all these different methods.
Thanks.
It's good practice to separate your header and footer into partials which you would live in the views/layouts folder as '_header.html.erb' and '_footer.html.erb' respectively.
You can then optionally wrap each partial with specific div's which is what you're trying to do with the header (you could do the same with the body too), and it would end up looking like this:
<!DOCTYPE html>
<html>
<head>
<title>home</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<div id="header">
<%= render 'layouts/header' %>
</div>
<%= yield %>
<div id="footer">
<%= render 'layouts/footer' %>
</div>
</body>
</html>
That will do what you want it to do.
Note that 'layouts/header' and 'layouts/footer' have '' around them.
To answer your question on what is the difference between a layout and a partial, well a layout is something that will used throughout your application, such as a consistent header or footer. A partial can be a layout, but it doesn't have to be, so you can partial specific to other views across your site.
<% content_for :header do %>
<p>HEADER TEXT</p>
<% end %>
You forgot the do
So - first - The yield syntax may or may not be correct, but I've never seen it, and I don't like it. I only ever call yield once in a file.
If you want to render a header in your application template file, that's certainly possible - my advice would be to place it in your template file directly - after all, that's what template files are for. If you want to completely encapsulate your header for some reason or another in seperate files, what you need is partials. You're going to do something like this:
<body>
<%= render :partial => "shared/header" %>
<%= yield %>
</body>
Which will render your header content, stored in /shared/_header.html.erb into the layout here.
Check out this guide here for more info

rails content_for does not get executed when doing render?

So I have a content_for inside my view for logging in and in the sessions controller, I have render :new when the user does not enter valid credentials. However, when it does render :new, I get a black and white page without any css or js. This is how my content_for look like
<% content_for :head do %>
<%= stylesheet_link_tag "user_sessions/new" %>
<%= javascript_include_tag 'user_sessions/new.onready' %>
<% end %>
Is there a work around to make sure that the above code gets executed when I do render?
My guess would be that you're not including the content_for anywhere. In app/views/layouts/application.html.erb (or whichever layout you're using for this page) make sure you've got something like the following:
<head>
<!-- your regular head content goes here -->
<%= content_for :head %>
</head>
When you pass a block to content_for, the contents of the block are stored to be used elsewhere. The call to content_for without a block will then insert that stored content.
See the docs for content_for for more info.
<head><%= content_for :head %></head>
didn't work for me, but
<head><%= yield :head %></head>
worked, i guess this is the right to do
Just remembering: yield calls the content, and :head is the parameter for content_for that u put in your rendered view, so u can put pieces of code anywhere of the application.html u want

RoR: How do I validate my pages when sometimes I have CSS links not in the HEAD?

I get this error when using the w3 validator: document type does not allow element "link" here
I mean, I know style links are suppossed to be in the head, but for an RoR project, it's more.. efficient? to only load what you need? cause, lets say, A stylesheet is loaded in a partial. and that partial is used on multiple pages. It makes sense, as far as DRYing things up goes, to include the stylesheet with the partial.
But it seems like DRYing things goes against W3C.
What do I do?
You shouldn't be putting <link> elements into your content like that. You can use ERB's blocks to yield the content into another part of your layout template, like this:
<% content_for :head do %>
<%= stylesheet_link_tag 'my_partial_styles' %>
<% end %>
<p>Your partial content...</p>
In your application layout, you can yield this content where it belongs:
<head>
<%= yield :head %>
</head>

Resources