site_map 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +63 -10
- data/Rakefile +1 -1
- data/lib/site_map.rb +41 -21
- data/lib/site_map/exceptions.rb +2 -0
- data/lib/site_map/helpers/mapping.rb +8 -4
- data/lib/site_map/map.rb +7 -0
- data/lib/site_map/tasks/view_nodes.rake +1 -1
- data/lib/site_map/version.rb +1 -1
- data/lib/site_map/view_helpers.rb +16 -2
- data/lib/site_map/view_node.rb +22 -17
- metadata +27 -7
data/README.rdoc
CHANGED
@@ -2,31 +2,84 @@
|
|
2
2
|
|
3
3
|
== Description
|
4
4
|
|
5
|
-
SiteMap provides a way to model out your site's views in a hierarchal fashion. You configure your views and then it builds a tree structure from it that is easy to lookup specific nodes and also traverse their relationships, such as
|
5
|
+
SiteMap provides a way to model out your site's views in a hierarchal fashion. You configure your views and then it builds a tree structure from it that is easy to lookup specific nodes and also traverse their relationships, such as parents or children.
|
6
6
|
|
7
7
|
== Installation
|
8
8
|
|
9
|
-
|
9
|
+
gem install site_map
|
10
10
|
|
11
|
-
==
|
11
|
+
== Usage
|
12
12
|
|
13
|
-
|
13
|
+
=== Basic Definition
|
14
14
|
|
15
|
+
SiteMap provides a simple syntax for defining a site's views.
|
16
|
+
|
17
|
+
require 'site_map'
|
18
|
+
SiteMap.define do |map|
|
19
|
+
map.view :home
|
20
|
+
map.view :about
|
21
|
+
map.view :contact
|
22
|
+
end
|
23
|
+
|
24
|
+
This defines three views home, about and contact. The +view+ method is the most basic way to configure your site map and only requires a unique index as it's first parameter. It simply creates within the site map a view node with the index provided (in this case +home+, +about+ or +contact+).
|
25
|
+
|
26
|
+
=== Setting Attributes
|
27
|
+
|
28
|
+
Every site map view node also has a +label+, +url+ and +visible+ attribute. The label is the name of the page the node represents and the url is how you navigate to that page. The visible attribute specifies whether this node should be shown. Using these options is simple:
|
29
|
+
|
30
|
+
require 'site_map'
|
15
31
|
SiteMap.define do |map|
|
16
|
-
map.view
|
32
|
+
map.view(:home, {
|
33
|
+
:label => "Home :app_name",
|
34
|
+
:url => "'/home'"
|
35
|
+
})
|
36
|
+
map.view(:about, {
|
37
|
+
:url => "about_path"
|
38
|
+
})
|
39
|
+
map.view(:contact, {
|
40
|
+
:visible => "can_contact?"
|
41
|
+
})
|
17
42
|
end
|
18
43
|
|
19
|
-
|
44
|
+
So same basic configuration, but I've added custom options for the previously mentioned attributes. Firstly, url and visible attributes are intended to be eav'd within the view space of an app. This allows you to specify very custom ways to determine a path or check if a node should be shown. Label's are not intended to be eval'd, but are dynamic in a different way, by subbing out symbol names with an options hash, again in the view space. This is explained more and used within site map's view helpers.
|
45
|
+
|
46
|
+
Secondly, not every attribute has to be set. By default, a site map's visible is always +true+, and it's url is +nil+. Label also has a default, based on the index. For labels, site map will try to use a +titleize+ method on the string version of it's index. If defined, the titleized string is returned, otherwise just the string version of the index is.
|
20
47
|
|
21
|
-
|
48
|
+
=== Groups and nesting
|
22
49
|
|
23
|
-
|
50
|
+
Site map provides other ways to define nodes and also allows nesting nodes within other nodes.
|
24
51
|
|
52
|
+
require 'site_map'
|
25
53
|
SiteMap.define do |map|
|
26
|
-
map.
|
54
|
+
map.view :home
|
55
|
+
map.view :about
|
56
|
+
map.group :community do |community_group|
|
57
|
+
community_group.view :forum
|
58
|
+
community_group.view :blog
|
59
|
+
end
|
27
60
|
end
|
28
61
|
|
29
|
-
|
62
|
+
In this definition, we are using a new method +group+. A group node is very similar to a regular view node, and is intended to group similar views. In this case, we have created a group, called community with a blog and forum view as children. A group's definition syntax is the same as a view's, but it has different defaulting logic and behavior within the site map. A group's url will default to it's first child's url, in this case the forum view's url. I'll explain the differences in how a group behaves in the looking up views and traversing the site map sections later.
|
63
|
+
|
64
|
+
=== Looking up a view node
|
65
|
+
|
66
|
+
Enough we defining the site map, on to actually retrieving what's been defined. Assuming the previous definition:
|
67
|
+
|
68
|
+
view_node = SiteMap[:forum]
|
69
|
+
view_node = SiteMap[:community] # => returns nil, can't look up group nodes
|
70
|
+
|
71
|
+
Specifying the index of a node will return that view node. When you look up a group node's index, it isn't returned. Group node's are not intended to be looked up, but still exist in the relationships of a view node.
|
72
|
+
|
73
|
+
=== View node relationships
|
74
|
+
|
75
|
+
After looking up a view node, you can access it's relationships.
|
76
|
+
|
77
|
+
view_node = SiteMap[:forum]
|
78
|
+
view_node.parent # => returns community group node
|
79
|
+
view_node.siblings # => returns an array with blog view node in it, [SiteMap[:blog]]
|
80
|
+
view_node.parent.children # => returns an array with blog and forum view nodes, [SiteMap[:forum], SiteMap[:blog]]
|
81
|
+
|
82
|
+
Other relationship methods include +ancestors+, +self_and_siblings+ and +self_and_ancestors+.
|
30
83
|
|
31
84
|
Copyright (c) 2010 John Collin Redding
|
32
85
|
See the attached MIT License.
|
data/Rakefile
CHANGED
@@ -17,7 +17,7 @@ spec = Gem::Specification.new do |s|
|
|
17
17
|
s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib}/**/*")
|
18
18
|
# s.executables = ['site_map']
|
19
19
|
|
20
|
-
|
20
|
+
s.add_development_dependency("shoulda", [">= 2.10.2"])
|
21
21
|
end
|
22
22
|
|
23
23
|
Rake::GemPackageTask.new(spec) do |pkg|
|
data/lib/site_map.rb
CHANGED
@@ -6,33 +6,53 @@ end
|
|
6
6
|
|
7
7
|
module SiteMap
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
DEFAULT_FILE = File.join('config', 'site_map.rb')
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def setup(*files)
|
14
|
+
files = files.first if files.first.is_a?(Array)
|
15
|
+
files << DEFAULT_FILE if files.empty?
|
16
|
+
self.logger = Rails.logger if defined?(Rails)
|
17
|
+
@@map ||= SiteMap::Map.new
|
18
|
+
@@map.clear_nodes!
|
19
|
+
files.each do |file|
|
20
|
+
begin
|
21
|
+
load file
|
22
|
+
rescue LoadError => exception
|
23
|
+
self.logger.info("SiteMap config file: #{file} could not be loaded.") unless file == DEFAULT_FILE
|
24
|
+
end
|
18
25
|
end
|
19
26
|
end
|
20
|
-
end
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
28
|
+
def [](view_node_index)
|
29
|
+
self.map.find(view_node_index.to_sym)
|
30
|
+
end
|
25
31
|
|
26
|
-
|
27
|
-
|
28
|
-
|
32
|
+
def view_nodes
|
33
|
+
self.map.view_nodes
|
34
|
+
end
|
35
|
+
alias_method :views, :view_nodes
|
36
|
+
|
37
|
+
def visible_views
|
38
|
+
self.map.visible_views
|
39
|
+
end
|
29
40
|
|
30
|
-
|
31
|
-
|
32
|
-
|
41
|
+
def map
|
42
|
+
@@map
|
43
|
+
end
|
44
|
+
|
45
|
+
def define(&block)
|
46
|
+
yield @@map
|
47
|
+
end
|
48
|
+
|
49
|
+
def logger
|
50
|
+
@@logger ||= Logger.new(STDOUT)
|
51
|
+
end
|
52
|
+
def logger=(new_logger)
|
53
|
+
@@logger = new_logger
|
54
|
+
end
|
33
55
|
|
34
|
-
def self.define(&block)
|
35
|
-
yield @@map
|
36
56
|
end
|
37
57
|
|
38
58
|
end
|
data/lib/site_map/exceptions.rb
CHANGED
@@ -31,9 +31,9 @@ module SiteMap
|
|
31
31
|
end
|
32
32
|
def collection_view(resource, action, options={})
|
33
33
|
options.merge!({:resource => resource.to_sym, :action => action.to_sym})
|
34
|
-
view_node = self.add_node(
|
34
|
+
view_node = self.add_node(self.index_for(resource, action), :collection, options)
|
35
35
|
(DEFAULT_ALIAS[action] || []).each do |action|
|
36
|
-
view_node.alias(
|
36
|
+
view_node.alias(self.index_for(resource, action), view_node.index)
|
37
37
|
end
|
38
38
|
block_given? ? (yield view_node) : view_node
|
39
39
|
end
|
@@ -43,15 +43,19 @@ module SiteMap
|
|
43
43
|
end
|
44
44
|
def member_view(resource, action, options={})
|
45
45
|
options.merge!({:resource => resource.to_sym, :action => action.to_sym})
|
46
|
-
view_node = self.add_node(
|
46
|
+
view_node = self.add_node(self.index_for(resource, action), :member, options)
|
47
47
|
(DEFAULT_ALIAS[action] || []).each do |action|
|
48
|
-
view_node.alias(
|
48
|
+
view_node.alias(self.index_for(resource, action), view_node.index)
|
49
49
|
end
|
50
50
|
block_given? ? (yield view_node) : view_node
|
51
51
|
end
|
52
52
|
|
53
53
|
protected
|
54
54
|
|
55
|
+
def index_for(resource, action)
|
56
|
+
[resource, action].join('__').to_sym
|
57
|
+
end
|
58
|
+
|
55
59
|
def add_node(new_index, node_type, options={})
|
56
60
|
view_node = SiteMap::ViewNode.new(*view_node_params(new_index, node_type, options))
|
57
61
|
self.add_to_children(view_node)
|
data/lib/site_map/map.rb
CHANGED
@@ -5,6 +5,7 @@ module SiteMap
|
|
5
5
|
include SiteMap::Helpers::Mapping
|
6
6
|
ATTRIBUTES = [:view_nodes, :index_of_nodes]
|
7
7
|
ATTRIBUTES.each{|attribute| attr_reader attribute }
|
8
|
+
alias_method :views, :view_nodes
|
8
9
|
|
9
10
|
def initialize
|
10
11
|
self.clear_nodes!
|
@@ -34,6 +35,12 @@ module SiteMap
|
|
34
35
|
def inspect
|
35
36
|
"#<#{self.class}>"
|
36
37
|
end
|
38
|
+
|
39
|
+
def visible_views
|
40
|
+
@view_nodes.select do |view|
|
41
|
+
view.visible?
|
42
|
+
end
|
43
|
+
end
|
37
44
|
|
38
45
|
protected
|
39
46
|
|
@@ -2,7 +2,7 @@ namespace :site_map do
|
|
2
2
|
|
3
3
|
desc 'Print out all defined view nodes based on the current SiteMap configuration'
|
4
4
|
task :nodes => :environment do
|
5
|
-
index_length = SiteMap.map.index_of_nodes.collect{|key, value| key.inspect.length}.max
|
5
|
+
index_length = SiteMap.map.index_of_nodes.collect{|key, value| key.inspect.length}.max + 1
|
6
6
|
index_length += (SiteMap.map.index_of_nodes.collect{|key, value| value.ancestors.size}.max * 2)
|
7
7
|
label_length = SiteMap.map.index_of_nodes.collect{|key, value| value.label.inspect.length}.max
|
8
8
|
url_length = SiteMap.map.index_of_nodes.collect{|key, value| value.url.inspect.length}.max
|
data/lib/site_map/version.rb
CHANGED
@@ -6,7 +6,7 @@ module SiteMap
|
|
6
6
|
{}
|
7
7
|
end
|
8
8
|
|
9
|
-
# subbing hash options into view node label code thanks to kelredd-useful
|
9
|
+
# subbing hash options into view node label, code thanks to kelredd-useful
|
10
10
|
def view_node_label(view_node)
|
11
11
|
label_string = view_node.label
|
12
12
|
view_node_label_options.each do |label_key, value|
|
@@ -18,9 +18,23 @@ module SiteMap
|
|
18
18
|
eval(view_node.url)
|
19
19
|
end
|
20
20
|
def view_node_visible(view_node)
|
21
|
-
eval(view_node.visible)
|
21
|
+
eval(view_node.visible.to_s)
|
22
22
|
end
|
23
23
|
alias :view_node_visible? :view_node_visible
|
24
24
|
|
25
|
+
def display_title(options = {})
|
26
|
+
options = { :connector => " > " }.merge(options)
|
27
|
+
[ view_node_label(@view_node.parent),
|
28
|
+
view_node_label(@view_node)
|
29
|
+
].join(options[:connector])
|
30
|
+
end
|
31
|
+
def display_crumbs
|
32
|
+
|
33
|
+
end
|
34
|
+
def display_menu
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
25
39
|
end
|
26
40
|
end
|
data/lib/site_map/view_node.rb
CHANGED
@@ -46,8 +46,15 @@ module SiteMap
|
|
46
46
|
@url ? @url : self.default_url
|
47
47
|
end
|
48
48
|
def visible
|
49
|
-
@visible
|
49
|
+
if @visible.nil?
|
50
|
+
true
|
51
|
+
elsif @visible.kind_of?(::String)
|
52
|
+
@visible
|
53
|
+
else
|
54
|
+
!!@visible
|
55
|
+
end
|
50
56
|
end
|
57
|
+
alias_method :visible?, :visible
|
51
58
|
|
52
59
|
def aliases
|
53
60
|
@aliases ||= self.map.index_of_nodes.collect do |key, view_node|
|
@@ -102,7 +109,7 @@ module SiteMap
|
|
102
109
|
when :member
|
103
110
|
self.resource_label(self.single_string)
|
104
111
|
else
|
105
|
-
@index.to_s
|
112
|
+
@index.to_s.titleize
|
106
113
|
end
|
107
114
|
end
|
108
115
|
def default_url
|
@@ -114,7 +121,7 @@ module SiteMap
|
|
114
121
|
when :member
|
115
122
|
self.resource_url
|
116
123
|
else
|
117
|
-
@
|
124
|
+
"/#{@index.to_s.underscore.dasherize}"
|
118
125
|
end
|
119
126
|
end
|
120
127
|
|
@@ -123,40 +130,38 @@ module SiteMap
|
|
123
130
|
template.gsub(':action', self.title_string(@action.to_s)).gsub(':resource', resource_text)
|
124
131
|
end
|
125
132
|
def resource_url
|
133
|
+
action_str = unless (action_template = URL_ACTION_TEMPLATES[@action])
|
134
|
+
@action.to_s
|
135
|
+
end
|
136
|
+
template = (action_template || BASE_URL_TEMPLATE[@node_type])
|
126
137
|
resource_text = if @node_type == :collection
|
127
|
-
action_str = unless URL_ACTION_TEMPLATES[@action]
|
128
|
-
@action.to_s
|
129
|
-
end
|
130
138
|
parent_str = if self.parent && [:member, :collection].include?(self.parent.node_type)
|
131
139
|
self.single_string(self.parent.resource)
|
132
140
|
end
|
133
|
-
template = (URL_ACTION_TEMPLATES[@action] || BASE_URL_TEMPLATE[@node_type])
|
134
141
|
resourced_url = [action_str, parent_str, template].flatten.compact.join('_')
|
135
142
|
resourced_url = [resourced_url, ("(@#{parent_str})" if parent_str)].compact.join
|
136
143
|
resourced_url.gsub(':resource', (@action == :new ? self.single_string : @resource.to_s))
|
137
144
|
else
|
138
|
-
action_str = unless URL_ACTION_TEMPLATES[@action]
|
139
|
-
@action.to_s
|
140
|
-
end
|
141
|
-
template = (URL_ACTION_TEMPLATES[@action] || BASE_URL_TEMPLATE[@node_type])
|
142
145
|
resourced_url = [action_str, template].flatten.compact.join('_')
|
143
146
|
resourced_url.gsub(':resource', self.single_string)
|
144
147
|
end
|
145
148
|
end
|
146
149
|
|
147
|
-
def single_string(string =
|
148
|
-
string
|
149
|
-
string.to_s.respond_to?(:singularize) ? string.to_s.singularize : string.to_s
|
150
|
+
def single_string(string = @resource)
|
151
|
+
self.format_string(string, :singularize)
|
150
152
|
end
|
151
|
-
def title_string(string =
|
152
|
-
string
|
153
|
-
string.to_s.respond_to?(:titleize) ? string.to_s.titleize : string.to_s
|
153
|
+
def title_string(string = @resource)
|
154
|
+
self.format_string(string, :titleize)
|
154
155
|
end
|
155
156
|
|
156
157
|
def view_node_params(new_index, node_type, options)
|
157
158
|
[new_index, self.map, node_type, options.merge(:parent => self)]
|
158
159
|
end
|
159
160
|
|
161
|
+
def format_string(string, format)
|
162
|
+
(string = string.to_s).respond_to?(format) ? string.send(format) : string
|
163
|
+
end
|
164
|
+
|
160
165
|
end
|
161
166
|
|
162
167
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: site_map
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 3
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Collin Redding
|
@@ -9,10 +14,23 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-04-16 00:00:00 -05:00
|
13
18
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: shoulda
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 2
|
29
|
+
- 10
|
30
|
+
- 2
|
31
|
+
version: 2.10.2
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
16
34
|
description:
|
17
35
|
email: TempestTTU@gmail.com
|
18
36
|
executables: []
|
@@ -49,18 +67,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
67
|
requirements:
|
50
68
|
- - ">="
|
51
69
|
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 0
|
52
72
|
version: "0"
|
53
|
-
version:
|
54
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
74
|
requirements:
|
56
75
|
- - ">="
|
57
76
|
- !ruby/object:Gem::Version
|
77
|
+
segments:
|
78
|
+
- 0
|
58
79
|
version: "0"
|
59
|
-
version:
|
60
80
|
requirements: []
|
61
81
|
|
62
82
|
rubyforge_project:
|
63
|
-
rubygems_version: 1.3.
|
83
|
+
rubygems_version: 1.3.6
|
64
84
|
signing_key:
|
65
85
|
specification_version: 3
|
66
86
|
summary: SiteMap provides a way to model out your site's views in a hierarchal fashion.
|