Module: Nanoc::Toolbox::Helpers::Navigation

Includes:
Helpers::Breadcrumbs, Helpers::LinkTo, HtmlTag
Defined in:
lib/nanoc/toolbox/helpers/navigation.rb

Overview

NANOC Helper for the Navigation related stuff.

This module contains functions for generating navigation menus for your pages, like navigation menu, breadcrumbs or a table of content for a given Item

Author:

Instance Method Summary collapse

Methods included from HtmlTag

#content_tag, #tag, #tag_options

Instance Method Details

Generate a Breadcrumb for a given item. The breadcrumbs, is starting with the root item and ending with the item itself.

Requires the Helper: Nanoc::Helpers::Breadcrumbs

Options Hash (options):

  • :depth (Interger) — default: 3

    maximum depth of the rendered menu

  • :collection_tag (String) — default: 'ol'

    tag englobing collection of items

  • :item_tag (String) — default: 'li'

    tag englobing item

  • :title_tag (String) — default: 'h2'

    tag englobing the title

  • :title (String) — default: ''

    Title of the menu, if nil will not display title

  • :separator (String) — default: ''

    Menu item separator

See Also:

  • Helpers::Breadcrumbs#breadcrumbs_for_identifier

78
79
80
81
82
83
84
85
# File 'lib/nanoc/toolbox/helpers/navigation.rb', line 78

def breadcrumb_for(identifier, options={})
  options[:collection_tag]   ||= 'ul'
  options[:collection_class] ||= 'breadcrumb'

  # Retreive the breadcrumbs trail and format them
  sections = find_breadcrumbs_trail(identifier)
  render_menu(sections, options)
end

Generate a navigation menu for a given item. The menu will be generated form the identifier of the desired root element. The root itself will not be rendered. It generate the menu by parsing all the descendent of the passed item.

Options Hash (options):

  • :kind (String) — default: 'article'

    The kind of items to display in the menu

  • :depth (Interger) — default: 3

    maximum depth of the rendered menu

  • :collection_tag (String) — default: 'ol'

    tag englobing collection of items

  • :item_tag (String) — default: 'li'

    tag englobing item

  • :title_tag (String) — default: 'h2'

    tag englobing the title

  • :title (String) — default: ''

    Title of the menu, if nil will not display title

  • :separator (String) — default: ''

    Menu item separator


26
27
28
29
30
31
32
33
34
35
36
# File 'lib/nanoc/toolbox/helpers/navigation.rb', line 26

def navigation_for(identifier, options={})
  # Get root item for which we need to draw the navigation
  root = @items.find { |i| i.identifier == identifier }

  # Do not render if there is no child
  return nil unless root.children

  # Find all sections, and render them
  sections = find_item_tree(root, options)
  render_menu(sections, options)
end

#render_menu(items, options = {}) ⇒ String

Render a Hash to a HTML List by default

Hash structure should be construct like this:

Link: is an hash with the following key
      - :title       => The content of the link
      - :link        => The link
      - :subsections => nil or an Array of Links

[{:title => 'Title', :link => 'http://example.com', :subsections =>  [{}, {}, ...]},{...}]

Results to an output like the following (by default):

<ul>
  <li>
    <a href="http://example.com">Title</a>
    <ul>
      <li><a href="">Title</a></li>
    </ul>
  </li>
  <li><a href="http://example.com">Title</a></li>
  <li><a href="http://example.com">Title</a></li>
</ul>

Options Hash (options):

  • :depth (Interger) — default: 3

    maximum depth of the rendered menu

  • :collection_tag (String) — default: 'ol'

    tag englobing collection of items

  • :item_tag (String) — default: 'li'

    tag englobing item

  • :title_tag (String) — default: 'h2'

    tag englobing the title

  • :title (String) — default: ''

    Title of the menu, if nil will not display title

  • :separator (String) — default: ''

    Menu item separator


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/nanoc/toolbox/helpers/navigation.rb', line 120

def render_menu(items, options={})
  options[:depth]            ||= 3
  options[:collection_tag]   ||= 'ol'
  options[:collection_class] ||= 'menu'
  options[:item_tag]         ||= 'li'
  options[:title_tag]        ||= 'h2'
  options[:title]            ||= nil
  options[:separator]        ||= ''


  # Parse the title and remove it from the options
  title =  options[:title] ? (options[:title_tag], options[:title]) : ''
  options.delete(:title_tag)
  options.delete(:title)

  # Decrease the depth level
  options[:depth] -= 1

  rendered_menu = items.map do |item|
    # Render only if there is depth left
    if options[:depth].to_i  > 0 && item[:subsections]
      output = render_menu(item[:subsections], options)
      options[:depth] += 1 # Increase the depth level after the call of navigation_for
    end
    output ||= ""
    (options[:item_tag], link_to_unless_current(item[:title], item[:link]) + options[:separator] + output)

  end.join()

  title + (options[:collection_tag], rendered_menu, :class => options[:collection_class]) unless rendered_menu.strip.empty?
end

#toc_for(item_rep, options = {}) ⇒ String

Generate a Table of Content for a given item. The toc will be generated form the item content. The parsing is done with Nokogiri through XPath.

Options Hash (options):

  • :path (String) — default: 'div[@class="section"]'

    Generic XPath for the sections

  • :depth (Interger) — default: 3

    maximum depth of the rendered menu

  • :collection_tag (String) — default: 'ol'

    tag englobing collection of items

  • :item_tag (String) — default: 'li'

    tag englobing item

  • :title_tag (String) — default: 'h2'

    tag englobing the title

  • :title (String) — default: ''

    Title of the menu, if nil will not display title

  • :separator (String) — default: ''

    Menu item separator

See Also:


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/nanoc/toolbox/helpers/navigation.rb', line 49

def toc_for(item_rep, options={})
  require 'nokogiri'
  item_rep = item_rep.rep_named(:default) if item_rep.is_a? Nanoc::Item

  options[:path]             ||= 'div[@class="section"]'

  # Retreive the parsed content and init nokogiri
  compiled_content = item_rep.instance_eval { @content[:pre] }
  doc = Nokogiri::HTML(compiled_content)
  doc_root = doc.xpath('/html/body').first
  return "" if doc_root.nil?

  # Find all sections, and render them
  sections = find_toc_sections(doc_root, options[:path])
  render_menu(sections, options) || ""
end