Best practices with templating

I’ve come up with two ways of breaking the rendering of my actions out
into a form of templates, and am wondering which (if either) is
considered “standard practice” by the rails community. Right now the
layout is fairly basic, but I’m trying to break things out into “chunks”
rather than repeating a lot of HTML throughout each main layout, and so
am considering having partials for things like the ‘subnav’, ‘sidebar’,
etc areas.

Currently, I am doing the following:

#app/controllers/company_controller.rb
@partials[‘sidebar’,‘subnav’]

#app/views/layouts/standard.html.erb
<%= render :partials => ‘sidebar’ if @partials.include?(‘sidebar’) %>

<%= render :partials => ‘subnav’ if @partials.include?(‘subnav’) %>

Would that be the best way, or would something like this be better:
#app/controllers/company_controller.rb

Gets the current action being processed, in a ‘before_filter’

@action = current_action

#app/views/layouts/standard.html.erb
<%= render :partials => “#{@action}_sidebar” if
partial_exists?("#{@action}_sidebar") %>

<%= render :partials => “#{@action}_subnav” if
partial_exists?("#{@action}_subnav") %>

As well, I could go for a combination approach:
#app/controllers/company_controller.rb

Gets the current action being processed, in a ‘before_filter’

@action_partials = []
[:sidebar,:subnav].each { |p| @action_partials[p] = current_action }

def index

Override the subnav partial

@action_partials[‘subnav’] = nil

end

#app/views/layouts/standard.html.erb
<%= render :partials => “#{@action_partials[:sidebar]}_sidebar” if
(!@action_partials[:sidebar].nil? and
partial_exists?("#{@action_partials[:sidebar]}_sidebar")) %>

<%= render :partials => “#{@action_partials[:subnav]}_subnav” if
(!@action_partials[:subnav].nil? and
partial_exists?("#{@action_partials[:subnav]}_subnavr")) %>

The first approach means checking the current action in the partials if
I need to render differing content based on that action, which I think
is the wrong way to do things.

The second means differing partials on a per-action basis, at the cost
of needing to repeat myself if any actions need a partial to render the
same content.

The third means increased flexibility and customization at the cost of
some code complexity.

I’m just curious if anyone has dealt with anything like this, and what
their approach(es) were?

Philip S. wrote:

#app/views/layouts/standard.html.erb
<%= render :partials => “#{@action_partials[:sidebar]}_sidebar” if
(!@action_partials[:sidebar].nil? and
partial_exists?("#{@action_partials[:sidebar]}_sidebar")) %>

<%= render :partials => “#{@action_partials[:subnav]}_subnav” if
(!@action_partials[:subnav].nil? and
partial_exists?("#{@action_partials[:subnav]}_subnavr")) %>

Note that this could be reduced (with the necessary methods in
ApplicationHelpter) to something like:

<%= get_template :sidebar if has_template :sidebar %>

<%= get_template :subnav if has_template :subnav %>

On Dec 28, 2007 12:45 PM, Philip S.
[email protected] wrote:

Gets the current action being processed, in a ‘before_filter’

#app/controllers/company_controller.rb
#app/views/layouts/standard.html.erb
The first approach means checking the current action in the partials if
I’m just curious if anyone has dealt with anything like this, and what
their approach(es) were?

I think that the more standard approach is the fourth.

In the layout:


<%= yield :sidebar %>
<%= yield :sidenav %>


Then within, say app/views/company/index.html.erb

<% content_for(:sidebar) do %>
stuff for the sidebar here, can render partials, be inline etc.
<% end %>

If for a particular controller/action no content_for is executed for a
given symbol, say :subnav, then the yield :subnav in the layout will
return nil which will in turn put an empty string in it’s place.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

I think that the more standard approach is the fourth.

In the layout:


<%= yield :sidebar %>
<%= yield :sidenav %>


blinks How on earth did I miss that? Anyway, that’s a LOT cleaner
(and actually, pretty much exactly what I was hoping I could do),
however, I’m wondering if there’s any way to check if a given
‘content_for’ block exists, because in your case, if you do:

<%= yield :sidebar %>

And sidebar returns an empty string, you’ll still have the

kicking around … is there any way to avoid that?

On Dec 28, 10:37 am, Philip S. [email protected]
wrote:

<%= yield :sidebar %>

And sidebar returns an empty string, you’ll still have the

kicking around … is there any way to avoid that?

Put the div in the partial?

///ark

Mark W. wrote:

On Dec 28, 10:37�am, Philip S. [email protected]
wrote:

� <%= yield :sidebar %>

And sidebar returns an empty string, you’ll still have the

kicking around … is there any way to avoid that?

Put the div in the partial?

///ark

That then seems non-DRYish … especially if I need the content_for
block to be duplicated elsewhere:

<%= yield :navigation %>
... ... ...
<%= yield :navigation %>

A very simplistic example but possibly a common one.

On 28 Dez., 19:37, Philip S. [email protected]
wrote:

however, I’m wondering if there’s any way to check if a given
‘content_for’ block exists, because in your case, if you do:

<%= yield :sidebar %>

And sidebar returns an empty string, you’ll still have the

kicking around … is there any way to avoid that?

<% unless yield(:sidebar).blank? %>

<%= yield :sidebar %>
<% end %>

Java wrote:

On 28 Dez., 19:37, Philip S. [email protected]
wrote:

however, I’m wondering if there’s any way to check if a given
‘content_for’ block exists, because in your case, if you do:

� <%= yield :sidebar %>

And sidebar returns an empty string, you’ll still have the

kicking around … is there any way to avoid that?

<% unless yield(:sidebar).blank? %>

<%= yield :sidebar %>
<% end %>

Alright … I was just wondering if there was any better way of doing
things. I guess there isn’t :slight_smile:

Nathan E. wrote:

I firmly recommend making that a helper function in application_helper.
Namely:

def yield_content_for(name)
unless yield(:sidebar).blank?
content_tag(:div, yield name, :id => name.to_s)
end
nil
end

That will keep things DRY and keep conditionals out of your views.

Excellent … this is all coming together in my head now. Thanks!

I firmly recommend making that a helper function in application_helper.
Namely:

def yield_content_for(name)
unless yield(:sidebar).blank?
content_tag(:div, yield name, :id => name.to_s)
end
nil
end

That will keep things DRY and keep conditionals out of your views.

On Dec 29, 2007, at 11:14 AM, Philip S. wrote:

This isn’t working for me - “no block given” is the error I keep
getting. Any suggestions on how to fix that (I fixed the error in the
code - changed :sidebar to name)?

Hi Philip,

You might find this article of interest.

http://www.railsdev.ws/blog/3/modular-page-assembly-in-rails/

I meant to post it earlier, but forgot to. It might answer some of
your questions.

Peace,
Phillip

Nathan E. wrote:

I firmly recommend making that a helper function in application_helper.
Namely:

def yield_content_for(name)
unless yield(:sidebar).blank?
content_tag(:div, yield name, :id => name.to_s)
end
nil
end

That will keep things DRY and keep conditionals out of your views.

This isn’t working for me - “no block given” is the error I keep
getting. Any suggestions on how to fix that (I fixed the error in the
code - changed :sidebar to name)?

Phillip K. wrote:

On Dec 29, 2007, at 11:14 AM, Philip S. wrote:

This isn’t working for me - “no block given” is the error I keep
getting. Any suggestions on how to fix that (I fixed the error in the
code - changed :sidebar to name)?

Hi Philip,

You might find this article of interest.

WEBSITE.WS - Your Internet Address For Life™

I meant to post it earlier, but forgot to. It might answer some of
your questions.

Peace,
Phillip

Hi Phillip (I’m glad you have two "l"s - that’ll alleviate at least some
confusion ;)),

It looks like it might help answering some of those questions indeed.
Thanks!