# Optional Partials in the Layout

**URL:** <https://www.ruby-forum.com/t/optional-partials-in-the-layout/116598>\
**Category:** Rails\
**Created:** [October 7, 2007, 8:26pm UTC](https://www.ruby-forum.com/t/optional-partials-in-the-layout/116598 "2007-10-07T20:26:27Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mozmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@Mozmonkey](https://www.ruby-forum.com/u/Mozmonkey)\
**Post date:** [October 7, 2007, 8:26pm UTC](https://www.ruby-forum.com/t/optional-partials-in-the-layout/116598/1 "2007-10-07T20:26:27Z")

</div>

I want to include a partial in the layout that might not exist. :o)  
Here’s an example: Some flows have specific CSS or JavaScript and I’d  
like to automatically include those in the HTML (via the  
layout), so it would be great to have an optional file in called  
\_head.rhtml in the views that need it – but not all views.

Does my question make sense?

- Jeremy

---

<div class="post-metadata">

**Author:** ![Mozmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@Mozmonkey](https://www.ruby-forum.com/u/Mozmonkey)\
**Post date:** [October 7, 2007, 10:24pm UTC](https://www.ruby-forum.com/t/optional-partials-in-the-layout/116598/2 "2007-10-07T22:24:27Z")

</div>

Mozmonkey wrote:

> I want to include a partial in the layout that might not exist. :o)  
> Here’s an example: Some flows have specific CSS or JavaScript and I’d  
> like to automatically include those in the HTML (via the  
> layout), so it would be great to have an optional file in called  
> \_head.rhtml in the views that need it – but not all views.

One way would be to simply wrap the includes with a conditional:

 \<% if params[:controller].eql?('certain\_controller') %\> \<%= javascript\_include\_tag 'some-javascript' %\> \<% end %\> ...

That sort of code can get pretty ugly, so I’d put the whole thing into a  
helper. I’m sure someone here has a better way though… 🙂

---

<div class="post-metadata">

**Author:** ![Mozmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@Mozmonkey](https://www.ruby-forum.com/u/Mozmonkey)\
**Post date:** [October 8, 2007, 5:05pm UTC](https://www.ruby-forum.com/t/optional-partials-in-the-layout/116598/3 "2007-10-08T17:05:54Z")

</div>

You could always create a partial at app/views/shared/\_head.rhtml, and  
include it on every page. Inside that partial you could place:

case params[:controller]  
when :application  
…  
end  
when :accounts  
…  
end  
end

Same effect as what Daniel said, but at least all your JS/CSS stuff is  
kept in one file (and you could be tricky and keep common JS/CSS above  
or below the case statement to make sure it’s included on every page,  
leaving the blocks inside the case for the specialized JS/CSS).

On Oct 7, 3:24 pm, Daniel W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Mozmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@Mozmonkey](https://www.ruby-forum.com/u/Mozmonkey)\
**Post date:** [October 9, 2007, 11:20pm UTC](https://www.ruby-forum.com/t/optional-partials-in-the-layout/116598/4 "2007-10-09T23:20:32Z")

</div>

Simpliest way I have found is to do this:-

\<%=render :partial=\>“side\_menu” rescue “”-%\>

This way if you have a \_side\_menu.rhtml file in the controller then it  
will use it otherwise display nothing.

---

<div class="post-metadata">

**Author:** ![Mozmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@Mozmonkey](https://www.ruby-forum.com/u/Mozmonkey)\
**Post date:** [October 8, 2007, 11:27pm UTC](https://www.ruby-forum.com/t/optional-partials-in-the-layout/116598/5 "2007-10-08T23:27:05Z")

</div>

Thanks for both of your suggestions. With that direction I came up  
with a helper that would give me even more control.

Here’s how it works. I have a directory called “shared” directly  
under views – this directory is for global partials. I can also have  
a partial in the controller view directory with the same name as one  
in the shared directory. For example, if I use it like this:

```
<%= shared :head %>
```

The helper will start by looking in the controller view directory for  
“\_head.rhtml” (i.e. views/users/\_head.rhtml) and if it’s not there  
load up the one in the shared directory (i.e. views/shared/  
\_head.rhtml). You can also have it include both with the :both  
option:

```
<%= shared :head, :both => true %>
```

This way “user” pages can include more scripts and CSS in the head  
than the default “shared” set. Here’s my code, let me know what you  
think:

```
#
  # Retreive a partial that can be local to the view or in the shared
directory.
  #
  # = EXAMPLE - For a sidebar
  # shared/_sidebar.rhtml - Default global sidebar
  # search/_sidebar.rhtml - Used for views under search
  # welcome/ (no sidebar.rhtml) - Pages under welcome/ use shared/
_sidebar.rhtml
  #
  # = OPTIONS
  # * :both=>true: This includes both the global and local version 
(if
it exists). The global will always be included first
  #
  def shared(name, options=false)

    content = ""
    name = name.to_s
    file = "_#{name}.rhtml";

    # Render global
    if options && options[:both]
      content = render(:file => "shared/#{file}")
    end

    # Check local
    if File.exist?("#{File.dirname( __FILE__ )}/../views/
#{params[:controller]}/#{file}")
      content < name)
    elsif !options || !options[:both]
      content = render(:file => "shared/#{file}")
    end

    return content
  end
```
