navi 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +41 -0
- data/Gemfile.lock +196 -0
- data/Guardfile +23 -0
- data/LICENSE.txt +20 -0
- data/README.textile +26 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/features/create_menu_items.feature +13 -0
- data/features/step_definitions/category_steps.rb +3 -0
- data/features/step_definitions/menu_item_steps.rb +19 -0
- data/features/step_definitions/page_steps.rb +3 -0
- data/features/step_definitions/web_steps.rb +211 -0
- data/features/support/env.rb +61 -0
- data/features/support/paths.rb +33 -0
- data/features/support/selectors.rb +39 -0
- data/lib/navi/helpers.rb +24 -0
- data/lib/navi/navigable/base.rb +16 -0
- data/lib/navi/navigable/instance_methods.rb +24 -0
- data/lib/navi/navigator/.base.rb.swo +0 -0
- data/lib/navi/navigator/base.rb +11 -0
- data/lib/navi/navigator/class_methods.rb +27 -0
- data/lib/navi/navigator/instance_methods.rb +57 -0
- data/lib/navi/railtie.rb +11 -0
- data/lib/navi/renderers/base.rb +31 -0
- data/lib/navi/renderers/simple_navigation.rb +30 -0
- data/lib/navi.rb +29 -0
- data/navi.gemspec +281 -0
- data/spec/blueprints.rb +16 -0
- data/spec/dummy/.gitignore +6 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/categories_controller.rb +7 -0
- data/spec/dummy/app/controllers/menu_items_controller.rb +15 -0
- data/spec/dummy/app/controllers/pages_controller.rb +7 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/category.rb +3 -0
- data/spec/dummy/app/models/menu_item.rb +2 -0
- data/spec/dummy/app/models/page.rb +3 -0
- data/spec/dummy/app/views/categories/_form.html.haml +2 -0
- data/spec/dummy/app/views/categories/edit.html.haml +5 -0
- data/spec/dummy/app/views/categories/index.html.haml +17 -0
- data/spec/dummy/app/views/categories/new.html.haml +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/menu_items/edit.html.haml +14 -0
- data/spec/dummy/app/views/menu_items/index.html.haml +11 -0
- data/spec/dummy/app/views/pages/_form.html.haml +2 -0
- data/spec/dummy/app/views/pages/edit.html.haml +5 -0
- data/spec/dummy/app/views/pages/index.html.haml +17 -0
- data/spec/dummy/app/views/pages/new.html.haml +5 -0
- data/spec/dummy/app/widgets/menu_editor/category/form/.display.html.haml.swo +0 -0
- data/spec/dummy/app/widgets/menu_editor/category/form/display.html.haml +7 -0
- data/spec/dummy/app/widgets/menu_editor/category/form_widget.rb +18 -0
- data/spec/dummy/app/widgets/menu_editor/display.html.haml +5 -0
- data/spec/dummy/app/widgets/menu_editor/page/form/.display.html.haml.swo +0 -0
- data/spec/dummy/app/widgets/menu_editor/page/form/display.html.haml +8 -0
- data/spec/dummy/app/widgets/menu_editor/page/form_widget.rb +18 -0
- data/spec/dummy/app/widgets/menu_editor/tree/display.html.haml +4 -0
- data/spec/dummy/app/widgets/menu_editor/tree/item.html.haml +7 -0
- data/spec/dummy/app/widgets/menu_editor/tree/items.html.haml +2 -0
- data/spec/dummy/app/widgets/menu_editor/tree_widget.rb +48 -0
- data/spec/dummy/app/widgets/menu_editor_widget.rb +11 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/cucumber.yml +8 -0
- data/spec/dummy/config/database.yml +19 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/navigable.rb +1 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/navigation.rb +7 -0
- data/spec/dummy/config/routes.rb +61 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/20110607155019_create_menu_items.rb +20 -0
- data/spec/dummy/db/migrate/20110607155202_create_categories.rb +13 -0
- data/spec/dummy/db/migrate/20110607160052_create_pages.rb +13 -0
- data/spec/dummy/db/schema.rb +41 -0
- data/spec/dummy/db/seeds.rb +15 -0
- data/spec/dummy/lib/tasks/.gitkeep +0 -0
- data/spec/dummy/lib/tasks/cucumber.rake +57 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/images/rails.png +0 -0
- data/spec/dummy/public/index.html +239 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/jquery-ui.js +11603 -0
- data/spec/dummy/public/javascripts/jquery-ui.min.js +406 -0
- data/spec/dummy/public/javascripts/jquery.js +8936 -0
- data/spec/dummy/public/javascripts/jquery.min.js +18 -0
- data/spec/dummy/public/javascripts/jquery_ujs.js +315 -0
- data/spec/dummy/public/javascripts/menu_items/index.js +40 -0
- data/spec/dummy/public/javascripts/rails.js +315 -0
- data/spec/dummy/public/robots.txt +5 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/cucumber +10 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/vendor/plugins/.gitkeep +0 -0
- data/spec/navi/helpers_spec.rb +5 -0
- data/spec/navi/navi_spec.rb +76 -0
- data/spec/navi/navigator_spec.rb +204 -0
- data/spec/navi/renderers/simple_navigation_spec.rb +49 -0
- data/spec/spec_helper.rb +125 -0
- metadata +683 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
ENV["RAILS_ENV"] ||= "test"
|
2
|
+
require File.expand_path("../../../spec/dummy/config/environment.rb", __FILE__)
|
3
|
+
require File.expand_path("../../../spec/blueprints.rb", __FILE__)
|
4
|
+
|
5
|
+
require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
|
6
|
+
require 'cucumber/rails/rspec'
|
7
|
+
|
8
|
+
require 'cucumber/rails/world'
|
9
|
+
require 'cucumber/rails3/active_record'
|
10
|
+
require 'cucumber/rails3/action_controller'
|
11
|
+
require 'cucumber/web/tableish'
|
12
|
+
|
13
|
+
require 'capybara/rails'
|
14
|
+
require 'capybara/cucumber'
|
15
|
+
require 'capybara/session'
|
16
|
+
require 'cucumber/rails/capybara/javascript_emulation' # Lets you click links with onclick javascript handlers without using @culerity or @javascript
|
17
|
+
|
18
|
+
# Tell apotomo to use this new view path, since it was looking at app/widgets and app/widgets/layouts
|
19
|
+
# It didn't know that the app was being run from inside spec/dummy
|
20
|
+
Apotomo::Widget.append_view_path File.join('spec', 'dummy', 'app', 'widgets')
|
21
|
+
Apotomo::Widget.append_view_path File.join('spec', 'dummy', 'app', 'widgets', 'layouts')
|
22
|
+
|
23
|
+
# Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
|
24
|
+
# order to ease the transition to Capybara we set the default here. If you'd
|
25
|
+
# prefer to use XPath just remove this line and adjust any selectors in your
|
26
|
+
# steps to use the XPath syntax.
|
27
|
+
Capybara.default_selector = :css
|
28
|
+
|
29
|
+
# If you set this to false, any error raised from within your app will bubble
|
30
|
+
# up to your step definition and out to cucumber unless you catch it somewhere
|
31
|
+
# on the way. You can make Rails rescue errors and render error pages on a
|
32
|
+
# per-scenario basis by tagging a scenario or feature with the @allow-rescue tag.
|
33
|
+
#
|
34
|
+
# If you set this to true, Rails will rescue all errors and render error
|
35
|
+
# pages, more or less in the same way your application would behave in the
|
36
|
+
# default production environment. It's not recommended to do this for all
|
37
|
+
# of your scenarios, as this makes it hard to discover errors in your application.
|
38
|
+
ActionController::Base.allow_rescue = false
|
39
|
+
|
40
|
+
# If you set this to true, each scenario will run in a database transaction.
|
41
|
+
# You can still turn off transactions on a per-scenario basis, simply tagging
|
42
|
+
# a feature or scenario with the @no-txn tag. If you are using Capybara,
|
43
|
+
# tagging with @culerity or @javascript will also turn transactions off.
|
44
|
+
#
|
45
|
+
# If you set this to false, transactions will be off for all scenarios,
|
46
|
+
# regardless of whether you use @no-txn or not.
|
47
|
+
#
|
48
|
+
# Beware that turning transactions off will leave data in your database
|
49
|
+
# after each scenario, which can lead to hard-to-debug failures in
|
50
|
+
# subsequent scenarios. If you do this, we recommend you create a Before
|
51
|
+
# block that will explicitly put your database in a known state.
|
52
|
+
|
53
|
+
# How to clean your database when transactions are turned off. See
|
54
|
+
# http://github.com/bmabey/database_cleaner for more info.
|
55
|
+
if defined?(ActiveRecord::Base)
|
56
|
+
begin
|
57
|
+
require 'database_cleaner'
|
58
|
+
DatabaseCleaner.strategy = :truncation
|
59
|
+
rescue LoadError => ignore_if_database_cleaner_not_present
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module NavigationHelpers
|
2
|
+
# Maps a name to a path. Used by the
|
3
|
+
#
|
4
|
+
# When /^I go to (.+)$/ do |page_name|
|
5
|
+
#
|
6
|
+
# step definition in web_steps.rb
|
7
|
+
#
|
8
|
+
def path_to(page_name)
|
9
|
+
case page_name
|
10
|
+
|
11
|
+
when /the home\s?page/
|
12
|
+
'/'
|
13
|
+
|
14
|
+
# Add more mappings here.
|
15
|
+
# Here is an example that pulls values out of the Regexp:
|
16
|
+
#
|
17
|
+
# when /^(.*)'s profile page$/i
|
18
|
+
# user_profile_path(User.find_by_login($1))
|
19
|
+
|
20
|
+
else
|
21
|
+
begin
|
22
|
+
page_name =~ /the (.*) page/
|
23
|
+
path_components = $1.split(/\s+/)
|
24
|
+
self.send(path_components.push('path').join('_').to_sym)
|
25
|
+
rescue Object => e
|
26
|
+
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
|
27
|
+
"Now, go and add a mapping in #{__FILE__}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
World(NavigationHelpers)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module HtmlSelectorsHelpers
|
2
|
+
# Maps a name to a selector. Used primarily by the
|
3
|
+
#
|
4
|
+
# When /^(.+) within (.+)$/ do |step, scope|
|
5
|
+
#
|
6
|
+
# step definitions in web_steps.rb
|
7
|
+
#
|
8
|
+
def selector_for(locator)
|
9
|
+
case locator
|
10
|
+
|
11
|
+
when /the page/
|
12
|
+
"html > body"
|
13
|
+
|
14
|
+
# Add more mappings here.
|
15
|
+
# Here is an example that pulls values out of the Regexp:
|
16
|
+
#
|
17
|
+
# when /the (notice|error|info) flash/
|
18
|
+
# ".flash.#{$1}"
|
19
|
+
|
20
|
+
# You can also return an array to use a different selector
|
21
|
+
# type, like:
|
22
|
+
#
|
23
|
+
# when /the header/
|
24
|
+
# [:xpath, "//header"]
|
25
|
+
|
26
|
+
# This allows you to provide a quoted selector as the scope
|
27
|
+
# for "within" steps as was previously the default for the
|
28
|
+
# web steps:
|
29
|
+
when /"(.+)"/
|
30
|
+
$1
|
31
|
+
|
32
|
+
else
|
33
|
+
raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
|
34
|
+
"Now, go and add a mapping in #{__FILE__}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
World(HtmlSelectorsHelpers)
|
data/lib/navi/helpers.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# This helper is a module that will get included into Rails via the
|
2
|
+
# lib/navi/railtie class
|
3
|
+
#
|
4
|
+
# It allows us to be in the context of the controller it is being included
|
5
|
+
# into: when this module is included to ActionView and the view/controller
|
6
|
+
# calls the render method, "self" will refer to the view or controller
|
7
|
+
# context
|
8
|
+
module Navi
|
9
|
+
module Helpers
|
10
|
+
def self.included(base)
|
11
|
+
#puts "Navi::Helpers was included into #{base}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def navi_render(collection)
|
15
|
+
renderer.render(collection)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def renderer
|
21
|
+
@renderer ||= Navi.renderer.new(self)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'navi/navigable/instance_methods'
|
2
|
+
|
3
|
+
module Navi
|
4
|
+
module Navigable
|
5
|
+
module Base
|
6
|
+
def navigable(options={})
|
7
|
+
cattr_accessor :navigable_config
|
8
|
+
self.navigable_config = options
|
9
|
+
has_one Navi.navigator, :as => :navigable
|
10
|
+
include Navi::Navigable::InstanceMethods
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ActiveRecord::Base.extend Navi::Navigable::Base
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Navi
|
2
|
+
module Navigable
|
3
|
+
module InstanceMethods
|
4
|
+
def to_navigator(options={})
|
5
|
+
return navigator_instance if navigator_instance
|
6
|
+
options.merge!(:navigable => self)
|
7
|
+
Navi.navigator_class.new options
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_navigator!(options={})
|
11
|
+
navigator = to_navigator(options)
|
12
|
+
navigator.save
|
13
|
+
navigator
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# Easily get the navigator instance based on the Navi.navigator setting
|
19
|
+
def navigator_instance
|
20
|
+
@navigator_instance ||= send(Navi.navigator)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
Binary file
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Navi
|
2
|
+
module Navigator
|
3
|
+
module ClassMethods
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
included do |child|
|
6
|
+
# So that Rails won't consider this to be an STI table.
|
7
|
+
# The actual project can have a model and inherit it this way:
|
8
|
+
# class MyNavItem < Navigable::NavigationItem::Base
|
9
|
+
#
|
10
|
+
# Then the navigable classes must tell the gem that the name of
|
11
|
+
# the nav item is :my_nav_item, this way: navigable :navigator => :my_nav_item
|
12
|
+
self.abstract_class = true
|
13
|
+
|
14
|
+
belongs_to :navigable, :polymorphic => true
|
15
|
+
|
16
|
+
# Calling ordered_tree on the child is important because
|
17
|
+
# of this: http://stackoverflow.com/q/6262033/61018
|
18
|
+
# where ordered_tree was picking up the Navi::Navigator::Base's
|
19
|
+
# information, rather than whatever inherits Base class
|
20
|
+
def self.inherited(child)
|
21
|
+
child.send 'ordered_tree'
|
22
|
+
super # super, so that Rails can continue to do what it's needs
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Navi
|
2
|
+
module Navigator
|
3
|
+
module InstanceMethods
|
4
|
+
def label
|
5
|
+
db_value = self.read_attribute :label
|
6
|
+
return db_value if db_value
|
7
|
+
return navigable.send navigable_config(:label) if navigable && navigable_config(:label)
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def link
|
12
|
+
db_value = self.read_attribute :link
|
13
|
+
return db_value if db_value
|
14
|
+
return navigable if navigable
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def title
|
19
|
+
db_value = self.read_attribute :title
|
20
|
+
return db_value if db_value
|
21
|
+
if navigable && navigable_config(:title)
|
22
|
+
config = navigable_config :title
|
23
|
+
return case config
|
24
|
+
when Symbol then navigable.send config
|
25
|
+
when String then config
|
26
|
+
when Proc then config.call navigable
|
27
|
+
end
|
28
|
+
end
|
29
|
+
return self.label
|
30
|
+
end
|
31
|
+
|
32
|
+
def highlights_on
|
33
|
+
db_value = self.read_attribute :highlights_on
|
34
|
+
value = if db_value
|
35
|
+
Regexp.new db_value
|
36
|
+
else # db_value.nil?
|
37
|
+
if navigable && navigable_config(:highlights_on)
|
38
|
+
config = navigable_config(:highlights_on)
|
39
|
+
case config
|
40
|
+
when Proc then config.call navigable
|
41
|
+
else config
|
42
|
+
end
|
43
|
+
else
|
44
|
+
self.link
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def navigable_config(key)
|
52
|
+
navigable.class.navigable_config[key]
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/navi/railtie.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# What is a railtie?
|
2
|
+
# tl;dr => Allows us to hook into Rails add add stuff to it
|
3
|
+
# http://www.rorexperts.com/what-is-railtie-t1898.html
|
4
|
+
|
5
|
+
module Navi
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
initializer "navi.helpers" do
|
8
|
+
ActionView::Base.send :include, Navi::Helpers
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Navi
|
2
|
+
module Renderers
|
3
|
+
class Base
|
4
|
+
attr_accessor :context, :controller, :template
|
5
|
+
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
|
+
@controller = controller_from @context
|
9
|
+
@template = template_from @controller
|
10
|
+
end
|
11
|
+
|
12
|
+
def render(collection)
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# Pretty much lifted from
|
19
|
+
# https://github.com/andi/simple-navigation/blob/master/lib/simple_navigation/adapters/rails.rb
|
20
|
+
def controller_from(context)
|
21
|
+
context.respond_to?(:controller) ? context.controller : context
|
22
|
+
end
|
23
|
+
|
24
|
+
# Pretty much lifted from
|
25
|
+
# https://github.com/andi/simple-navigation/blob/master/lib/simple_navigation/adapters/rails.rb
|
26
|
+
def template_from(controller)
|
27
|
+
controller.respond_to?(:view_context) ? controller.view_context : controller.instance_variable_get(:@template)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Navi
|
2
|
+
module Renderers
|
3
|
+
class SimpleNavigation < Navi::Renderers::Base
|
4
|
+
|
5
|
+
def render(collection)
|
6
|
+
items = create_dynamic_items(collection)
|
7
|
+
@template.render_navigation :items => items, :expand_all => true
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Create an array of hashes that can be easily fed into SimpleNavigation
|
13
|
+
# like in the following like:
|
14
|
+
# https://github.com/andi/simple-navigation/wiki/Dynamic-Navigation-Items
|
15
|
+
def create_dynamic_items(collection)
|
16
|
+
nav = []
|
17
|
+
collection.each do |nav_item|
|
18
|
+
nav << {
|
19
|
+
:key => @template.dom_id(nav_item).to_sym,
|
20
|
+
:name => nav_item.label,
|
21
|
+
:url => @template.polymorphic_path(nav_item.link),
|
22
|
+
:options => {:title => nav_item.title, :class => nav_item.class.name.underscore},
|
23
|
+
:items => create_dynamic_items(nav_item.children)
|
24
|
+
}
|
25
|
+
end
|
26
|
+
nav
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/navi.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require "active_support/core_ext/module" # so we can use mattr_accessor
|
3
|
+
require 'active_record'
|
4
|
+
require 'ordered_tree'
|
5
|
+
require 'navi/navigable/base'
|
6
|
+
require 'navi/railtie' if defined?(Rails) # so we can include the rendering helper into Rails
|
7
|
+
|
8
|
+
module Navi
|
9
|
+
autoload :Helpers, 'navi/helpers'
|
10
|
+
|
11
|
+
module Navigator
|
12
|
+
autoload :Base, 'navi/navigator/base'
|
13
|
+
end
|
14
|
+
|
15
|
+
module Renderers
|
16
|
+
autoload :Base, 'navi/renderers/base'
|
17
|
+
autoload :SimpleNavigation, 'navi/renderers/simple_navigation'
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.navigator_class
|
21
|
+
self.navigator.to_s.classify.constantize
|
22
|
+
end
|
23
|
+
|
24
|
+
mattr_accessor :navigator
|
25
|
+
@@navigator ||= :nav_item
|
26
|
+
|
27
|
+
mattr_accessor :renderer
|
28
|
+
@@renderer ||= Navi::Renderers::SimpleNavigation
|
29
|
+
end
|