semantic_navigation 0.0.6 → 0.0.8
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.
- data/Changelog.md +10 -1
- data/README.md +33 -4
- data/Rakefile +3 -0
- data/lib/generators/semantic_navigation/install/install_generator.rb +20 -0
- data/lib/generators/semantic_navigation/install/templates/semantic_navigation.en.yml +2 -0
- data/lib/generators/semantic_navigation/install/templates/semantic_navigation.rb +25 -0
- data/lib/semantic_navigation.rb +2 -0
- data/lib/semantic_navigation/configuration.rb +52 -44
- data/lib/semantic_navigation/core.rb +4 -0
- data/lib/semantic_navigation/core/base.rb +21 -0
- data/lib/semantic_navigation/core/leaf.rb +25 -0
- data/lib/semantic_navigation/core/navigation.rb +35 -0
- data/lib/semantic_navigation/core/node.rb +29 -0
- data/lib/semantic_navigation/helper_methods.rb +14 -17
- data/lib/semantic_navigation/railtie.rb +14 -6
- data/lib/semantic_navigation/renderers.rb +8 -0
- data/lib/semantic_navigation/renderers/acts_as_breadcrumb.rb +39 -0
- data/lib/semantic_navigation/renderers/acts_as_list.rb +46 -0
- data/lib/semantic_navigation/renderers/bread_crumb.rb +50 -0
- data/lib/semantic_navigation/renderers/list.rb +44 -0
- data/lib/semantic_navigation/renderers/render_helpers.rb +113 -0
- data/lib/semantic_navigation/twitter_bootstrap/breadcrumb.rb +58 -0
- data/lib/semantic_navigation/twitter_bootstrap/list.rb +76 -0
- data/lib/semantic_navigation/twitter_bootstrap/tabs.rb +70 -0
- data/lib/semantic_navigation/version.rb +1 -1
- data/semantic_navigation.gemspec +3 -3
- data/spec/lib/semantic_navigation/configuration_spec.rb +55 -0
- data/spec/lib/semantic_navigation/custom_renderer.rb +3 -0
- data/spec/lib/semantic_navigation/helper_methods_spec.rb +1 -0
- data/spec/lib/semantic_navigation_spec.rb +1 -0
- data/spec/spec_helper.rb +8 -0
- metadata +32 -14
- data/lib/semantic_navigation/core/procs.rb +0 -15
- data/lib/semantic_navigation/core/render.rb +0 -94
- data/lib/semantic_navigation/item.rb +0 -118
- data/lib/tasks/semantic_navigation.rake +0 -8
- data/lib/tasks/templates/semantic_navigation.rb +0 -53
data/Changelog.md
CHANGED
@@ -1,4 +1,13 @@
|
|
1
|
-
### 0.0.
|
1
|
+
### 0.0.8 /
|
2
|
+
|
3
|
+
* New configuration logic
|
4
|
+
* New helper render method
|
5
|
+
* Reloadable in development, and caching in production
|
6
|
+
* I18n support
|
7
|
+
* Render config, can be set through helper render method
|
8
|
+
* Included support for custom renderers
|
9
|
+
|
10
|
+
### 0.0.6 / February 10th, 2012
|
2
11
|
|
3
12
|
* Now uses fileutils raver ftools for ruby-1.9.x
|
4
13
|
* Some fixes for ruby-1.9.x
|
data/README.md
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
This is semantic_navigation
|
2
2
|
|
3
|
-
Current version: 0.
|
3
|
+
Current version: 0.0.8
|
4
4
|
|
5
5
|
###Purpose
|
6
|
-
|
6
|
+
This gem generates the navigation for your Rails app.
|
7
|
+
Really customizable and simple to use.
|
8
|
+
Using this gem you have 4 types of renderers: menu, breadcrumb, tabs, and, pills
|
9
|
+
|
10
|
+
You can define different menus and render them separatelly.
|
11
|
+
|
12
|
+
Now with simple integration with a twitter-bootstrap css framework.
|
7
13
|
|
8
14
|
###How to install
|
9
15
|
|
@@ -19,7 +25,30 @@ $ bundle install
|
|
19
25
|
|
20
26
|
Generate the config file:
|
21
27
|
<pre><code>
|
22
|
-
$
|
28
|
+
$ rails generate semantic_navigation:install
|
23
29
|
</code></pre>
|
24
30
|
|
25
|
-
|
31
|
+
###Quick start
|
32
|
+
|
33
|
+
Configure your navigation in config/semantic_navigation.rb
|
34
|
+
|
35
|
+
<pre><code>
|
36
|
+
SemanticNavigation::Configuration.run do
|
37
|
+
navigate :root_menu do
|
38
|
+
item :header_item, nil, :name => 'Header'
|
39
|
+
item :first_item, '#', :name => 'First Item', :ico => :tag
|
40
|
+
item :divide
|
41
|
+
item :second_item, '#', :name => 'Second Item', :ico => :user
|
42
|
+
end
|
43
|
+
end
|
44
|
+
</code></pre>
|
45
|
+
|
46
|
+
And try to render it in your layout(code in haml):
|
47
|
+
<pre><code>
|
48
|
+
.well
|
49
|
+
= navigation_for :root_menu, :as => :bootstrap_list
|
50
|
+
</code></pre>
|
51
|
+
|
52
|
+
Render the navigation using the semantic_navigation helper methods and options for them.
|
53
|
+
|
54
|
+
For the information of how to configure and render your navigation read the <a href='https://github.com/fr33z3/semantic_navigation/wiki'>Wiki</a>
|
data/Rakefile
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
module SemanticNavigation
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < ::Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../templates", __FILE__)
|
5
|
+
desc "This generator creates config file for your navigation"
|
6
|
+
|
7
|
+
def add_semantic_navigation
|
8
|
+
puts <<-EOM
|
9
|
+
+===============================================================+
|
10
|
+
| SemanticNavigation install |
|
11
|
+
| Please read the Wiki to learn how to define your navigation. |
|
12
|
+
| http://github.com/fr33z3/semantic_navigation/wiki. |
|
13
|
+
+===============================================================+
|
14
|
+
EOM
|
15
|
+
copy_file "semantic_navigation.rb", "config/semantic_navigation.rb"
|
16
|
+
copy_file "semantic_navigation.en.yml", "config/locales/semantic_navigation.en.yml"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
SemanticNavigation::Configuration.run do
|
2
|
+
# Read wiki https://github.com/fr33z3/semantic_navigation/wiki to lear about
|
3
|
+
# semantic_navigation configuration
|
4
|
+
|
5
|
+
#styles_for :list do
|
6
|
+
# show_navigation_active_class true
|
7
|
+
# navigation_active_class [:some_active_class]
|
8
|
+
#end
|
9
|
+
|
10
|
+
#register_renderer :some_renderer, SomeRendererClass
|
11
|
+
|
12
|
+
#navigate :navigation do
|
13
|
+
# item :header_item, :name => 'Header Item'
|
14
|
+
# item :first_item, :first_item_route, :ico => 'user' do
|
15
|
+
# item :sub_item, :sub_item_route do
|
16
|
+
# item :sub_sub_item, :sub_sub_item_route
|
17
|
+
# end
|
18
|
+
# item :second_sub, :second_sub_route, :ico => 'user'
|
19
|
+
# end
|
20
|
+
# item :divide
|
21
|
+
# item :second_item, :second_item_route
|
22
|
+
#end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
data/lib/semantic_navigation.rb
CHANGED
@@ -1,55 +1,63 @@
|
|
1
|
-
require 'semantic_navigation/item'
|
2
|
-
|
3
1
|
module SemanticNavigation
|
4
2
|
class Configuration
|
5
3
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
@@navigations = {}
|
5
|
+
@@renderers = {:list => Renderers::List,
|
6
|
+
:breadcrumb => Renderers::BreadCrumb,
|
7
|
+
:bootstrap_breadcrumb => TwitterBootstrap::Breadcrumb,
|
8
|
+
:bootstrap_list => TwitterBootstrap::List,
|
9
|
+
:bootstrap_tabs => TwitterBootstrap::Tabs,
|
10
|
+
:bootstrap_pills => TwitterBootstrap::Tabs
|
11
|
+
}
|
12
|
+
@@render_styles = {:bootstrap_pills => proc {
|
13
|
+
navigation_default_classes [:nav, 'nav-pills']
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.run(&block)
|
18
|
+
self.class_eval &block if block_given?
|
10
19
|
end
|
11
|
-
|
12
|
-
def
|
13
|
-
|
20
|
+
|
21
|
+
def self.navigate(id, options = {}, &block)
|
22
|
+
options[:id] = id.to_sym
|
23
|
+
options[:i18n_name] = "semantic_navigation.#{id}"
|
24
|
+
navigation = Core::Navigation.new(options)
|
25
|
+
navigation.instance_eval &block if block_given?
|
26
|
+
@@navigations[id.to_sym] = navigation
|
14
27
|
end
|
15
|
-
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
else
|
21
|
-
menu = Item.new(name, args, nil)
|
22
|
-
menu.level = 0
|
23
|
-
@menus.merge!({name.to_sym => menu})
|
24
|
-
yield menu if block_given?
|
28
|
+
|
29
|
+
def render(menu_id, renderer_name, options, view_object)
|
30
|
+
renderer = @@renderers[renderer_name].new(view_object)
|
31
|
+
unless @@render_styles[renderer_name].nil?
|
32
|
+
renderer.instance_eval &@@render_styles[renderer_name]
|
25
33
|
end
|
34
|
+
options.keys.each{|key| renderer.send "#{key}=", options[key]}
|
35
|
+
navigation = @@navigations[menu_id]
|
36
|
+
navigation.mark_active(view_object)
|
37
|
+
navigation.render(renderer)
|
26
38
|
end
|
27
|
-
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
return @menus[name.to_sym].render_levels command[:levels]
|
44
|
-
elsif command.is_a?(Hash) && command.keys == [:from_level]
|
45
|
-
return @menus[name.to_sym].render_from command[:from_level]
|
46
|
-
else
|
47
|
-
raise NoMethodError.new("Wrong menu render parameter:`#{command.to_s}`")
|
48
|
-
end
|
49
|
-
else
|
50
|
-
raise NoMethodError.new("No such menu name:`#{name}` check your #{Rails.root}/config/semantic_navigation.rb file")
|
39
|
+
|
40
|
+
def self.styles_for(name)
|
41
|
+
@@render_styles[name.to_sym] = proc
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.to_s
|
45
|
+
"<#{self.name}:#{@@navigations};#{@@renderers}>"
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.register_renderer(*options)
|
49
|
+
if options.count == 1
|
50
|
+
name = options[0].name.demodulize.underscore.to_sym
|
51
|
+
@@renderers[name] = options[0]
|
52
|
+
elsif options.count == 2
|
53
|
+
name = options[0].to_sym
|
54
|
+
@@renderers[name] = options[1]
|
51
55
|
end
|
52
56
|
end
|
53
|
-
|
57
|
+
|
58
|
+
def navigation(name)
|
59
|
+
@@navigations[name]
|
60
|
+
end
|
61
|
+
|
54
62
|
end
|
55
63
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SemanticNavigation
|
2
|
+
module Core
|
3
|
+
class Base
|
4
|
+
|
5
|
+
attr :id, :level, :classes, :active
|
6
|
+
|
7
|
+
def initialize(options, level)
|
8
|
+
@level = level
|
9
|
+
options.keys.each do |option_name|
|
10
|
+
instance_variable_set :"@#{option_name}", options[option_name]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def render(renderer)
|
15
|
+
class_name = self.class.name.split('::').last.downcase
|
16
|
+
renderer.send :"render_#{class_name}", self
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module SemanticNavigation
|
2
|
+
module Core
|
3
|
+
class Leaf < Base
|
4
|
+
attr :url, :link_classes
|
5
|
+
|
6
|
+
def initialize(options, level)
|
7
|
+
super options, level
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
rendering_name = @name || I18n.t("#{@i18n_name}.#{@id}", :default => '')
|
12
|
+
rendering_name.is_a?(Proc) ? rendering_name.call.to_s : rendering_name
|
13
|
+
end
|
14
|
+
|
15
|
+
def mark_active(view_object)
|
16
|
+
if @url
|
17
|
+
@active = view_object.current_page?(@url)
|
18
|
+
else
|
19
|
+
@active = false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SemanticNavigation
|
2
|
+
module Core
|
3
|
+
class Navigation < Base
|
4
|
+
attr :sub_elements
|
5
|
+
|
6
|
+
def initialize(options, level = 0)
|
7
|
+
@sub_elements = []
|
8
|
+
super options, level
|
9
|
+
end
|
10
|
+
|
11
|
+
def item(id, url=nil, options={}, &block)
|
12
|
+
options[:id] = id.to_sym
|
13
|
+
options[:url] = url unless url.nil?
|
14
|
+
options[:i18n_name] = @i18n_name
|
15
|
+
|
16
|
+
if block_given?
|
17
|
+
element = Node.new(options, @level+1)
|
18
|
+
element.instance_eval &block
|
19
|
+
else
|
20
|
+
element = Leaf.new(options, @level+1)
|
21
|
+
end
|
22
|
+
|
23
|
+
@sub_elements.push element
|
24
|
+
end
|
25
|
+
|
26
|
+
def mark_active(view_object)
|
27
|
+
@sub_elements.each do |element|
|
28
|
+
element.mark_active(view_object)
|
29
|
+
end
|
30
|
+
@active = !@sub_elements.find{|element| element.active}.nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module SemanticNavigation
|
2
|
+
module Core
|
3
|
+
class Node < Navigation
|
4
|
+
attr :url, :link_classes, :node_classes
|
5
|
+
|
6
|
+
def initialize(options, level)
|
7
|
+
super options, level
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
rendering_name = @name || i18n_name
|
12
|
+
rendering_name.is_a?(Proc) ? rendering_name.call.to_s : rendering_name
|
13
|
+
end
|
14
|
+
|
15
|
+
def mark_active(view_object)
|
16
|
+
@sub_elements.each{|element| element.mark_active(view_object)}
|
17
|
+
@active = view_object.current_page?(@url)
|
18
|
+
@active |= !@sub_elements.find{|element| element.active}.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def i18n_name
|
24
|
+
I18n.t("#{@i18n_name}.#{@id}", :default => '')
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,23 +1,20 @@
|
|
1
1
|
module SemanticNavigation::HelperMethods
|
2
|
-
|
3
|
-
def method_missing(name, command = :render)
|
4
|
-
name = name.to_s
|
5
|
-
if name[0..6] == 'render_'
|
6
|
-
SemanticNavigation::Item.set_default_option('view_object',self)
|
7
|
-
semantic_navigation_config.render(name[7..-1], command)
|
8
|
-
else
|
9
|
-
raise NoMethodError.new("NoMethodError:#{name}")
|
10
|
-
end
|
11
|
-
end
|
12
2
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
def navigation_for(name, options = {})
|
4
|
+
render_name = options.delete :as
|
5
|
+
render_name ||= :list
|
6
|
+
SemanticNavigation::Configuration.new.render(name, render_name, options, self)
|
7
|
+
end
|
8
|
+
|
9
|
+
def active_item_for(name, level = nil)
|
10
|
+
navigation = SemanticNavigation::Configuration.new.navigation(name)
|
11
|
+
item = navigation
|
12
|
+
while !item.is_a?(SemanticNavigation::Core::Leaf) &&
|
13
|
+
!item.sub_elements.find{|e| e.active}.nil? &&
|
14
|
+
(!level.nil? ? item.level < level : true)
|
15
|
+
item = item.sub_elements.find{|e| e.active}
|
18
16
|
end
|
19
|
-
|
17
|
+
item.name if item != navigation
|
20
18
|
end
|
21
|
-
|
22
19
|
|
23
20
|
end
|
@@ -2,14 +2,22 @@ require 'semantic_navigation/helper_methods'
|
|
2
2
|
|
3
3
|
module SemanticNavigation
|
4
4
|
class Railtie < Rails::Railtie
|
5
|
-
|
6
|
-
initializer "semantic_navigation.
|
7
|
-
|
5
|
+
|
6
|
+
initializer "semantic_navigation.extend_helper_methods" do
|
7
|
+
ActiveSupport.on_load :action_view do
|
8
|
+
ActionView::Base.send :include, HelperMethods
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
+
if Rails.env == "production"
|
13
|
+
config.after_initialize {
|
14
|
+
load "#{Rails.root}/config/semantic_navigation.rb"
|
15
|
+
}
|
16
|
+
else
|
17
|
+
ActionDispatch::Callbacks.before {
|
18
|
+
load "#{Rails.root}/config/semantic_navigation.rb"
|
19
|
+
}
|
12
20
|
end
|
13
|
-
|
21
|
+
|
14
22
|
end
|
15
23
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'semantic_navigation/renderers/render_helpers'
|
2
|
+
require 'semantic_navigation/renderers/acts_as_list'
|
3
|
+
require 'semantic_navigation/renderers/acts_as_breadcrumb'
|
4
|
+
require 'semantic_navigation/renderers/list'
|
5
|
+
require 'semantic_navigation/renderers/bread_crumb'
|
6
|
+
require 'semantic_navigation/twitter_bootstrap/breadcrumb'
|
7
|
+
require 'semantic_navigation/twitter_bootstrap/list'
|
8
|
+
require 'semantic_navigation/twitter_bootstrap/tabs'
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module SemanticNavigation
|
2
|
+
module Renderers
|
3
|
+
module ActsAsBreadcrumb
|
4
|
+
|
5
|
+
def render_navigation(object)
|
6
|
+
navigation(object) do
|
7
|
+
while !object.class.in?(SemanticNavigation::Core::Leaf, NilClass) &&
|
8
|
+
from_level.to_i > object.level
|
9
|
+
object = object.sub_elements.find(&:active)
|
10
|
+
end
|
11
|
+
unless object.class.in?(SemanticNavigation::Core::Leaf, NilClass)
|
12
|
+
active_element = object.sub_elements.find{|e| e.active}
|
13
|
+
active_element.render(self) if active_element
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def render_node(object)
|
19
|
+
active_element = object.sub_elements.find{|e| e.active}
|
20
|
+
render_element = active_element.render(self) if active_element
|
21
|
+
if render_element
|
22
|
+
node(object) do
|
23
|
+
render_element
|
24
|
+
end
|
25
|
+
else
|
26
|
+
render_leaf(object)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def render_leaf(object)
|
31
|
+
show = !until_level.nil? ? object.level <= until_level+1 : true
|
32
|
+
return nil unless show
|
33
|
+
|
34
|
+
leaf(object)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|