# 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