Skip to content

Instantly share code, notes, and snippets.

@esdras
Created November 18, 2009 14:28
Show Gist options
  • Save esdras/237894 to your computer and use it in GitHub Desktop.
Save esdras/237894 to your computer and use it in GitHub Desktop.
module ApplicationHelper
#
# @usage
#
# breadcrumb_for @post
# breadcrumb_for @post, 'comments'
# breadcrumb_for @post, @comment
# breadcrumb_for :namespace, @post, @comment
#
def breadcrumb_for *args
options = args.extract_options!
options[:skip] = options.is_a?(Array) ? options[:skip] : [options[:skip]]
aux = args.dup
has_prefix = aux.first.is_a?(Symbol)
prefix = aux.delete(aux.first) if has_prefix
breadcrumb = []
current = aux.last
args.each do |e|
unless args.empty? or options[:skip].include?(aux.last)
scope = aux.last
if scope.is_a?(ActiveRecord::Base)
label = scope.to_label
breadcrumb << { :label => scope.to_label, :url => resource_url_for(aux)}
breadcrumb << { :label => collection_label_for(scope), :url => collection_url_for(aux) }
elsif scope.is_a?(String)
# collection url in current controller
breadcrumb << {:label => collection_label_for(scope), :url => collection_url_for_current_controller(aux) }
end
end
aux.pop
end
apply_prefix_for breadcrumb, prefix if has_prefix
breadcrumb << {:label => 'Início', :url => namespace_or_root_path_for(prefix)} if has_prefix
current = breadcrumb.delete_at(0)
breadcrumb.reverse!.map! { |e| content_tag(:li, link_to(e[:label], eval(e[:url]))) }
if edit_or_new(current)
breadcrumb << content_tag(:li, link_to(current[:label], eval(current[:url])))
breadcrumb << content_tag(:li, edit_or_new(current)[:label])
else
breadcrumb << content_tag(:li, current[:label])
end
content_tag(:ul, breadcrumb, :id => 'breadcrumb')
end
# Tries to guess the url for a single resource based on a given array
# of resources. The last resource will be the current scope
# It returns something like "post_comment_path(@post, @comment)"
def resource_url_for *args
args = args.first if args.first.is_a?(Array)
aux = args.dup
entities = aux.select {|e| e.is_a?(ActiveRecord::Base) }.map {|e| "@#{e.class.to_s.downcase}" }
entities = entities.inspect.delete('"[]')
aux.map! { |e| e.class.to_s.downcase }
aux = aux.join('_')
"#{aux}_path(#{entities})"
end
# Tries to guess the url for a collection of resources based on a given array
# of resources. The last resource will be the current scope
# It returns something like "post_comments_path(@post)"
def collection_url_for *args
args = args.first if args.first.is_a?(Array)
aux = args.dup
if aux.size == 1
"#{methodize(aux.first).pluralize}_path"
else
scope = aux.delete(aux.last)
entities = aux.select {|e| e.is_a?(ActiveRecord::Base) }.map {|e| "@#{e.class.to_s.downcase}" }
entities = entities.inspect.delete('"[]')
aux.map! { |e| e.class.to_s.downcase }
aux = aux.join('_')
"#{aux}_#{methodize(scope).pluralize}_path(#{entities})"
end
end
# Tries to guess the colletion path for the current controller, when the
# current action is a collection action (like index). You must supply a
# string with the collection name. Ex: breadcrumb_for('posts').
# The example above will force the method bellow to be called returning
# something like this: "posts_path". If you call:
# breadcrumb_for(@post, 'comments') the method bellow will be called
# returning something like "post_comments_path(@post)"
def collection_url_for_current_controller *args
args = args.first if args.first.is_a?(Array)
aux = args.dup
if aux.size == 1
"#{aux.first}_path"
else
scope = aux.delete(aux.last)
entities = aux.select {|e| e.is_a?(ActiveRecord::Base) }.map {|e| "@#{e.class.to_s.downcase}" }
entities = entities.inspect.delete('"[]')
aux.map! { |e| e.class.to_s.downcase }
aux = aux.join('_')
"#{aux}_#{scope}_path(#{entities})"
end
end
# This method tries to return the "namespace_root_path" method if it is setted
# in config/routes.rb. If the root of the namespace is not setted it will return
# the "root_url"
def namespace_or_root_path_for namespace
methods.include?("#{namespace}_root_path") ? "#{namespace}_root_path" : "root_path"
end
# Aplies the namespace to all urls in a given array. The array suplied must
# be an array of hashes with a :url key
def apply_prefix_for bdc, prefix
bdc.each {|e| e[:url] = "#{prefix}_#{e[:url]}" }
end
# A helper to turn an object into a part of a method name
def methodize(entity)
entity.class.to_s.downcase
end
# Label display in a collection link breadcrumb
def collection_label_for resource
if resource.is_a?(ActiveRecord::Base)
resource.class.human_name(:count => 2).capitalize
elsif resource.is_a?(String)
resource.singularize.camelize.constantize.human_name(:count => 2).capitalize
else
resource.to_s.capitalize.pluralize
end
end
def edit_or_new(current)
new_page = "new_#{current[:url]}".gsub(/\(.*\)/, '')
edit_page = "edit_#{current[:url]}".gsub(/\(.*\)/, '')
if methods.include?(new_page)
return { :label => 'Cadastrar', :url => new_page } if current_page?(eval("new_#{current[:url]}"))
end
if methods.include?(edit_page)
return { :label => 'Editar', :url => new_page} if current_page?(eval("edit_#{current[:url]}"))
end
nil
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment