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.
@@ -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 parent or children.
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
- sudo gem install site_map
9
+ gem install site_map
10
10
 
11
- == Basic Usage
11
+ == Usage
12
12
 
13
- SiteMap by default looks for "config/site_map.rb" to try and load configurations from. Defining your site map is easy with a syntax similar to Rails routes:
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 :user
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
- This creates a single view in your map that can be found with the index :user. Finding view node's is easy as well:
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
- SiteMap[:user]
48
+ === Groups and nesting
22
49
 
23
- If the a view node with the index :user exists in the site map, then it will return it and can be used as needed. SiteMap can also be used to define views in a resource based method. You can define a collection of view node's with the collection method:
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.collection :users
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
- This defines a single view node with an index of :users__index. It then uses the alias method, to also allow looking up the view node with :users__new and :users_create. SiteMap also defines a member method, which creates a node with :users__show, and alias' :users__edit, :users__update and :users__destroy.
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
- # s.add_dependency('gem_name', '~> 0.0.1')
20
+ s.add_development_dependency("shoulda", [">= 2.10.2"])
21
21
  end
22
22
 
23
23
  Rake::GemPackageTask.new(spec) do |pkg|
@@ -6,33 +6,53 @@ end
6
6
 
7
7
  module SiteMap
8
8
 
9
- def self.setup(*files)
10
- files = files.first if files.first.is_a?(Array)
11
- files << File.join('config', 'site_map.rb') if files.empty?
12
- @@map ||= SiteMap::Map.new
13
- @@map.clear_nodes!
14
- files.each do |file|
15
- begin
16
- load file
17
- rescue LoadError => exception
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
- def self.[](view_node_index)
23
- self.map.find(view_node_index.to_sym)
24
- end
28
+ def [](view_node_index)
29
+ self.map.find(view_node_index.to_sym)
30
+ end
25
31
 
26
- def self.view_nodes
27
- self.map.view_nodes
28
- end
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
- def self.map
31
- @@map
32
- end
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
@@ -1,6 +1,8 @@
1
1
  module SiteMap
2
2
  module Exceptions
3
3
 
4
+ # This is an exception raised when an alias mapping is used and the node to be aliased does not
5
+ # exist
4
6
  class NonExistantViewNode < StandardError
5
7
  end
6
8
 
@@ -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([resource, action].join('__').to_sym, :collection, options)
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([resource, action].join('__').to_sym, view_node.index)
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([resource, action].join('__').to_sym, :member, options)
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([resource, action].join('__').to_sym, view_node.index)
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)
@@ -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
@@ -3,7 +3,7 @@ module SiteMap
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 3
6
- TINY = 0
6
+ TINY = 1
7
7
 
8
8
  def self.to_s # :nodoc:
9
9
  [MAJOR, MINOR, TINY].join('.')
@@ -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
@@ -46,8 +46,15 @@ module SiteMap
46
46
  @url ? @url : self.default_url
47
47
  end
48
48
  def visible
49
- @visible ? @visible : 'true'
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
- @url
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 = nil)
148
- string ||= @resource
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 = nil)
152
- string ||= @resource
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
- version: 0.3.0
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-01-19 00:00:00 -06:00
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.5
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.