# Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com # All files in this distribution are subject to the terms of the Ruby license. module Ramaze # LinkHelper is included into the Controller by default # # Usage is shown in spec/ramaze/helper/link.rb and the rdocs below. module LinkHelper private # Builds a basic tag. # # `title` is mandatory, the second hash of options will be transformed into # arguments of the tag, :href is a special case and its segments will be # CGI.escaped. # # If you pass no :href, the title will be run through Rs and its result is # used instead. If you really want an empty href, use :href => '' # # Usage: # A('title') #> title # A('foo/bar') #> foo/bar # A('/foo?x=y') #> /foo?x=y # A('title', :href => '/foo?x=y') #> title # A('Home', :href => Rs(:/)) #> Home def A(*args) hash = args.last.respond_to?(:to_hash) ? args.pop : {} hash[:href] ||= Rs(*args) title = hash.delete(:title) || (args.last.respond_to?(:to_s) ? args.last : nil) || hash[:href] hash[:href].to_s.sub!(/\A[^\/?]+/) {|m| CGI.escape(m) } args = [''] hash.each {|k,v| args << %(#{k}="#{v}") if k and v } %(#{title}) end # Builds links out of segments. # # Pass it strings, symbols, controllers and it will produce a link out of # it. Paths to Controllers are obtained from Global.mapping. # # For brevity, the mapping for the example below is following: # { MC => '/', OC => '/o', ODC => '/od' } # # Usage: # R(MC) #=> '/' # R(OC) #=> '/o' # R(ODC) #=> '/od' # R(MC, :foo) #=> '/foo' # R(OC, :foo) #=> '/o/foo' # R(ODC, :foo) #=> '/od/foo' # R(MC, :foo, :bar => :x) #=> '/foo?bar=x' def R(*atoms) args, atoms = atoms.flatten.partition{|a| a.is_a?(Hash) } args = args.flatten.inject{|s,v| s.merge!(v) } map = Global.mapping.invert atoms.map! do |atom| if atom.is_a?(Ramaze::Controller) map[atom.class] || atom else map[atom] || atom end end front = atoms.join('/').squeeze('/') if args rear = args.inject('?'){|s,(k,v)| s << "#{k}=#{v};"}[0..-2] front + rear else front end end # Uses R with Controller.current as first element. def Rs(*atoms) atoms.unshift Controller.current unless atoms.first.is_a?(Controller) R(*atoms) end # Give it a path with character to split at and one to join the crumbs with. # It will generate a list of links that act as pointers to previous pages on # this path. # # Example: # breadcrumbs('/path/to/somewhere') # # # results in this, newlines added for readability: # # path/ # to/ # somewhere # # Optionally a href prefix can be specified which generate link # names a above, but with the prefix prepended to the href path. # # Example: # breadcrumbs('/path/to/somewhere', '/', '/', '/mycontroller/action') # # # results in this, newlines added for readability: # # path/ # to/ # somewhere def breadcrumbs(path, split = '/', join = '/', href_prefix = '') atoms = path.split(split).reject{|a| a.empty?} crumbs = atoms.inject([]){|s,v| s << [s.last,v]} bread = crumbs.map do |a| href_path = href_prefix + a*'/' A(a[-1], :href=>(href_path)) end bread.join(join) end end end