wonder_navigation 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d76249b8eec88051a188e99388c1975634a29be2
4
+ data.tar.gz: 352d500b597833be7f75484bbb1f62c4e5372e49
5
+ SHA512:
6
+ metadata.gz: c1a0790d51e750d70556929d60f5c8ef7eda8bfc14799f32406984565c77deed0a7c847cc7f8bc7b7e6eabc488450c49200151838c07048a9a9efe273c23e3f2
7
+ data.tar.gz: 4fc8b58b919bf87c65d84d5536752f0c14bbc8286423cc2baf5a34656ad8f943bd68ded2b11a005280755e8c21ae85cb7d7ad6bbb6817ee1faa5cd229ea32d18
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.4
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wonder_navigation.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # Rails Wonderful Navigation
2
+
3
+ [![Code Climate](https://codeclimate.com/github/douglaslise/wonder_navigation/badges/gpa.svg)](https://codeclimate.com/github/douglaslise/wonder_navigation)
4
+
5
+ Describe your Rails' menus and breadcrumbs in a single place, with support for permissions, fixed and resource based labels.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'wonder_navigation'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install wonder_navigation
22
+
23
+ ## Usage
24
+
25
+ In Rails, create a folder `config/navigation/default` and a file called `config/navigation/default.yml`. Inside the yml file you put the list of files that contains menu definitions:
26
+ ```yml
27
+ ---
28
+ default:
29
+ - public
30
+ - admin
31
+ ```
32
+ After, create the corresponding files (`config/navigation/default/public.rb`, `config/navigation/default/admin.rb`):
33
+
34
+ ```ruby
35
+ WonderNavigation::Menu.register(:default) do
36
+ label { "Begin" }
37
+ path { root_path }
38
+ menu :blog, "Blog" do #Non-linked menu level
39
+ resource :posts, label: "Posts", path: posts_path do |index, new, show|
40
+ show.label {|post| post.title.truncate(15) }
41
+ # Here you can overwrite new and index entries
42
+
43
+ menu :comments, "Comments", path: post_comments_path do
44
+ menu :comment_show do
45
+ label {|comment| "Comment from #{comment.author}" }
46
+ path {|comment| post_comment_path(comment) }
47
+ menu :comment_edit, "Editing" do
48
+ path {|comment| edit_post_comment_path(comment)}
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ ```
55
+
56
+
57
+ ## Development
58
+
59
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
60
+
61
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
62
+
63
+ ## Contributing
64
+
65
+ Bug reports and pull requests are welcome on GitHub at https://github.com/douglaslise/wonder_navigation.
66
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "wonder_navigation"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,26 @@
1
+ module WonderNavigation
2
+ module Controller
3
+
4
+ def self.included(controller)
5
+ controller.before_action :set_default_wonder_navigation_page
6
+ end
7
+
8
+ def set_default_wonder_navigation_page
9
+ page_action = case action_name.to_sym
10
+ when :create then :new
11
+ when :update then :edit
12
+ else action_name
13
+ end
14
+ set_navigation_page "#{controller_path.tr('/','_')}_#{page_action}"
15
+ end
16
+
17
+ def set_wonder_navigation_object(navigation_object)
18
+ @navigation_object = navigation_object
19
+ end
20
+
21
+ def set_navigation_page(navigation_page)
22
+ @navigation_page = navigation_page.to_sym
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ module WonderNavigation
2
+ class Crumb
3
+ attr_accessor :label, :path, :id
4
+
5
+ def initialize(id, label = nil)
6
+ @id = id
7
+ @label = label
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,43 @@
1
+ module WonderNavigation
2
+ class DeferrableOption
3
+ attr_accessor :fixed_value, :block, :name, :fixed_value_assigned
4
+
5
+ def initialize(options = {})
6
+ @fixed_value_assigned = options.has_key?(:fixed) && !options[:fixed].nil?
7
+ @fixed_value = options[:fixed]
8
+ @block = options[:block]
9
+ @name = options[:name]
10
+ end
11
+
12
+ def present?
13
+ fixed_value_assigned || !!block
14
+ end
15
+
16
+ def resolvable?(object)
17
+ fixed_value_assigned || !!block && (!!object || block.arity.zero?)
18
+ end
19
+
20
+ def try_resolve(object)
21
+ resolve(object) if resolvable?(object)
22
+ end
23
+
24
+ def resolve(object)
25
+ check_resolvable(object)
26
+ fixed_value_assigned ? fixed_value : block.call(object)
27
+ end
28
+
29
+ private
30
+
31
+ def check_resolvable(object)
32
+ unless resolvable?(object)
33
+ if present?
34
+ raise EObjectNotSupplied.new "A block was defined to require an object but none (or nil) was supplied on deferrable option #{name}"
35
+ else
36
+ raise EDeferrableOptionEmpty.new "Neither a fixed value or a block was passed to deferrable option #{name}"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ class EObjectNotSupplied < StandardError; end
42
+ class EDeferrableOptionEmpty < StandardError; end
43
+ end
@@ -0,0 +1,62 @@
1
+ module WonderNavigation
2
+ module Helper
3
+
4
+ def navigation_breadcrumb
5
+ crumbs = crumbs_for_current_page
6
+ crumbs.any? ? breadcrumb(crumbs) : "Breadcrumb undefined for '#{@navigation_page}'"
7
+ end
8
+
9
+ def navigation_title_breadcrumb(prefix)
10
+ crumbs = crumbs_for_current_page.collect(&:label)
11
+ crumbs[0] = prefix
12
+ crumbs.join(" - ")
13
+ end
14
+
15
+ def menu_tree(menu_id, current_user)
16
+ WonderNavigation::MenuManager.get(menu_id).menu_tree(current_page: @navigation_page, current_user: current_user)
17
+ end
18
+
19
+ private
20
+
21
+ def crumbs_for_current_page(menu_id = :default)
22
+ page = @navigation_page
23
+
24
+ object = @navigation_object
25
+ unless object
26
+ # If object was not given by set_wonder_navigation_object then try get an instance variable called with the same name that the controller in singular
27
+ mod, resource = controller_path.split("/")
28
+ mod, resource = nil, mod if resource.nil?
29
+ variable_name = [mod, resource.singularize].compact.join("_")
30
+ variable_name = "@#{variable_name}"
31
+ object = controller.instance_variable_get(variable_name.to_sym)
32
+ end
33
+ # object ||= @navigation_parent_object
34
+ crumbs_for(menu_id, page.to_sym, object)
35
+ end
36
+
37
+ def crumbs_for(menu_id, id, object)
38
+ menu = WonderNavigation::MenuManager.get(menu_id)
39
+ if menu.item_exists?(id)
40
+ menu.breadcrumb_for(id, object)
41
+ else
42
+ []
43
+ end
44
+ end
45
+
46
+ def breadcrumb(crumbs)
47
+ content_tag(:ol, class: "breadcrumb") do
48
+ raw(crumbs.collect do |menu_item|
49
+ content_tag(:li) do
50
+ if menu_item.path
51
+ link_to menu_item.label, menu_item.path
52
+ else
53
+ menu_item.label
54
+ end
55
+ end
56
+ end.join(" "))
57
+ end
58
+ end
59
+
60
+
61
+ end
62
+ end
@@ -0,0 +1,70 @@
1
+ module WonderNavigation
2
+ class ENotDefinedMenu < StandardError; end
3
+ class Menu
4
+ attr_reader :items
5
+ attr_accessor :permission_checker
6
+
7
+ def initialize
8
+ @items = {}
9
+ end
10
+
11
+ def self.register_permission_check(menu_id, menu_manager = MenuManager, &block)
12
+ get_instance(menu_id, menu_manager).tap do |instance|
13
+ instance.permission_checker = block
14
+ end
15
+ end
16
+
17
+ def self.register(menu_id, menu_manager = MenuManager, &block)
18
+ get_instance(menu_id, menu_manager).tap do |instance|
19
+ instance.items[:root].instance_eval(&block)
20
+ end
21
+ end
22
+
23
+ def self.get_instance(menu_id, menu_manager)
24
+ instance = menu_manager.fetch(menu_id)
25
+ unless instance
26
+ instance = Menu.new
27
+ instance.items[:root] = MenuItem.new(instance, 0, :root, validate: false)
28
+ menu_manager.set(menu_id, instance)
29
+ end
30
+
31
+ instance
32
+ end
33
+
34
+ def item_exists?(id)
35
+ items[id].present?
36
+ end
37
+
38
+ def breadcrumb_for(id, object = nil)
39
+ if items[id]
40
+ items[id].breadcrumbs(object)
41
+ else
42
+ raise ENotDefinedMenu.new "Menu '#{id}' not defined"
43
+ end
44
+ end
45
+
46
+ def menu_tree(options = {})
47
+ current_user = options[:current_user]
48
+ current_page = options[:current_page]
49
+ max_depth = options[:max_depth] || 10
50
+ items[:root].tree(current_page, max_depth, current_user)
51
+ end
52
+
53
+ def menu_tree_flat(options = {})
54
+ extract_children menu_tree(options)
55
+ end
56
+
57
+ private
58
+
59
+ def extract_children(menu_entry)
60
+ result = []
61
+ result << menu_entry
62
+ result << menu_entry.visible_children.collect do |child|
63
+ extract_children(child)
64
+ end
65
+ menu_entry.children = []
66
+
67
+ result.flatten
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,38 @@
1
+ module WonderNavigation
2
+ class MenuEntry
3
+ attr_accessor :id, :label, :path, :level, :active, :visible, :children
4
+ def initialize(id, level)
5
+ @id = id
6
+ @level = level
7
+ @children = []
8
+ end
9
+
10
+ def active?
11
+ active || children.any?(&:active?)
12
+ end
13
+
14
+ def has_visible_children?
15
+ children.any?(&:visible)
16
+ end
17
+
18
+ def has_active_children?
19
+ children.any?(&:active)
20
+ end
21
+
22
+ def promote_active_state
23
+ self.active ||= has_active_children?
24
+ end
25
+
26
+ def visible_children
27
+ children.select(&:visible)
28
+ end
29
+
30
+ def self.level_class(level)
31
+ classes = {
32
+ 2 => "second",
33
+ 3 => "third"
34
+ }
35
+ classes[level]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,157 @@
1
+ module WonderNavigation
2
+ class ELabelNotDefined < StandardError; end
3
+ class MenuItem
4
+ attr_accessor :menu_instance, :level, :id, :parent_item, :subitems, :deferrables, :permission
5
+
6
+ def initialize(menu_instance, level, id, options = {}, &block)
7
+ @level = level
8
+ @menu_instance = menu_instance
9
+ @id = id
10
+ @subitems = []
11
+ @permission = options[:permission]
12
+ @menu_instance.items[id] = self
13
+ initialize_deferrables(options)
14
+
15
+ self.instance_eval(&block) if block_given?
16
+
17
+ validate if options.fetch(:validate, true)
18
+ end
19
+
20
+ def validate
21
+ unless label_deferrable.present?
22
+ raise ELabelNotDefined.new("MenuItem #{id} was called without define a label text or proc")
23
+ end
24
+ end
25
+
26
+ def menu(id, label = nil, options = {}, &block)
27
+ if label.is_a?(Hash)
28
+ options = label
29
+ else
30
+ options[:label] = label
31
+ end
32
+ sub_item = MenuItem.new(menu_instance, level + 1, id.to_sym, options, &block)
33
+ sub_item.parent_item = self
34
+ sub_item
35
+ end
36
+
37
+ def resource(id, options = {}, &block)
38
+ new = show = nil
39
+ index = menu "#{id}_index", options do
40
+ new = menu "#{id}_new", "Novo", visible: false
41
+ show = menu "#{id}_show" do
42
+ label {|obj| obj.to_s }
43
+ path {|obj| obj }
44
+ menu "#{id}_edit", "Edição"
45
+ end
46
+ end
47
+ index.instance_exec(index, new, show, &block) if block_given?
48
+ end
49
+
50
+ def breadcrumbs(object = nil)
51
+ result = []
52
+ if parent_item
53
+ parent_object = object
54
+ if parent_deferrable.present?
55
+ parent_object = parent_deferrable.resolve(object)
56
+ end
57
+ result += parent_item.breadcrumbs(parent_object)
58
+ end
59
+ current = Crumb.new(id)
60
+ current.label = label_deferrable.resolve(object)
61
+ current.path = path_deferrable.resolve(object) if path_deferrable.resolvable?(object)
62
+
63
+ result << current
64
+ end
65
+
66
+ def entry_visible?(max_depth, current_user)
67
+ # require "byebug"; debugger
68
+
69
+ level < max_depth &&
70
+ visible_deferrable.resolve(current_user) &&
71
+ label_deferrable.resolvable?(nil) &&
72
+ has_permission?(current_user)
73
+ end
74
+
75
+ def tree(current_page, max_depth, current_user)
76
+ MenuEntry.new(id, level).tap do |entry|
77
+ entry.active = id == current_page
78
+ entry.visible = entry_visible?(max_depth, current_user)
79
+ if entry.visible
80
+ entry.label = label_deferrable.resolve(nil)
81
+ entry.path = path_deferrable.try_resolve(nil)
82
+ end
83
+
84
+ entry.children = subtree(current_page, max_depth, current_user)
85
+ entry.promote_active_state
86
+ end
87
+ end
88
+
89
+ def has_permission?(current_user)
90
+ if !!permission && !!menu_instance.permission_checker
91
+ # debugger
92
+ instance_exec(permission, current_user, &menu_instance.permission_checker)
93
+ else
94
+ true
95
+ end
96
+ end
97
+
98
+ def parent_item=(parent_item)
99
+ if parent_item
100
+ @parent_item = parent_item
101
+ parent_item.subitems << self
102
+ elsif @parent_item
103
+ @parent_item.subitems.delete(self)
104
+ @parent_item = nil
105
+ end
106
+ end
107
+
108
+ def label(&block)
109
+ deferrables[:label] = DeferrableOption.new(block: block, name: "Label for #{id}")
110
+ end
111
+
112
+ def path(&block)
113
+ deferrables[:path] = DeferrableOption.new(block: block, name: "Path for #{id}")
114
+ end
115
+
116
+ def visible(&block)
117
+ deferrables[:visible] = DeferrableOption.new(block: block, name: "Visible for #{id}")
118
+ end
119
+
120
+ def parent(&block)
121
+ deferrables[:parent] = DeferrableOption.new(block: block, name: "Parent for #{id}")
122
+ end
123
+
124
+ private
125
+
126
+ def initialize_deferrables(options)
127
+ @deferrables = {}
128
+ visible = options.fetch(:visible, true)
129
+ deferrables[:visible] = DeferrableOption.new(fixed: visible, name: "Visible for #{id}")
130
+ deferrables[:label] = DeferrableOption.new(fixed: options[:label], name: "Label for #{id}")
131
+ deferrables[:path] = DeferrableOption.new(fixed: options[:path], name: "Path for #{id}")
132
+ deferrables[:parent] = DeferrableOption.new(name: "Parent for #{id}")
133
+ end
134
+
135
+ def label_deferrable
136
+ deferrables[:label]
137
+ end
138
+
139
+ def path_deferrable
140
+ deferrables[:path]
141
+ end
142
+
143
+ def visible_deferrable
144
+ deferrables[:visible]
145
+ end
146
+
147
+ def parent_deferrable
148
+ deferrables[:parent]
149
+ end
150
+
151
+ def subtree(current_page, max_depth, current_user)
152
+ subitems.collect do |sub_item|
153
+ sub_item.tree(current_page, max_depth, current_user)
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,70 @@
1
+ module WonderNavigation
2
+ class MenuManager
3
+ class << self
4
+
5
+ def fetch(menu_id)
6
+ menus[menu_id]
7
+ end
8
+
9
+ def get(menu_id)
10
+ load_menus
11
+ fetch(menu_id)
12
+ end
13
+
14
+ def set(menu_id, menu_instance)
15
+ menus[menu_id] = menu_instance
16
+ end
17
+
18
+ private
19
+
20
+ def menus
21
+ @menus ||= Hash.new
22
+ end
23
+
24
+ def reset
25
+ @menus = nil
26
+ end
27
+
28
+ def load_menus
29
+ if need_reload?
30
+ reset
31
+ load_register_files
32
+ @loaded_file_mtimes = get_file_mtimes
33
+ end
34
+ end
35
+
36
+ def load_register_files
37
+ register_files.each do |file|
38
+ Rails.logger.info("Reloading menu on file #{file}")
39
+ instance_eval open(file).read, file
40
+ end
41
+ end
42
+
43
+ def yml_files
44
+ Dir[Rails.root.join("config", "navigation", "*.yml")]
45
+ end
46
+
47
+ def register_files
48
+ yml_files.flat_map do |file|
49
+ YAML.load(File.new(file)).flat_map do |folder, files|
50
+ files.collect do |menu_file|
51
+ File.join(Rails.root.join("config", "navigation", folder, "#{menu_file}.rb"))
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ def need_reload?
58
+ !@loaded_file_mtimes || files_modified?
59
+ end
60
+
61
+ def files_modified?
62
+ Rails.env.development? && get_file_mtimes != @loaded_file_mtimes
63
+ end
64
+
65
+ def get_file_mtimes
66
+ (yml_files + register_files).flatten.collect { |file| File.mtime(file) }
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ module WonderNavigation
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,17 @@
1
+ require "ostruct"
2
+ require "wonder_navigation/version"
3
+ require "wonder_navigation/menu"
4
+ require "wonder_navigation/menu_manager"
5
+ require "wonder_navigation/menu_item"
6
+ require "wonder_navigation/menu_entry"
7
+ require "wonder_navigation/deferrable_option"
8
+ require "wonder_navigation/crumb"
9
+ require "wonder_navigation/controller"
10
+
11
+ if defined?(ActionView)
12
+ require "wonder_navigation/helper"
13
+ ActionView::Base.send :include, WonderNavigation::Helper
14
+ end
15
+
16
+ module WonderNavigation
17
+ end
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'wonder_navigation/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "wonder_navigation"
8
+ spec.version = WonderNavigation::VERSION
9
+ spec.authors = ["Douglas Lise", "Rodrigo Rosa"]
10
+ spec.email = ["douglaslise@gmail.com"]
11
+
12
+ spec.summary = "Rails Wonderful Navigation"
13
+ spec.description = "Describe your Rails' menus and breadcrumbs in a single place, with support for permissions, fixed and resource based labels."
14
+ spec.homepage = "http://github.com/douglaslise/wonder_navigation"
15
+ spec.licenses = ['MIT']
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ # if spec.respond_to?(:metadata)
20
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
+ # else
22
+ # raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ # end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "rails", "~> 4.2"
31
+ spec.add_development_dependency "bundler", "~> 1.11"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "rspec", "~> 3.0"
34
+ spec.add_development_dependency "simplecov", "~> 0.10"
35
+ spec.add_development_dependency "byebug", "~> 6.0"
36
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wonder_navigation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Douglas Lise
8
+ - Rodrigo Rosa
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2016-03-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '4.2'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '4.2'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.11'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.11'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '10.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '10.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: simplecov
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '0.10'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0.10'
84
+ - !ruby/object:Gem::Dependency
85
+ name: byebug
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '6.0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '6.0'
98
+ description: Describe your Rails' menus and breadcrumbs in a single place, with support
99
+ for permissions, fixed and resource based labels.
100
+ email:
101
+ - douglaslise@gmail.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - ".gitignore"
107
+ - ".rspec"
108
+ - ".travis.yml"
109
+ - Gemfile
110
+ - README.md
111
+ - Rakefile
112
+ - bin/console
113
+ - bin/setup
114
+ - lib/wonder_navigation.rb
115
+ - lib/wonder_navigation/controller.rb
116
+ - lib/wonder_navigation/crumb.rb
117
+ - lib/wonder_navigation/deferrable_option.rb
118
+ - lib/wonder_navigation/helper.rb
119
+ - lib/wonder_navigation/menu.rb
120
+ - lib/wonder_navigation/menu_entry.rb
121
+ - lib/wonder_navigation/menu_item.rb
122
+ - lib/wonder_navigation/menu_manager.rb
123
+ - lib/wonder_navigation/version.rb
124
+ - wonder_navigation.gemspec
125
+ homepage: http://github.com/douglaslise/wonder_navigation
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.4.8
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Rails Wonderful Navigation
149
+ test_files: []
150
+ has_rdoc: