Skip to content

Commit

Permalink
Merge pull request #53 from r72cccp/master
Browse files Browse the repository at this point in the history
Added a four features to render_crumb
  • Loading branch information
andrew committed Oct 20, 2013
2 parents 301c629 + 1933a5d commit 5ee65f4
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 27 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ These are added to the *a* tag.
add_crumb "Home", '/', link_html_options: {title: "my link title"}
```

##You can set html instead text in first parameter.
If tag <code>a</code> present in this html, tag a not be a wrapper.

```ruby
add_crumb "<a class='glyphicons shield' href='/support'><i></i>Support</a>".html_safe, "", {}
```

## Options for render\_crumbs

render\_crumbs renders the list of crumbs as either html or xml
Expand Down Expand Up @@ -103,6 +110,7 @@ microdata: true

With this option, output will be blank if there are no breadcrumbs.


### Examples

```ruby
Expand All @@ -113,6 +121,13 @@ render_crumbs format: :html_list #=> <ul class="" id=""><li class=""><a href="/
render_crumbs format: :html_list, :microdata => true
#=> <ul class="" id=""><li class="" itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb">
# <a href="/" itemprop="url"><span itemprop="title">Home</span></a></li></ul>
add_crumb support_link, {:right_side => true, :links => "/support", :li_right_class => "pull-right hidden-phone"}
#=> <li class="pull-right hidden-phone">
#=> <span><a class="glyphicons shield" href="/support">
#=> <i></i>Support</a>
#=> </span>
#=> </li>
#=> <li class="divider pull-right hidden-phone"></li>
```

A crumb with a nil argument for the link will output an unlinked crumb.
Expand Down Expand Up @@ -147,18 +162,28 @@ Possible parameters for configuration are:
:html_separator
:xml_separator
:html_list_separator
:html_list_right_separator
:first_class
:last_class
:ul_id
:ul_class
:li_class
:li_right_class
:microdata
:last_crumb_linked
:truncate
:right_side
```

See `lib/crummy.rb` for a list of these parameters and their defaults.

###Individually for each crumb configuration:
```ruby
add_crumb support_link, {:right_side => true, :links => "/support", : li_class => "my_class", :li_right_class => "pull-right hidden-phone"}
```
Simple add that parameter to options hash.


## Live example application

An example application is available right inside this gem. That application is documented, see `example/README` for details about usage.
Expand Down
8 changes: 8 additions & 0 deletions lib/crummy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ class Configuration
attr_accessor :links
attr_accessor :skip_if_blank
attr_accessor :html_separator
attr_accessor :html_right_separator
attr_accessor :xml_separator
attr_accessor :xml_right_separator
attr_accessor :html_list_separator
attr_accessor :html_list_right_separator
attr_accessor :first_class
attr_accessor :last_class
attr_accessor :ul_id
Expand All @@ -23,12 +26,16 @@ class Configuration
attr_accessor :microdata
attr_accessor :last_crumb_linked
attr_accessor :truncate
attr_accessor :right_side

def initialize
@format = :html
@html_separator = " &raquo; ".html_safe
@html_right_separator = " &raquo; ".html_safe
@xml_separator = "crumb"
@xml_right_separator = "crumb"
@html_list_separator = ''
@html_list_right_separator = ''
@skip_if_blank = true
@links = true
@first_class = ''
Expand All @@ -39,6 +46,7 @@ def initialize
@microdata = false
@last_crumb_linked = true
@truncate = nil
@right_side = false
end

def active_li_class=(class_name)
Expand Down
95 changes: 70 additions & 25 deletions lib/crummy/standard_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,56 @@ class StandardRenderer
#
# Takes 3 options:
# The output format. Can either be xml or html. Default :html
# :format => (:html|:xml)
# :format => (:html|:xml)
# The separator text. It does not assume you want spaces on either side so you must specify. Default +&raquo;+ for :html and +crumb+ for xml
# :separator => string
# :separator => string
# Render links in the output. Default +true+
# :link => boolean
#
# :link => boolean
#
# Examples:
# render_crumbs #=> <a href="/">Home</a> &raquo; <a href="/businesses">Businesses</a>
# render_crumbs :separator => ' | ' #=> <a href="/">Home</a> | <a href="/businesses">Businesses</a>
# render_crumbs :format => :xml #=> <crumb href="/">Home</crumb><crumb href="/businesses">Businesses</crumb>
# render_crumbs :format => :html_list #=> <ul class="" id=""><li class=""><a href="/">Home</a></li><li class=""><a href="/">Businesses</a></li></ul>
#
#
# With :format => :html_list you can specify additional params: li_class, ul_class, ul_id
# The only argument is for the separator text. It does not assume you want spaces on either side so you must specify. Defaults to +&raquo;+
#
# render_crumbs(" . ") #=> <a href="/">Home</a> . <a href="/businesses">Businesses</a>
#
def render_crumbs(crumbs, options = {})

options[:skip_if_blank] ||= Crummy.configuration.skip_if_blank
return '' if options[:skip_if_blank] && crumbs.count < 1
options[:format] ||= Crummy.configuration.format
options[:separator] ||= Crummy.configuration.send(:"#{options[:format]}_separator")
options[:right_separator] ||= Crummy.configuration.send(:"#{options[:format]}_right_separator")
options[:links] ||= Crummy.configuration.links
options[:first_class] ||= Crummy.configuration.first_class
options[:last_class] ||= Crummy.configuration.last_class
options[:microdata] ||= Crummy.configuration.microdata if options[:microdata].nil?
options[:truncate] ||= Crummy.configuration.truncate if options[:truncate]
options[:last_crumb_linked] = Crummy.configuration.last_crumb_linked if options[:last_crumb_linked].nil?
options[:right_side] ||= Crummy.configuration.right_side

last_hash = lambda {|o|k=o.map{|c|
c.is_a?(Hash) ? (c.empty? ? nil: c) : nil}.compact
k.empty? ? {} : k.last
}
local_global = lambda {|crumb, global_options, param_name| last_hash.call(crumb).has_key?(param_name.to_sym) ? last_hash.call(crumb)[param_name.to_sym] : global_options[param_name.to_sym]}

case options[:format]
when :html
crumb_string = ''.html_safe
crumbs.each_with_index do |crumb, index|
crumb_string << options[:separator] unless(index == 0)
crumb_string << crumb_to_html(crumb, options[:links], options[:first_class], options[:last_class], (crumb == crumbs.first), (crumb == crumbs.last), options[:microdata], options[:last_crumb_linked], options[:truncate])
end
crumb_string = crumbs.map{|crumb|local_global.call(crumb, options, :right_side) ? nil :
crumb_to_html(crumb,
local_global.call(crumb, options, :links),
local_global.call(crumb, options, :first_class),
local_global.call(crumb, options, :last_class),
(crumb == crumbs.first),
(crumb == crumbs.last),
local_global.call(crumb, options, :microdata),
local_global.call(crumb, options, :last_crumb_linked),
local_global.call(crumb, options, :truncate))}.compact.join(options[:separator]).html_safe
crumb_string
when :html_list
# Let's set values for special options of html_list format
Expand All @@ -54,15 +68,44 @@ def render_crumbs(crumbs, options = {})
options[:ul_id] ||= Crummy.configuration.ul_id
options[:ul_id] = nil if options[:ul_id].blank?

crumb_string = ''.html_safe
crumbs.each do |crumb|
crumb_string << crumb_to_html_list(crumb, options[:links], options[:li_class], options[:first_class], options[:last_class], (crumb == crumbs.first), (crumb == crumbs.last), options[:microdata], options[:last_crumb_linked], options[:truncate], options[:separator])
end
crumb_string = content_tag(:ul, crumb_string, :class => options[:ul_class], :id => options[:ul_id])
crumb_string = crumbs.map{|crumb|local_global.call(crumb, options, :right_side) ? nil :
crumb_to_html_list(crumb,
local_global.call(crumb, options, :links),
local_global.call(crumb, options, :li_class),
local_global.call(crumb, options, :first_class),
local_global.call(crumb, options, :last_class),
(crumb == crumbs.first),
(crumb == crumbs.find_all{|crumb|
!last_hash.call(crumb).fetch(:right_side,false)}.compact.last),
local_global.call(crumb, options, :microdata),
local_global.call(crumb, options, :last_crumb_linked),
local_global.call(crumb, options, :truncate),
local_global.call(crumb, options, :separator))}.compact.join.html_safe
crumb_right_string = crumbs.reverse.map{|crumb|!local_global.call(crumb, options, :right_side) ? nil :

crumb_to_html_list(crumb,
local_global.call(crumb, options, :links),
local_global.call(crumb, options, :li_right_class),
local_global.call(crumb, options, :first_class),
local_global.call(crumb, options, :last_class),
(crumb == crumbs.first),
(crumb == crumbs.find_all{|crumb|!local_global.call(crumb, options, :right_side)}.compact.last),
local_global.call(crumb, options, :microdata),
local_global.call(crumb, options, :last_crumb_linked),
local_global.call(crumb, options, :truncate),
local_global.call(crumb, options, :right_separator))}.compact.join.html_safe
crumb_string = content_tag(:ul,
crumb_string+crumb_right_string,
:class => options[:ul_class],
:id => options[:ul_id])
crumb_string
when :xml
crumbs.collect do |crumb|
crumb_to_xml(crumb, options[:links], options[:separator], (crumb == crumbs.first), (crumb == crumbs.last))
crumb_to_xml(crumb,
local_global.call(crumb, options, :links),
local_global.call(crumb, options, :separator),
(crumb == crumbs.first),
(crumb == crumbs.last))
end * ''
else
raise ArgumentError, "Unknown breadcrumb output format"
Expand Down Expand Up @@ -90,16 +133,17 @@ def crumb_to_html(crumb, links, first_class, last_class, is_first, is_last, with
can_link ? link_to((truncate.present? ? name.truncate(truncate) : name), url, link_html_options) : (truncate.present? ? name.truncate(truncate) : name)
end
end

def crumb_to_html_list(crumb, links, li_class, first_class, last_class, is_first, is_last, with_microdata, last_crumb_linked, truncate, separator='')
name, url, options = crumb
options = {} unless options.is_a?(Hash)
can_link = url && links && (!is_last || last_crumb_linked)
can_link = url && links && (!is_last || last_crumb_linked) && !(/<\/a/ =~ name)
html_classes = []
html_classes << first_class if is_first
html_classes << last_class if is_last
html_classes << li_class
html_options = {:class => html_classes.join(' ').strip}
html_classes << first_class if is_first && !first_class.empty?
html_classes << last_class if is_last && !last_class.empty?
html_classes << li_class unless li_class.empty?
html_options = html_classes.size > 0 ? {:class => html_classes.join(' ').strip} : {}

if with_microdata
html_options[:itemscope] = true
html_options[:itemtype] = data_definition_url("Breadcrumb")
Expand All @@ -110,10 +154,10 @@ def crumb_to_html_list(crumb, links, li_class, first_class, last_class, is_first
else
html_content = can_link ? link_to((truncate.present? ? name.truncate(truncate) : name), url, options[:link_html_options]) : content_tag(:span, (truncate.present? ? name.truncate(truncate) : name))
end
html_content += separator unless separator.blank? || is_last
content_tag(:li, html_content, html_options)
content_tag(:li, html_content, html_options)+(/<\/li/ =~ separator ?
separator : content_tag(:li, separator) unless separator.blank? || is_last)
end

def crumb_to_xml(crumb, links, separator, is_first, is_last)
name, url = crumb
content_tag(separator, name, :href => (url && links ? url : nil))
Expand All @@ -124,3 +168,4 @@ def data_definition_url(type)
end
end
end

4 changes: 2 additions & 2 deletions test/standard_renderer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test_classes
renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2']], :first_class => 'first', :last_class => 'last', :format => :html))
assert_equal('<ul class=""><li class="first li_class"><a href="url1">name1</a></li><li class="li_class"><a href="url2">name2</a></li><li class="last li_class"><a href="url3">name3</a></li></ul>',
renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2'], ['name3', 'url3']], :li_class => "li_class", :first_class => 'first', :last_class => 'last', :format => :html_list))
assert_equal('<ul class=""><li class="first li_class"><a href="url1">name1</a> / </li><li class="li_class"><a href="url2">name2</a> / </li><li class="last li_class"><a href="url3">name3</a></li></ul>',
assert_equal('<ul class=""><li class="first li_class"><a href="url1">name1</a></li><li> / </li><li class="li_class"><a href="url2">name2</a></li><li> / </li><li class="last li_class"><a href="url3">name3</a></li></ul>',
renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2'], ['name3', 'url3']], :li_class => "li_class", :first_class => 'first', :last_class => 'last', :format => :html_list, :separator => " / "))
assert_equal('<crumb href="url1">name1</crumb><crumb href="url2">name2</crumb>',
renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2']], :first_class => 'first', :last_class => 'last', :format => :xml))
Expand All @@ -52,7 +52,7 @@ def test_classes_last_crumb_not_linked
renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2']], :first_class => 'first', :last_class => 'last', :format => :html, :last_crumb_linked => false))
assert_equal('<ul class=""><li class="first li_class"><a href="url1">name1</a></li><li class="li_class"><a href="url2">name2</a></li><li class="last li_class"><span>name3</span></li></ul>',
renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2'], ['name3', 'url3']], :li_class => "li_class", :first_class => 'first', :last_class => 'last', :format => :html_list, :last_crumb_linked => false))
assert_equal('<ul class=""><li class="first li_class"><a href="url1">name1</a> / </li><li class="li_class"><a href="url2">name2</a> / </li><li class="last li_class"><span>name3</span></li></ul>',
assert_equal('<ul class=""><li class="first li_class"><a href="url1">name1</a></li><li> / </li><li class="li_class"><a href="url2">name2</a></li><li> / </li><li class="last li_class"><span>name3</span></li></ul>',
renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2'], ['name3', 'url3']], :li_class => "li_class", :first_class => 'first', :last_class => 'last', :format => :html_list, :separator => " / ", :last_crumb_linked => false))
assert_equal('<crumb href="url1">name1</crumb><crumb href="url2">name2</crumb>',
renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2']], :first_class => 'first', :last_class => 'last', :format => :xml, :last_crumb_linked => false))
Expand Down

0 comments on commit 5ee65f4

Please sign in to comment.