content_for best practices

View: New views
8 Messages — Rating Filter:   Alert me  

content_for best practices

by Josh Kieschnick :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


recently i ready about using content_for to add more dynamic control
in my layouts.

wanting to keep DRY, i'm wondering what the best way is to use this is
if i'm wanting to check specific areas for content. based on if there
is or isn't, i would like to totally remove or add elements to the
page.

while the example i am including works, it seems like this would
probably be creating a lot more work than necessary...

<% if(yield :sidebar) %>
  <div id="sidebar">
    <%= yield :sidebar %>
  </div>
<% end %>

if this isn't a good way of doing it, please let me know why. and if
there is an easy / clean way of doing it.

Thanks for the help


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@...
To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: content_for best practices

by Jacob Atzen-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Josh wrote:

> recently i ready about using content_for to add more dynamic control
> in my layouts.
>
> wanting to keep DRY, i'm wondering what the best way is to use this is
> if i'm wanting to check specific areas for content. based on if there
> is or isn't, i would like to totally remove or add elements to the
> page.
>
> while the example i am including works, it seems like this would
> probably be creating a lot more work than necessary...
>
> <% if(yield :sidebar) %>
>   <div id="sidebar">
>     <%= yield :sidebar %>
>   </div>
> <% end %>
>
> if this isn't a good way of doing it, please let me know why. and if
> there is an easy / clean way of doing it.

Maybe you can find some inspiration from Err:

http://errtheblog.com/post/28

--
Cheers,
- Jacob Atzen

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@...
To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: content_for best practices

by Josh Kieschnick :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Thanks for the reply Jacob. That blog post was actually one of the
first links I came across.

I liked the idea for conditionals like this example:

  <%= (sidebar = yield :sidebar) ? sidebar : render(:partial =>
'shared/sidebar') %>

I guess I could do something like so:

view.rhtml:
  <% content_for :sidebar do %>
    <div id="sidebar">
      all of my content in here
    </div>
<% end %>

and then in my layout:
  <%= (sidebar = yield :sidebar) ? sidebar : '' %>

but I'm still having to type that sidebar div everytime.


On May 24, 4:32 pm, Jacob Atzen <j...@...> wrote:

> Josh wrote:
> > recently i ready about using content_for to add more dynamic control
> > in my layouts.
>
> > wanting to keep DRY, i'm wondering what the best way is to use this is
> > if i'm wanting to check specific areas for content. based on if there
> > is or isn't, i would like to totally remove or add elements to the
> > page.
>
> > while the example i am including works, it seems like this would
> > probably be creating a lot more work than necessary...
>
> > <% if(yield :sidebar) %>
> >   <div id="sidebar">
> >     <%= yield :sidebar %>
> >   </div>
> > <% end %>
>
> > if this isn't a good way of doing it, please let me know why. and if
> > there is an easy / clean way of doing it.
>
> Maybe you can find some inspiration from Err:
>
> http://errtheblog.com/post/28
>
> --
> Cheers,
> - Jacob Atzen


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@...
To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: content_for best practices

by Jacob Atzen-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Josh wrote:

> Thanks for the reply Jacob. That blog post was actually one of the
> first links I came across.
>
> I liked the idea for conditionals like this example:
>
>   <%= (sidebar = yield :sidebar) ? sidebar : render(:partial =>
> 'shared/sidebar') %>
>
> I guess I could do something like so:
>
> view.rhtml:
>   <% content_for :sidebar do %>
>     <div id="sidebar">
>       all of my content in here
>     </div>
> <% end %>
>
> and then in my layout:
>   <%= (sidebar = yield :sidebar) ? sidebar : '' %>
>
> but I'm still having to type that sidebar div everytime.

If you have a default sidebar, then you could just put the div in the
layout, right?

Or you could make it into a helper method, something like (untested):

def conditional_element(name)
   element = yield(name.to_sym)
   content_tag(:div, element, :id => name.to_s) if element
end

I'm not sure exactly what the problem you're trying to solve is, so
maybe I'm misunderstanding something :)

--
Cheers,
- Jacob Atzen


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@...
To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: content_for best practices

by Josh Kieschnick :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> def conditional_element(name)
>    element = yield(name.to_sym)
>    content_tag(:div, element, :id => name.to_s) if element
> end

I might could get something like that to work. Basically I am just
looking for a way to check and see if there is content for a specific
area and adjust my markup, ids and classes accordingly.

Say I have a 3 column layout, and if there is no sidebar content, i
want to be able to check and render a 2 column layout instead.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@...
To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: content_for best practices

by Jacob Atzen-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Josh wrote:

>> def conditional_element(name)
>>    element = yield(name.to_sym)
>>    content_tag(:div, element, :id => name.to_s) if element
>> end
>
> I might could get something like that to work. Basically I am just
> looking for a way to check and see if there is content for a specific
> area and adjust my markup, ids and classes accordingly.
>
> Say I have a 3 column layout, and if there is no sidebar content, i
> want to be able to check and render a 2 column layout instead.

Sounds like you're trying to squeeze two templates into one with a
resulting mess of conditional logic in the template. Perhaps it would be
easier to just make two templates and then select the corresponding
template from the controller dynamically? Or maybe I'm still not totally
clear on what you're trying to achieve ;)

--
Cheers,
- Jacob Atzen

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@...
To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: content_for best practices

by Josh Kieschnick :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Yes, that is what i was trying to do. haha...

Maybe in this case, i should just stick with simple instead of dry and
have two templates.

I did come up with something that worked for me for now though. This
is what I have currently:

<% left_col = yield :left_col -%>

        <% if left_col -%>
        <div id="left_col">
                <%= left_col -%>
        </div>
        <% end -%>

Thanks for your help though. I managed to learn a lot from the
examples you provided for other pieces of my project.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@...
To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: content_for best practices

by Andrew Vit :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


# helper

module ApplicationHelper

  def sidebar( args={}, html_options={}, &block )
    block_to_partial( 'shared/sidebar', args, html_options, block )
  end

  def block_to_partial( template, args, html_options, block )
    template_name = template.split('/').last
    args = { :title => args, :subtitle => nil } if args.is_a?(String)
&& !args.empty?
    html_options[:class] = if html_options[:class].nil?
      template_name
    else
      ( html_options[:class].split(' ') << template_name).join(' ')
    end
    vars = args.merge!  :options => html_options,
                        :@content_for_layout => capture(&block)
    concat render(:partial => template,
                  :locals => vars), block.binding
  end

end



# shared/_sidebar.rhtml

<% content_tag 'div', options do -%>
<%= content_tag 'h3', title %>
<%= content_tag('h4', subtitle) unless subtitle.blank? %>
<%= yield %>
<% end %>


# view

<% sidebar 'Companies', :id => 'companies_sidebar' do %>
<ul>...html lives here...</ul>
<% end %>


# explanation

I use the nested_layouts plugin and I find it invaluable... This
helper pattern makes a perfect addition for when I need to pass things
to other layers of my layout. You can use this in your case where you
use content_for.

I found block_to_partial somewhere on the interweb (forgot the source;
if you want credit, speak up!). I customized it so that I can pass a
String as the first parameter, which automatically becomes the title
variable in the partial. Otherwise, I can pass a Hash for the vars
needed in the partial that I don't want to consider "content":

sidebar :title=>'Companies', :subtitle=>'Mortgage Brokers' {...}

rather than yielding these as the content, it lets me render them as
part of the partial, however I might want them commonly formatted in
my partial temlate (DRYness!).

Based on this pattern, I've defined other helpers that accomplish
similar tasks. I used title as the only convention for all partials so
I could pass a string for it. This might not be necessary for your
case, and if you need to define other things instead, you can just
pass a hash when you call it.

It works well for all my needs. Improvements? Suggestions?

--Andrew Vit



On May 25, 5:40 am, Josh <jjkie...@...> wrote:

> Yes, that is what i was trying to do. haha...
>
> Maybe in this case, i should just stick with simple instead of dry and
> have two templates.
>
> I did come up with something that worked for me for now though. This
> is what I have currently:
>
> <% left_col = yield :left_col -%>
>
>         <% if left_col -%>
>         <div id="left_col">
>                 <%= left_col -%>
>         </div>
>         <% end -%>
>
> Thanks for your help though. I managed to learn a lot from the
> examples you provided for other pieces of my project.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@...
To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---