In my application.html.erb
layout for my app, I want to have a partial that renders if it exists for the given view. for example.
If the visitor is at http://example.com/users/show
, I'd want the partial /users/_sidebar.html.erb
to render.
But if the visitor were at say, http://example.com/user/locations/san_francisco
, I'd want the partial /users/locations/_sidebar.html.erb
to render.
So the thing here is that if there were no partial for that controller/action it would render some generic partial in my shared directory, and I'd rather not litter every single view with content_for
blocks ya know?
Any ideas guys?
You can render the partial view in the parent view using the HTML helper methods: @html. Partial() , @html. RenderPartial() , and @html. RenderAction() .
By default, if you use the :plain option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the layout: true option and use the . text. erb extension for the layout file.
local_assigns is a Rails view helper method that you can check whether this partial has been provided with local variables or not. Here you render a partial with some values, the headline and person will become accessible with predefined value.
My solution is a bit different. Throw this in your application helper:
def render_partial_if_exists(base_name, options={})
file_name = ::Rails.root.to_s+"/app/views/layouts/_#{base_name}.html.erb"
partial_name = "layouts/#{base_name}"
else_file_name = ::Rails.root.to_s+"/app/views/layouts/_#{options[:else]}.html.erb"
else_partial_name = "layouts/#{options[:else]}"
if File.exists?(file_name)
render :partial => partial_name
elsif (options.key?(:else) and !options[:else].nil? and File.exists?(else_file_name))
render :partial => else_partial_name
end
end
Then in your view:
<%= render_partial_if_exists "page_#{controller.action_name}_sidebar", :else => "page_sidebar" %>
In an edit action, if "layouts/page_edit_sidebar" exists it renders it, otherwise it will render a standby "layouts/page_sidebar"
Sean Behan has a great post on exactly this:
http://seanbehan.com/programming/render-partial-if-file-exists/
I might move it to a helper and tweak it a bit to:
<%= render_sidebar %>
# This method could use either the rescue or the if file exists technique.
def render_sidebar
render(:partial => "/#{controller.name}/sidebar"
rescue
#default side bar
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With