class Locomotive::Steam::Liquid::Tags::Nav

Display the children pages of the site, current page or the parent page. If not precised, nav is applied on the current page. The html output is based on the ul/li tags.

Usage:

{% nav site %} => <ul class=“nav”><li class=“on”><a href=“/features”>Features</a></li></ul>

{% nav site, no_wrapper: true, exclude: 'contact|about', id: 'main-nav', class: 'nav', active_class: 'on' }

Constants

Syntax

Attributes

current_locale[RW]
current_page[RW]
current_site[RW]
page_repository[RW]
services[RW]

Public Class Methods

new(tag_name, markup, options) click to toggle source
Calls superclass method
# File lib/locomotive/steam/liquid/tags/nav.rb, line 21
def initialize(tag_name, markup, options)
  markup =~ Syntax

  @source = ($1 || 'page').gsub(/"|'/, '')

  self.set_options(markup, options)

  super
end

Public Instance Methods

render(context) click to toggle source
# File lib/locomotive/steam/liquid/tags/nav.rb, line 31
def render(context)
  self.set_vars_from_context(context)

  set_template_if_asked

  # get all the children of a source: site (index page), parent or page.
  pages     = children_of(fetch_starting_page)
  _output   = self.build_entries_output(pages, context)

  if self.no_wrapper?
   _output
  else
    self.render_tag(:nav, id: @_options[:id], css: @_options[:class]) do
      self.render_tag(:ul) { _output }
    end
  end
end

Protected Instance Methods

bootstrap?() click to toggle source
# File lib/locomotive/steam/liquid/tags/nav.rb, line 291
def bootstrap?
  @_options[:bootstrap].to_bool
end
build_entries_output(pages, depth = 1, context) click to toggle source

Build recursively the links of all the pages.

@param [ Array ] pages List of pages

@return [ String ] The final HTML output

# File lib/locomotive/steam/liquid/tags/nav.rb, line 57
def build_entries_output(pages, depth = 1, context)
  output  = []

  pages.each_with_index do |page, index|
    css = []
    css << 'first'  if index == 0
    css << 'last'   if index == pages.size - 1

    output << self.render_entry_link(page, css.join(' '), depth, context)
  end

  output.join("\n")
end
children_of(page) click to toggle source

Get all the children of page. It filters the collection to only return pages which will be displayed in the nav.

# File lib/locomotive/steam/liquid/tags/nav.rb, line 86
def children_of(page)
  children  = (page_repository.children_of(page) || [])
  children
  .map { |child| decorate_page(child) }
  .select { |child| self.include_page?(child) }
end
decorate_page(page) click to toggle source
# File lib/locomotive/steam/liquid/tags/nav.rb, line 286
def decorate_page(page)
  klass = Locomotive::Steam::Decorators::I18nDecorator
  klass.new(page, current_locale, current_site.default_locale)
end
entry_css(page, extra_css = '') click to toggle source

Return the css of an entry (page).

@param [ Object ] page The page @param [ String ] extra_css The extra css

@return [ String ] The css

# File lib/locomotive/steam/liquid/tags/nav.rb, line 168
def entry_css(page, extra_css = '')
  ['link'].tap do |css|
    css << @_options[:active_class] if self.page_selected?(page)
    css << extra_css if !extra_css.blank?
  end.join ' '
end
entry_label(page, context) click to toggle source

Return the label of an entry. It may use or not the template given by the snippet option.

@param [ Object ] page The page

@return [ String ] The label in HTML

# File lib/locomotive/steam/liquid/tags/nav.rb, line 138
def entry_label(page, context)
  icon  = @_options[:icon] ? '<span></span>' : ''
  title = @_options[:liquid_render] ? @_options[:liquid_render].render({ 'page' => page }, registers: context.registers) : page.title

  if icon.blank?
    title
  elsif @_options[:icon] == 'after'
    "#{title} #{icon}"
  else
    "#{icon} #{title}"
  end
end
entry_url(page) click to toggle source

Return the localized url of an entry (page).

@param [ Object ] page The page

@return [ String ] The localized url

# File lib/locomotive/steam/liquid/tags/nav.rb, line 157
def entry_url(page)
  services.url_builder.url_for(page)
end
fetch_starting_page() click to toggle source

Get the first page used to list all the children. It depends on the source: site, parent, page or a fullpath

# File lib/locomotive/steam/liquid/tags/nav.rb, line 74
def fetch_starting_page
  case @source
  when 'site'    then page_repository.root
  when 'parent'  then page_repository.parent_of(current_page) || current_page
  when 'page'    then current_page
  else
    page_repository.by_fullpath(@source)
  end
end
include_page?(page) click to toggle source

Determine whether or not a page should be a part of the menu.

@param [ Object ] page The page

@return [ Boolean ] True if the page can be included or not

# File lib/locomotive/steam/liquid/tags/nav.rb, line 99
def include_page?(page)
  if !page.listed? || page.templatized? || !page.published?
    false
  elsif @_options[:exclude]
    (page.fullpath =~ @_options[:exclude]).nil?
  else
    true
  end
end
no_wrapper?() click to toggle source
# File lib/locomotive/steam/liquid/tags/nav.rb, line 295
def no_wrapper?
  @_options[:no_wrapper].to_bool
end
page_selected?(page) click to toggle source

Determine wether or not a page is currently the displayed one.

@param [ Object ] page The page

@return [ Boolean ]

# File lib/locomotive/steam/liquid/tags/nav.rb, line 115
def page_selected?(page)
  self.current_page.fullpath =~ /^#{page.fullpath}(\/.*)?$/
end
parse_snippet_template(template_name) click to toggle source

Parse the template of the snippet give in option of the tag. If the template_name contains a liquid tag or drop, it will be used an inline template.

# File lib/locomotive/steam/liquid/tags/nav.rb, line 254
def parse_snippet_template(template_name)
  source = if template_name.include?('{{')
    template_name
  else
    snippet = services.snippet_finder.find(template_name)
    if snippet
      snippet.liquid_source
    else
      Locomotive::Common::Logger.warn "[Liquid][Nav] unable to find the #{template_name} snippet"
      nil
    end
  end

  source ? ::Liquid::Template.parse(source) : nil
end
render_children_for_page?(page, depth) click to toggle source

Determine if the children of a page have to be rendered or not. It depends on the depth passed in the option.

@param [ Object ] page The page @param [ Integer ] depth The current depth

@return [ Boolean ] True if the children have to be rendered.

# File lib/locomotive/steam/liquid/tags/nav.rb, line 127
def render_children_for_page?(page, depth)
  depth.succ <= @_options[:depth].to_i && children_of(page).any?
end
render_entry_children(page, depth, context) click to toggle source

Recursively create a nested unordered list for the depth specified.

@param [ Array ] entries The children of the page @param [ Integer ] depth The current depth

@return [ String ] The HTML code

# File lib/locomotive/steam/liquid/tags/nav.rb, line 209
def render_entry_children(page, depth, context)
  entries = children_of(page)
  css     = self.bootstrap? ? 'dropdown-menu' : ''

  unless entries.empty?
    self.render_tag(:ul, id: "#{@_options[:id]}-#{page.slug.to_s.dasherize}", css: css) do
      self.build_entries_output(entries, depth, context)
    end
  else
    ''
  end
end
render_entry_link(page, css, depth, context) click to toggle source

Return the HTML output of a page and its children if requested.

@param [ Object ] page The page @param [ String ] css The current css to apply to the entry @param [ Integer] depth Used to know if the children has to be added or not.

@return [ String ] The HTML output

# File lib/locomotive/steam/liquid/tags/nav.rb, line 183
def render_entry_link(page, css, depth, context)
  url       = self.entry_url(page)
  label     = self.entry_label(page, context)
  css       = self.entry_css(page, css)
  options   = ''

  if self.render_children_for_page?(page, depth) && self.bootstrap?
    url       = '#'
    label     += %{ <b class="caret"></b>}
    css       += ' dropdown'
    options   = %{ class="dropdown-toggle" data-toggle="dropdown"}
  end

  self.render_tag(:li, id: "#{page.slug.to_s.dasherize}-link", css: css) do
    children_output = depth.succ <= @_options[:depth].to_i ? self.render_entry_children(page, depth.succ, context) : ''
    %{<a href="#{url}"#{options}>#{label}</a>} + children_output
  end
end
render_tag(tag_name, html_options = {}, &block) click to toggle source

Render any kind HTML tags. The content of the tag comes from the block.

@param [ String ] tag_name Name of the HTML tag (li, ul, div, …etc). @param [ String ] html_options Id, class, ..etc

@return [ String ] The HTML

# File lib/locomotive/steam/liquid/tags/nav.rb, line 278
def render_tag(tag_name, html_options = {}, &block)
  options = ['']
  options << %{id="#{html_options[:id]}"} if html_options[:id].present?
  options << %{class="#{html_options[:css]}"} if html_options[:css].present?

  %{<#{tag_name}#{options.join(' ')}>#{yield}</#{tag_name}>}
end
set_options(markup, options) click to toggle source

Set the value (default or assigned by the tag) of the options.

# File lib/locomotive/steam/liquid/tags/nav.rb, line 224
def set_options(markup, options)
  @_options = { id: 'nav', class: '', active_class: 'on', bootstrap: false, no_wrapper: false }

  markup.scan(::Liquid::TagAttributes) { |key, value| @_options[key.to_sym] = value.gsub(/"|'/, '') }

  @_options[:exclude] = Regexp.new(@_options[:exclude]) if @_options[:exclude]
end
set_template_if_asked() click to toggle source
# File lib/locomotive/steam/liquid/tags/nav.rb, line 232
def set_template_if_asked
  if @_options[:snippet]
    if template = parse_snippet_template(@_options[:snippet])
      @_options[:liquid_render] = template
    end
  end
end
set_vars_from_context(context) click to toggle source

Avoid to call context.registers to get the current page.

# File lib/locomotive/steam/liquid/tags/nav.rb, line 242
def set_vars_from_context(context)
  self.current_site       = context.registers[:site]
  self.current_page       = context.registers[:page]
  self.services           = context.registers[:services]
  self.current_locale     = context.registers[:locale]
  self.page_repository    = services.repositories.page
end