semantic_navigation 0.0.6 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|