JJane navigation helper


/ Published in: Ruby
Save to your folder(s)

sample


Copy this code and paste it in your HTML
  1. class JJane
  2. module Helpers
  3. module NavigationHelper
  4.  
  5. # Breadcrumbs
  6. # :framing_tag (default=:div)
  7. # :include_self - if true then adds current page link(default=true)
  8. # :separator - wich separator use(default=' » ')
  9. # :before - what to write before breadcrumbs(default=' » ')
  10. # :after - what to write after breadcrumbs(default='')
  11. # :include_node - if true then include node title(default=false)
  12. # :before_node - what to draw before node(if :include_node specified)
  13. # :after_node - what to draw after node(if :include_node specified)
  14. # :html - hash of html options for :framing_tag
  15. def breadcrumbs options={}
  16. if controller_name=='site' then
  17. default_options = {
  18. :framing_tag => :div,
  19. :include_self => true,
  20. :before => '',
  21. :after => '',
  22. :separator => ' » ',
  23. :include_node => false,
  24. :before_node => '',
  25. :after_node => ''
  26. }
  27. default_html_options = { :id => 'breadcrumbs' }
  28.  
  29. if options[:html]
  30. options[:html] = default_html_options.merge(options[:html])
  31. else
  32. options[:html] = default_html_options
  33. end
  34. options = default_options.merge(options)
  35.  
  36. line = options[:before]
  37. @page.ancestors.each do |page|
  38. line += link_to(page.menu, root_url+page.url) + options[:separator]
  39. end
  40. line += link_to(@page.menu,root_url+@page.url) if options[:include_self]
  41.  
  42. if defined?(@node) && options[:include_node]
  43. line += options[:separator] +
  44. options[:before_node] +
  45. content_tag(:span,link_to(@node.title,root_url+@node.url),:class => 'node') +
  46. options[:after_node]
  47. end
  48.  
  49. line += options[:after]
  50.  
  51. content_tag options[:framing_tag], line, options[:html]
  52. end
  53. end
  54.  
  55. # simple navigation menu based on unordered lists
  56. # name - name of menu to display
  57. def menu menu_name, options = {}
  58. options = {
  59. :dir_class => 'dir',
  60. :active_dir_class => 'active',
  61. :active_link_class => 'active',
  62. :root => nil
  63. }.deep_merge(options)
  64.  
  65. ul_li_menu(menu_name,options) do |page|
  66. if page[:page].page_type=='directory'
  67. page[:page].menu
  68. else
  69. %[<a href="#{root_url+page[:page].url}" #{%[class="#{options[:active_link_class]}"] if options[:active_link_class] && page[:page]==@page}>#{page[:page].menu}</a>]
  70. end
  71. end
  72. end
  73.  
  74. # draws menu, but takes block that represent content of <li> tags
  75. # options:
  76. # :root - ID of page,if present draws child pages of this page
  77. def ul_li_menu menu_name, options = {}, &block
  78. raise 'no block given' unless block_given?
  79.  
  80. # collection
  81. if options[:root]
  82. begin
  83. collection = Page.find_by_name(options[:root]).self_and_descendants
  84. rescue
  85. collection = []
  86. end
  87. else
  88. collection = Page.find(:all, :order => 'lft ASC')
  89. end
  90.  
  91. # one SQL!
  92. pages = []
  93. Page.each_with_level(collection) do |page,level|
  94. pages << {
  95. :page => page,
  96. :level => level,
  97. :visible => page.visible_in_menu?(menu_name)
  98. }
  99. end
  100.  
  101. # deleting invisible pages
  102. this_level = 0
  103. destroy_this_level = false
  104. pages.each_index do |i|
  105. if destroy_this_level and (pages[i][:level] > this_level)
  106. pages[i] = nil
  107. else
  108. this_level = pages[i][:level]
  109. if pages[i][:visible]
  110. destroy_this_level = false
  111. else
  112. destroy_this_level = true
  113. pages[i] = nil
  114. end
  115. end
  116. end
  117. pages.compact!
  118.  
  119. # detecting children(ето делается для избежания дополнительного SQL-запроса)
  120. pages[0..-2].map! do |p|
  121. p.update(:have_children => p[:level] < pages[pages.index(p)+1][:level])
  122. end
  123. pages.last.update(:have_children => false) unless pages.empty?
  124.  
  125. # draw menu
  126. unless pages.empty?
  127. ul_li_for(pages,options,&block)
  128. else
  129. warning('pages array empty')
  130. end
  131. end
  132.  
  133. # Draws link to page specified by it's unique ID
  134. def link_to_page name, page_name, options={}
  135. link_to name, root_url+Page.find_by_name(page_name.to_s).url, options
  136. rescue
  137. warning("no such page with ID '#{page_name}'")
  138. end
  139.  
  140. # draws raw unordered list for 'pages' array
  141. # each element in 'pages' must be a hash with keys:
  142. # :level - deep of nesting
  143. # :have_children - boolean value that represents is this item have a children
  144. # :id - DOM id for <li> tag
  145. # :class - DOM class for <li> tag
  146. # content to include in <li>...</li> generated in block given to ul_li_for,like
  147. # ul_li_for(pages,options) do |page|
  148. # %[<a href="#{root_url+page[:page].url}">#{page[:page].menu}</a>]
  149. # end
  150. #
  151. # options:
  152. # :include_framing - unclide framing <ul> and </ul> tags?(default true)
  153. # :html - hash of html options(no default)
  154. # :dir_class - class for using in <li> tags of objects that has children(default nil)
  155. #--TODO
  156. # :active_dir_class что б опция бралась из блока,хехе,ебать
  157. #
  158. #++
  159. def ul_li_for pages, options={}, &block
  160. raise 'no block given' unless block_given?
  161.  
  162. options = {
  163. :dir_class => nil,
  164. :include_framing => true,
  165. :html => { :id => '', :class => ''}
  166. }.deep_merge(options)
  167.  
  168. menu = ''
  169.  
  170. menu += %[<ul#{' id="'+options[:html][:id]+'"' unless options[:html][:id].empty?}#{' class="'+options[:html][:class]+'"' unless options[:html][:class].empty?}>\n] if options[:include_framing]
  171.  
  172. pages.each_index do |i|
  173. previous = i==0 ? nil : pages[i-1]; current = pages[i]
  174.  
  175. l = ' '*current[:level]
  176.  
  177. menu += %[ #{l}#{"</ul>\n#{l}</li>\n"*(previous[:level]-current[:level])}] if previous and current[:level] < previous[:level]
  178.  
  179. menu += l+'<li'
  180. menu += ' id="'+current[:id].to_s+'"' if current[:id]
  181. class_string = ''
  182. class_string += options[:dir_class]+' ' if current[:have_children] && options[:dir_class]!=nil
  183. class_string += current[:class] if current[:class]!=nil
  184. menu += %[ class="#{class_string}"] if class_string!=''
  185. menu += '>'
  186.  
  187. if block_called_from_erb?(block)
  188. menu += capture(current,&block)
  189. else
  190. menu += yield(current)
  191. end
  192.  
  193. if current[:have_children]
  194. menu += "\n #{l}<ul>\n"
  195. else
  196. menu += "</li>\n"
  197. end
  198. menu += "</ul>\n</li>"*current[:level] if pages[i] == pages.last
  199. end
  200.  
  201. menu += "</ul>" if options[:include_framing]
  202.  
  203. if block_called_from_erb?(block)
  204. concat menu
  205. else
  206. return menu
  207. end
  208. end
  209.  
  210. # site map ul li
  211. def sitemap
  212. pages = []
  213. Page.each_with_level(Page.find(:all, :order => 'lft ASC')) do |page,level|
  214. pages << {
  215. :page => page,
  216. :level => level
  217. }
  218. end
  219. pages[0..-2].map! do |p|
  220. p.update(:have_children => p[:level] < pages[pages.index(p)+1][:level])
  221. end
  222. pages.last.update(:have_children => false) unless pages.empty?
  223.  
  224. ul_li_for pages do |page|
  225. %[<a href="#{root_url+page[:page].url}">#{page[:page].menu}</a>]
  226. end
  227. end
  228. end
  229. end
  230. end

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.