Skip to content

Instantly share code, notes, and snippets.

@stex
Last active October 11, 2015 05:07
Show Gist options
  • Save stex/3807634 to your computer and use it in GitHub Desktop.
Save stex/3807634 to your computer and use it in GitHub Desktop.
A helper method for creating breadcrumbs based on Models. The output partial adds bootstrap dropdown functionality and generally the bootstrap breadcrumbs view.
%ul.breadcrumb
- breadcrumbs.each do |breadcrumb_item|
%li{:class => breadcrumb_item[:classes].join(' ')}
- if breadcrumb_item[:collection] && breadcrumb_item[:collection].size > 1 #Elements with dropdowns
%a.dropdown-toggle{'data-toggle' => 'dropdown', :href => '#'}
= breadcrumb_item[:caption]
%span.caret
%ul.dropdown-menu
- breadcrumb_item[:collection].shift if breadcrumb_item[:active]
- breadcrumb_item[:collection].each do |bi|
= bi[:divider] ? navigation_divider : navigation_item(bi[:caption], bi[:url], :active => false)
- else #Elements without dropdowns
- if breadcrumb_item[:function]
= link_to_function breadcrumb_item[:caption], breadcrumb_item[:function], breadcrumb_item[:options]
- elsif breadcrumb_item[:url]
- if breadcrumb_item[:remote]
= link_to_remote(breadcrumb_item[:caption], :url => breadcrumb_item[:url], :html => breadcrumb_item[:options])
- else
= link_to breadcrumb_item[:caption], breadcrumb_item[:url], breadcrumb_item[:options]
- else
= breadcrumb_item[:caption]
- unless breadcrumb_item[:active]
%span.divider= '/'
# Generates a breadcrumbs structure based on model classes and records
# Example: model_breadcrumbs(Property, my_property)
# => "Properties » My Property Name"
# Element types can be:
# - Model Classes which will be localized and pluralized
# - Records: If the record has a "name" attribute, it will be used.
# Otherwise, the Record class and ID are used
# - Arrays: Are converted to a collection of their parsed contents, e.g.
# for dropdown menus.
# - Hash: has to contain the keys :caption and :url and will be converted
# to a link_to. Can use the key :options for additional html options
# - everything else will just be used for output.
#----------------------------------------------------------------------------
def model_breadcrumbs(*elements)
namespace = params[:controller].split('/').size > 1 ? params[:controller].split('/').first : nil
options = {:record_links => true, :model_links => true, :namespace => namespace }
if elements.last.is_a?(Hash)
options.merge!(elements.pop)
end
render :partial => 'breadcrumbs', :object => (elements.map {|e| breadcrumb_item(e, elements, options)})
end
private
def breadcrumb_item(element, elements, options)
klass = element.class
klass = ActiveRecord::Base if klass < ActiveRecord::Base
item = {}
item[:active] = element == elements.last
item[:classes] = item[:active] ? ['active'] : []
#We have to compare strings here, it seems to be a "feature" of case
#that "when Class" is true for all elements which are classes...
case klass.to_s
when 'Array'
item[:collection] = element.map {|e| breadcrumb_item(e, elements, options)}
item[:caption] = item[:collection].first[:caption]
item[:classes] << 'dropdown'
when 'ActiveRecord::Base'
item[:caption] = element.respond_to?('breadcrumb_caption') ? element.breadcrumb_caption :
element.class.human_name << ' #' << element.id
if options[:record_links] && element != elements.last
item[:url] = [options[:namespace], element].compact
end
when 'Class'
item[:caption] = element.respond_to?('breadcrumb_caption') ? element.breadcrumb_caption :
element.human_name(:count => 2)
if options[:model_links]
item[:url] = [options[:namespace], element.to_s.downcase.pluralize].compact
end
when 'Hash'
element.each do |k,v|
item[k] = v
end
else
item[:caption] = element
item[:divider] = true if element.nil?
end
item
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment