Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a four features to render_crumb #53

Merged
merged 17 commits into from
Oct 20, 2013
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