Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3, rendering a partial for the given controller if it exists?

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?

like image 725
JP Silvashy Avatar asked Mar 18 '11 02:03

JP Silvashy


People also ask

How do you render a partial?

You can render the partial view in the parent view using the HTML helper methods: @html. Partial() , @html. RenderPartial() , and @html. RenderAction() .

How can you tell Rails to render without a layout *?

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.

What is Local_assigns?

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.


2 Answers

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"

like image 128
Michael K Madison Avatar answered Sep 30 '22 02:09

Michael K Madison


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
like image 36
Alan Peabody Avatar answered Sep 30 '22 01:09

Alan Peabody