Skip to content

Instantly share code, notes, and snippets.

@agibralter
Created May 12, 2009 21:47
Show Gist options
  • Save agibralter/110754 to your computer and use it in GitHub Desktop.
Save agibralter/110754 to your computer and use it in GitHub Desktop.
module ApplicationHelper
def ul(opts={}, &block)
ListBuilder.new(@template, block, opts)
end
def ul_nav(&block)
ul(:class => 'nav', &block)
end
end
<% ul_nav do |ul| %>
<%= ul.link_to "hello", '#' %>
<%= ul.link_to "middle", '#' %>
<%= ul.link_to "goodbye", '#' %>
<% end %>
<ul class="nav">
<li class="first"><a href="#">hello</a></li>
<li><a href="#">middle</a></li>
<li class="last"><a href="#">goodbye</a></li>
</ul>
<% ul_nav do |ul| %>
<% ul.li do %>
<%= link_to "Hello", '#' %>, my child...
<% end %>
<% ul.li do %>
<% 3.times do %>
<%= link_to "middle!", '#' %>
<% end %>
<% end %>
<%= ul.link_to "goodbye", '#' %>
<% end %>
<ul class="nav">
<li class="first">
<a href="#">Hello</a>, my child...
</li>
<li>
<a href="#">middle!</a>
<a href="#">middle!</a>
<a href="#">middle!</a>
</li>
<li class="last"><a href="#">goodbye</a></li>
</ul>
class ListBuilder
class List
def initialize(template)
@items = []
@template = template
end
def li(&block)
@items << ListItem.new(nil, &block)
nil
end
def method_missing(method, *args, &block)
@items << ListItem.new(method, *args, &block)
nil
end
def generate(spacer)
@items.each_with_index do |item, i|
place = case i
when 0: :first
when (@items.size-1): :last
else
nil
end
item.generate(@template, place.to_s)
@template.concat(@template.content_tag('li', spacer || '|', :class => 'spacer')) unless place == :last
end
end
end
class ListItem
def initialize(method, *args, &block)
@method = method
@args = args
@block = block
end
def generate(template, place=nil)
if @method.nil?
template.concat("<li class=\"#{place}\">")
template.instance_eval(&@block)
template.concat('</li>')
else
template.concat(template.content_tag(
'li',
template.send(@method, *@args, &@block),
:class => place
))
end
end
end
def initialize(template, block, opts={})
template.concat("<ul class=\"#{opts[:class]}\">")
list = List.new(template)
block.call(list)
list.generate(opts[:spacer])
template.concat('</ul>')
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment