crumble 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ pkg
2
+ crumble.gemspec
@@ -0,0 +1,124 @@
1
+ Crumble - It's like breadcrumbs for your Rails application!
2
+
3
+ It's a tiny combination of a helper and a simple configuration class to make breadcrumbs cool, because they're not.
4
+
5
+ Installation
6
+ ============
7
+
8
+ The gem is hosted on gemcutter, so if you haven’t already, add it as a gem source:
9
+
10
+ gem sources -a http://gemcutter.org/
11
+
12
+ Then install the Formtastic gem (recommended):
13
+
14
+ gem install crumble
15
+
16
+ Alternatively you can also install it as a Rails plugin:
17
+
18
+ script/plugin install git://github.com/mattmatt/crumble.git
19
+
20
+ Requires Rails 2.3.
21
+
22
+ Note: If you have configured Rails to reload all plugins in development mode, then putting your breadcrumbs configuration into an initializer won't work, since the classes, and therefore the breadcrumbs configuration will be unloaded after the request, and not be reloaded before the next one.
23
+
24
+ This will cause the problem. Either disable it, or let Rails use the default, which is to not reload plugins.
25
+
26
+ config.reload_plugins = true
27
+
28
+ Usage
29
+ =====
30
+
31
+ I wanted to have a rather simple API to configure breadcrumbs, so I made one. Basically you configure your breadcrumbs in an initializers, e.g. config/initializers/breadcrumbs.rb like so:
32
+
33
+ Breadcrumb.configure do
34
+ # Specify name, link title and the URL to link to
35
+ crumb :profile, "Your Profile", :account_url
36
+ crumb :root, "Home", :root_url
37
+
38
+ # Specify controller, action, and an array of the crumbs you specified above
39
+ trail :accounts, :show, [:root, :profile]
40
+ trail :home, :index, [:root]
41
+
42
+ # Specify the delimiter for the crumbs
43
+ delimit_with "/"
44
+ end
45
+
46
+ You can hand over parameters to the URL generator methods, the parameters are expected to exist as instance variables in your controller/helper:
47
+
48
+ crumb :blog_comment, "Your Profile", :blog_comment_url, :blog, :comment
49
+
50
+ If you need to fetch a nested object from an existing one, you can do it with nested hashes, nesting knowing now boundaries, as long as a tree of objects conforming to them (in this case @user.blog.name) exists:
51
+
52
+ crumb :blog, "Your Blog", :blog_url, :user => {:blog => :name}
53
+ crumb :blog, "Your Blog", :blog_url, :user => :blog
54
+
55
+ If you really need to (only if you really, really need to), you can specify a string to be eval'd at runtime as parameter for the URL method. Brace yourself, it's not pretty:
56
+
57
+ crumb :blog, "Your Blog", :blog_url, '@user.blog'
58
+
59
+ You can also add URL parameters derived from the parameters of the current request:
60
+
61
+ crumb :search, "Search", :new_search_url, :params => :q
62
+
63
+ Arrays of parameters work too:
64
+
65
+ crumb :search, "Search", :new_search_url, :params => [:q, :country]
66
+
67
+ And nested parameters:
68
+
69
+ crumb :search, "Search", :new_search_url, :params => {:search => :q}
70
+
71
+ If you want to make the link title content dynamic, just use single quotes and rely on interpolation, you just need to ensure the interpolated code exists in the context of your helpers:
72
+
73
+ crumb :search, 'Search (Keywords: #{params[:q]})', :new_search_url, :params => :q
74
+
75
+ If you don't want to specify any URL method at all, just use :current, it'll just use all the parameters of the current action, of course being aware that you can't have an URL method called current to rely on. But who would do that anyway?
76
+
77
+ crumb :search, 'Search (Keywords: #{params[:q]})', :current
78
+
79
+ You can base trails on conditions using :unless and :if. Both need to point to a method that exists in the context of the view.
80
+
81
+ trail :home, :index, [:root], :unless => :logged_in?
82
+ trail :home, :index, [:your_account], :if => :logged_in?
83
+
84
+ Alternatively you can specify a block that takes the controller as an argument.
85
+
86
+ trail :home, :index, [:your_account], :if => lambda {|controller| controller.logged_in?}
87
+
88
+ Your trails can also relate to a bunch of actions, just specify an array instead.
89
+
90
+ trail :profiles, [:show, :edit], [:profile]
91
+
92
+ To keep your breadcrumbs definition neat and tidy, wrap them based on their context with a handy method called, you guessed it, context:
93
+
94
+ context "user profile" do
95
+ trail :home, :index, [:root], :unless => :logged_in?
96
+ trail :home, :index, [:your_account], :if => :logged_in?
97
+ end
98
+
99
+ Dump your trails and crumbs in there and bask in the glory of an easier readable crumbs definition.
100
+
101
+ If you don't want to have the last crumb linked, no problem at all, we can do that too:
102
+
103
+ Breadcrumb.configure do
104
+ dont_link_last_crumb
105
+ end
106
+
107
+ Yep, that's it. Include that in your breadcrumbs definition and you're done.
108
+ Then, in your views, just insert the following:
109
+
110
+ <%= crumbs %>
111
+
112
+ If your trails reference non-existing crumbs, the plugin will raise an error telling you where in your configuration the illegal reference was made.
113
+
114
+ Future
115
+ ======
116
+
117
+ If you think something's missing, let me know at <meyer@paperplanes.de>, or even better, send patches, including tests.
118
+
119
+ License
120
+ =======
121
+
122
+ MIT
123
+
124
+ (c) 2009 [Mathias Meyer](http://www.paperplanes.de)
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require "spec/rake/spectask"
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "crumble"
9
+ gem.summary = %Q{Crumble - It's like breadcrumbs for your Rails application!}
10
+ gem.description = %Q{How did these breadcrumbs in your Rails application? Oh right, with this plugin!}
11
+ gem.email = "meyer@paperplanes.de"
12
+ gem.homepage = "http://github.com/mattmatt/crumble"
13
+ gem.authors = ["Mathias Meyer"]
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ end
19
+
20
+ desc "Run all specs"
21
+ Spec::Rake::SpecTask.new("spec") do |t|
22
+ t.spec_files = FileList["spec/*.rb"]
23
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,89 @@
1
+ module BreadcrumbsHelper
2
+ def crumbs
3
+ (Breadcrumb.instance.trails || []).each do |trail|
4
+ if trail.controller.to_sym == params[:controller].to_sym and
5
+ trail.action.to_sym == params[:action].to_sym
6
+ next unless trail.condition_met?(self)
7
+ return calculate_breadcrumb_trail(trail.trail)
8
+ end
9
+ end
10
+ ""
11
+ end
12
+
13
+ def calculate_breadcrumb_trail(trail)
14
+ breadcrumb_trail = []
15
+ trail.each do |crummy|
16
+ crumb = Breadcrumb.instance.crumbs[crummy]
17
+ if not Breadcrumb.instance.last_crumb_linked? and crummy == trail.last
18
+ breadcrumb_trail << eval(%Q{"#{crumb.title}"})
19
+ else
20
+ breadcrumb_trail << link_to(eval(%Q{"#{crumb.title}"}), fetch_crumb_url(crumb))
21
+ end
22
+ end
23
+ breadcrumb_trail.join(Breadcrumb.instance.delimiter)
24
+ end
25
+
26
+ def fetch_parameterized_crumb_url(crumb)
27
+ case crumb.params
28
+ when Hash
29
+ if crumb.params[:params]
30
+ send(crumb.url, fetch_parameters_recursive(crumb.params[:params]))
31
+ else
32
+ result = instance_eval("@#{assemble_crumb_url_parameter(crumb.params).join(".")}")
33
+ send(crumb.url, result)
34
+ end
35
+ else
36
+ if crumb.url == :current
37
+ params
38
+ else
39
+ prams = crumb.params.collect do |name|
40
+ case name
41
+ when Symbol
42
+ instance_variable_get("@#{name}")
43
+ when String
44
+ instance_eval(name)
45
+ end
46
+ end
47
+ send(crumb.url, *prams)
48
+ end
49
+ end
50
+ end
51
+
52
+ def fetch_crumb_url(crumb)
53
+ if crumb.params
54
+ fetch_parameterized_crumb_url(crumb)
55
+ else
56
+ send(crumb.url)
57
+ end
58
+ end
59
+
60
+ def fetch_parameters_recursive(params_hash, parent = nil)
61
+ parameters = {}
62
+ case params_hash
63
+ when Symbol
64
+ parameters[params_hash] = (parent || params)[params_hash]
65
+ when Array
66
+ params_hash.each do |pram|
67
+ parameter = (parent || params)[pram]
68
+ parameters[pram] = parameter unless parameter.blank?
69
+ end
70
+ when Hash
71
+ params_hash.each do |pram, nested|
72
+ parameters[pram] = fetch_parameters_recursive(nested, params[pram])
73
+ end
74
+ end
75
+ parameters
76
+ end
77
+
78
+ def assemble_crumb_url_parameter(params)
79
+ result = []
80
+ params.to_a.flatten.collect do |step|
81
+ result << if step.is_a?(Hash)
82
+ assemble_crumb_url_parameter(step)
83
+ else
84
+ step
85
+ end
86
+ end
87
+ result
88
+ end
89
+ end
@@ -0,0 +1,91 @@
1
+ require 'singleton'
2
+
3
+ class Breadcrumb
4
+ include Singleton
5
+ Trail = Struct.new(:controller, :action, :trail, :options, :line) do
6
+ def condition_met?(obj)
7
+ if options[:if]
8
+ evaluate(obj, options[:if])
9
+ elsif options[:unless]
10
+ !evaluate(obj, options[:unless])
11
+ else
12
+ true
13
+ end
14
+ end
15
+
16
+ def evaluate(obj, condition)
17
+ if condition.respond_to?(:call)
18
+ condition.call(obj.controller)
19
+ else
20
+ obj.send(condition)
21
+ end
22
+ end
23
+ end
24
+
25
+ Crumb = Struct.new(:name, :title, :url, :params)
26
+
27
+ attr_accessor :trails, :crumbs, :delimiter
28
+
29
+ def initialize
30
+ @last_crumb_linked = true
31
+ end
32
+
33
+ def self.configure(&blk)
34
+ instance.crumbs = {}
35
+ instance.trails = []
36
+ instance.instance_eval &blk
37
+ instance.validate
38
+ end
39
+
40
+ def trail(controller, actions, trail, options = {})
41
+ @trails ||= []
42
+ actions = Array(actions)
43
+ actions.each do |action|
44
+ @trails << Trail.new(controller, action, trail, options, caller[2].split(":")[1])
45
+ end
46
+ end
47
+
48
+ def crumb(name, title, url, *params)
49
+ params = params.first if params.any? && params.first.is_a?(Hash)
50
+ @crumbs ||= {}
51
+ @crumbs[name] = Crumb.new(name, title, url, params)
52
+ end
53
+
54
+ def context(name)
55
+ yield
56
+ end
57
+
58
+ def delimit_with(delimiter)
59
+ @delimiter = delimiter
60
+ end
61
+
62
+ def dont_link_last_crumb
63
+ @last_crumb_linked = false
64
+ end
65
+
66
+ def link_last_crumb
67
+ @last_crumb_linked = true
68
+ end
69
+
70
+ def last_crumb_linked?
71
+ @last_crumb_linked
72
+ end
73
+
74
+ def validate
75
+ invalid_trails = []
76
+ trails.each do |trail|
77
+ trail.trail.collect do |t|
78
+ invalid_trails << [trail, t] if crumbs[t].nil?
79
+ end
80
+ end
81
+
82
+ if invalid_trails.any?
83
+ messages = []
84
+ invalid_trails.each do |trail|
85
+ messages << "Trail for #{trail.first.controller}/#{trail.first.action} references non-existing crumb '#{trail.last}' (configuration file line: #{trail.first.line})"
86
+ end
87
+ raise messages.join("\n")
88
+ end
89
+ end
90
+
91
+ end
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), *%w[.. lib breadcrumb])
@@ -0,0 +1,84 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Breadcrumb do
4
+ describe "when configuring the instance" do
5
+ it "should add trails" do
6
+ Breadcrumb.configure do
7
+ crumb :profile, "Public Profile", :user_url, :user
8
+ crumb :your_account, "Public Profile", :user_url, :user
9
+
10
+ trail :accounts, :edit, [:profile, :your_account]
11
+ end
12
+
13
+ trail = Breadcrumb.instance.trails.last
14
+ trail.controller.should == :accounts
15
+ trail.action.should == :edit
16
+ trail.trail.should == [:profile, :your_account]
17
+ end
18
+
19
+ it "should add crumbs" do
20
+ Breadcrumb.configure do
21
+ crumb :profile, "Public Profile", :user_url, :user
22
+ end
23
+
24
+ profile = Breadcrumb.instance.crumbs[:profile]
25
+ profile.title.should == "Public Profile"
26
+ profile.url.should == :user_url
27
+ profile.params.should == [:user]
28
+ end
29
+
30
+ it "should store the delimiter" do
31
+ Breadcrumb.configure do
32
+ delimit_with "/"
33
+ end
34
+
35
+ Breadcrumb.instance.delimiter.should == "/"
36
+ end
37
+
38
+ it "should set the flag not to link the last crumb" do
39
+ Breadcrumb.configure do
40
+ dont_link_last_crumb
41
+ end
42
+
43
+ Breadcrumb.instance.last_crumb_linked?.should == false
44
+ end
45
+
46
+ it "should unset the flag not to link the last crumb" do
47
+ Breadcrumb.configure do
48
+ link_last_crumb
49
+ end
50
+
51
+ Breadcrumb.instance.last_crumb_linked?.should == true
52
+ end
53
+
54
+ it "should support contexts" do
55
+ Breadcrumb.configure do
56
+ context "user profile" do
57
+ crumb :profile, "Public Profile", :user_url, :user
58
+ end
59
+ end
60
+
61
+ profile = Breadcrumb.instance.crumbs[:profile]
62
+ profile.title.should == "Public Profile"
63
+ profile.url.should == :user_url
64
+ profile.params.should == [:user]
65
+ end
66
+
67
+ it "should not accept non-existing trails in crumb definitions" do
68
+ lambda {
69
+ Breadcrumb.configure do
70
+ trail :accounts, :edit, [:profile]
71
+ end
72
+ }.should raise_error(RuntimeError, "Trail for accounts/edit references non-existing crumb 'profile' (configuration file line: 70)")
73
+ end
74
+
75
+ it "should include errors for multiple missing crumb definitions" do
76
+ lambda {
77
+ Breadcrumb.configure do
78
+ trail :accounts, :edit, [:profile]
79
+ trail :accounts, :show, [:profile]
80
+ end
81
+ }.should raise_error(RuntimeError, "Trail for accounts/edit references non-existing crumb 'profile' (configuration file line: 78)\nTrail for accounts/show references non-existing crumb 'profile' (configuration file line: 79)")
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,335 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ require 'active_support'
4
+ require 'action_view/helpers/url_helper'
5
+
6
+ describe BreadcrumbsHelper do
7
+ include ActionView::Helpers::UrlHelper
8
+ include ActionView::Helpers::TagHelper
9
+ include BreadcrumbsHelper
10
+
11
+ attr_accessor :params
12
+
13
+ def controller
14
+ self
15
+ end
16
+
17
+ before(:each) do
18
+ @params = {}
19
+ @user = User.new("jonathan")
20
+ @article = Article.new(1)
21
+ Breadcrumb.configure do
22
+ delimit_with " / "
23
+ link_last_crumb
24
+ end
25
+ end
26
+
27
+ describe "when getting the breadcrumbs" do
28
+ before(:each) do
29
+ end
30
+
31
+ it "should calculate the urls in the breadcrumbs" do
32
+ Breadcrumb.configure do
33
+ crumb :your_account, "Your Account", :edit_account_url
34
+ trail :accounts, :index, [:your_account]
35
+ end
36
+ params[:controller] = 'accounts'
37
+ params[:action] = 'index'
38
+ crumbs.should == %Q{<a href="http://test.host/account/edit">Your Account</a>}
39
+ end
40
+
41
+ it "should support fetching an instance variable" do
42
+ Breadcrumb.configure do
43
+ crumb :profile, "Public Profile", :user_url, :user
44
+ trail :accounts, :edit, [:profile]
45
+ end
46
+ params[:controller] = 'accounts'
47
+ params[:action] = 'edit'
48
+ crumbs.should == %Q{<a href="http://test.host/f/jonathan">Public Profile</a>}
49
+ end
50
+
51
+ it "should support fetching multiple instance variables" do
52
+ Breadcrumb.configure do
53
+ trail :accounts, :profile, [:your_article]
54
+ crumb :your_article, "Your Article", :user_article_url, :user, :article
55
+ end
56
+
57
+ params[:controller] = 'accounts'
58
+ params[:action] = 'profile'
59
+ crumbs.should == %Q{<a href="http://test.host/f/jonathan/articles/1">Your Article</a>}
60
+ end
61
+
62
+ it "should join multiple crumbs with a /" do
63
+ Breadcrumb.configure do
64
+ trail :accounts, :show, [:profile, :your_account]
65
+ crumb :profile, "Public Profile", :user_url, :user
66
+ crumb :your_account, "Your Account", :edit_account_url
67
+ end
68
+
69
+ params[:controller] = 'accounts'
70
+ params[:action] = 'show'
71
+ crumbs.should == %Q{<a href="http://test.host/f/jonathan">Public Profile</a> / <a href="http://test.host/account/edit">Your Account</a>}
72
+ end
73
+
74
+ it "should return an empty string for no matches" do
75
+ Breadcrumb.configure do
76
+ end
77
+ params[:controller] = 'accounts'
78
+ params[:action] = 'sho'
79
+ crumbs.should == ""
80
+ end
81
+
82
+ it "should add parameters to the url" do
83
+ Breadcrumb.configure do
84
+ crumb :search, "Search", :search_url, :params => :q
85
+ trail :search, :new, [:search]
86
+ end
87
+
88
+ params[:controller] = 'search'
89
+ params[:action] = 'new'
90
+ params[:q] = 'google'
91
+ crumbs.should == %Q{<a href="http://test.host/search?q=google">Search</a>}
92
+ end
93
+
94
+ it "should add multiple parameters to the url" do
95
+ Breadcrumb.configure do
96
+ crumb :search, "Search", :search_url, :params => [:q, :country]
97
+ trail :search, :new, [:search]
98
+ end
99
+
100
+ params[:controller] = 'search'
101
+ params[:action] = 'new'
102
+ params[:country] = 'Germany'
103
+ params[:q] = 'google'
104
+ crumbs.should == %Q{<a href="http://test.host/search?q=google&amp;country=Germany">Search</a>}
105
+ end
106
+
107
+ it "should eval single quoted title strings and interpolate them" do
108
+ Breadcrumb.configure do
109
+ crumb :search_results, 'Search Results (#{@query})', :search_url, :query
110
+ trail :search, :create, [:search_results]
111
+ end
112
+
113
+ params[:controller] = 'search'
114
+ params[:action] = 'create'
115
+
116
+ @query = 'google'
117
+ crumbs.should == %Q{<a href="http://test.host/search/google">Search Results (google)</a>}
118
+ end
119
+
120
+ it "should support a list of actions to configure a trail" do
121
+ Breadcrumb.configure do
122
+ crumb :search_results, 'Search Results (#{@query})', :search_url
123
+ trail :search, [:create, :new], [:search_results]
124
+ end
125
+
126
+ params[:controller] = 'search'
127
+ params[:action] = 'create'
128
+ crumbs.should == %Q{<a href="http://test.host/search/">Search Results ()</a>}
129
+
130
+ params[:action] = 'new'
131
+ crumbs.should == %Q{<a href="http://test.host/search/">Search Results ()</a>}
132
+ end
133
+
134
+ it "should support using the current url instead of a predefined one" do
135
+ Breadcrumb.configure do
136
+ crumb :search_results, 'Search Results (#{@query})', :current
137
+ trail :search, [:create, :new], [:search_results]
138
+ end
139
+
140
+ params[:controller] = 'search'
141
+ params[:action] = 'new'
142
+ crumbs.should == %Q{<a href="http://test.host/search/new">Search Results ()</a>}
143
+ end
144
+
145
+ it "should not consider a trail when it has an :if condition and it's not met" do
146
+ Breadcrumb.configure do
147
+ crumb :search_results, 'Search Results', :current
148
+ trail :search, [:create, :new], [:search_results], :if => :is_it_false?
149
+ end
150
+
151
+ params[:controller] = 'search'
152
+ params[:action] = 'new'
153
+ crumbs.should == ""
154
+ end
155
+
156
+ it "should consider a trail when it has an :if condition and it's met" do
157
+ Breadcrumb.configure do
158
+ crumb :search_results, 'Search Results', :current
159
+ trail :search, [:create, :new], [:search_results], :if => :its_true!
160
+ end
161
+
162
+ params[:controller] = 'search'
163
+ params[:action] = 'new'
164
+ crumbs.should == %Q{<a href="http://test.host/search/new">Search Results</a>}
165
+ end
166
+
167
+ it "should not consider a trail when it has an :unless condition and it's not met" do
168
+ Breadcrumb.configure do
169
+ crumb :search_results, 'Search Results', :current
170
+ trail :search, [:create, :new], [:search_results], :unless => :its_true!
171
+ end
172
+
173
+ params[:controller] = 'search'
174
+ params[:action] = 'new'
175
+ crumbs.should == ""
176
+ end
177
+
178
+ it "should consider a trail when it has an :unless condition and it's met" do
179
+ Breadcrumb.configure do
180
+ crumb :search_results, 'Search Results', :current
181
+ trail :search, [:create, :new], [:search_results], :unless => :is_it_false?
182
+ end
183
+
184
+ params[:controller] = 'search'
185
+ params[:action] = 'new'
186
+ crumbs.should == %Q{<a href="http://test.host/search/new">Search Results</a>}
187
+ end
188
+
189
+ it "should call blocks as :unless parameters" do
190
+ Breadcrumb.configure do
191
+ crumb :search_results, 'Search Results', :current
192
+ trail :search, [:create, :new], [:search_results], :unless => lambda {|controller| controller.its_true!}
193
+ end
194
+
195
+ params[:controller] = 'search'
196
+ params[:action] = 'new'
197
+ crumbs.should == ""
198
+ end
199
+
200
+ it "should call blocks as :if parameters" do
201
+ Breadcrumb.configure do
202
+ crumb :search_results, 'Search Results', :current
203
+ trail :search, [:create, :new], [:search_results], :if => lambda {|controller| controller.its_true!}
204
+ end
205
+
206
+ params[:controller] = 'search'
207
+ params[:action] = 'new'
208
+ crumbs.should == "<a href=\"http://test.host/search/new\">Search Results</a>"
209
+ end
210
+
211
+ it "should support resolving parameters for url methods derived from a string" do
212
+ Breadcrumb.configure do
213
+ crumb :search_results, 'Search Results', :search_url, "@user.login"
214
+ trail :search, [:create, :new], [:search_results]
215
+ end
216
+
217
+ params[:controller] = 'search'
218
+ params[:action] = 'new'
219
+ crumbs.should == %Q{<a href="http://test.host/search/jonathan">Search Results</a>}
220
+ end
221
+
222
+ it "should support resolving parameters for url methods derived from a hash pointing to an object hierarchy" do
223
+ Breadcrumb.configure do
224
+ crumb :search_results, 'Search Results', :search_url, :user => :login
225
+ trail :search, [:create, :new], [:search_results]
226
+ end
227
+
228
+ params[:controller] = 'search'
229
+ params[:action] = 'new'
230
+ crumbs.should == %Q{<a href="http://test.host/search/jonathan">Search Results</a>}
231
+ end
232
+
233
+ it "should support resolving parameters for url methods derived from a hash pointing to a nested object hierarchy" do
234
+ Breadcrumb.configure do
235
+ crumb :search_results, 'Search Results', :search_url, :user => {:login => :to_s}
236
+ trail :search, [:create, :new], [:search_results]
237
+ end
238
+
239
+ params[:controller] = 'search'
240
+ params[:action] = 'new'
241
+ crumbs.should == %Q{<a href="http://test.host/search/jonathan">Search Results</a>}
242
+ end
243
+
244
+ it "should return the same breadcrumbs on subsequent calls" do
245
+ Breadcrumb.configure do
246
+ crumb :your_account, "Your Account", :edit_account_url
247
+ trail :accounts, :index, [:your_account]
248
+ end
249
+ params[:controller] = 'accounts'
250
+ params[:action] = 'index'
251
+ once = crumbs
252
+ twice = crumbs
253
+ once.should == twice
254
+ end
255
+
256
+ it "should not link the last link when the option was specified" do
257
+ Breadcrumb.configure do
258
+ trail :accounts, :show, [:profile, :your_account]
259
+ crumb :profile, "Public Profile", :user_url, :user
260
+ crumb :your_account, "Your Account", :edit_account_url
261
+ dont_link_last_crumb
262
+ end
263
+
264
+ params[:controller] = 'accounts'
265
+ params[:action] = 'show'
266
+ crumbs.should == %Q{<a href="http://test.host/f/jonathan">Public Profile</a> / Your Account}
267
+ end
268
+
269
+ it "should not link the last link when the option was specified and only one crumb is in the trail" do
270
+ Breadcrumb.configure do
271
+ trail :accounts, :show, [:profile]
272
+ crumb :profile, "Public Profile", :user_url, :user
273
+ dont_link_last_crumb
274
+ end
275
+
276
+ params[:controller] = 'accounts'
277
+ params[:action] = 'show'
278
+ crumbs.should == %Q{Public Profile}
279
+ end
280
+
281
+ describe "when fetching parameters" do
282
+ it "should support nested parameter attributes" do
283
+ Breadcrumb.configure do
284
+ crumb :nested_search, "Search", :search_url, :params => {:search => :q}
285
+ trail :search, :new, [:nested_search]
286
+ end
287
+
288
+ params[:controller] = "search"
289
+ params[:action] = 'new'
290
+ params[:search] = {:q => "google", :country => "Germany"}
291
+
292
+ fetch_parameters_recursive({:search => [:q, :country]}).should == {:search => {:q => "google", :country => "Germany"}}
293
+ end
294
+
295
+ it "should support nested array parameters" do
296
+ Breadcrumb.configure do
297
+ crumb :nested_search, "Search", :search_url, :params => {:search => :q}
298
+ trail :search, :new, [:nested_search]
299
+ end
300
+
301
+ params[:controller] = "search"
302
+ params[:action] = 'new'
303
+ params[:search] = {:q => "google", :country => ["Germany", "Australia"]}
304
+
305
+ fetch_parameters_recursive({:search => [:q, :country]}).should == {:search => {:q => "google", :country => ["Germany", "Australia"]}}
306
+ end
307
+
308
+ it "should not include empty parameters" do
309
+ Breadcrumb.configure do
310
+ crumb :nested_search, "Search", :search_url, :params => {:search => :q}
311
+ trail :search, :new, [:nested_search]
312
+ end
313
+
314
+ params[:controller] = "search"
315
+ params[:action] = 'new'
316
+ params[:search] = {:q => ""}
317
+
318
+ fetch_parameters_recursive({:search => [:q, :country]}).should == {:search => {}}
319
+ end
320
+
321
+ it "should not include empty parameters with nested hashes" do
322
+ Breadcrumb.configure do
323
+ crumb :nested_search, "Search", :search_url, :params => {:search => :q}
324
+ trail :search, :new, [:nested_search]
325
+ end
326
+
327
+ params[:controller] = "search"
328
+ params[:action] = 'new'
329
+ params[:search] = {:q => "google", :country => []}
330
+
331
+ fetch_parameters_recursive({:search => [:q, :country]}).should == {:search => {:q => "google"}}
332
+ end
333
+ end
334
+ end
335
+ end
@@ -0,0 +1,62 @@
1
+ require 'rubygems'
2
+ gem 'rspec'
3
+
4
+ require "#{File.dirname(__FILE__)}/../app/helpers/breadcrumbs_helper"
5
+ require "#{File.dirname(__FILE__)}/../lib/breadcrumb"
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ config.before(:each) do
10
+ @old_trails = Breadcrumb.instance.trails
11
+ Breadcrumb.instance.trails = nil
12
+
13
+ @old_crumbs = Breadcrumb.instance.crumbs
14
+ Breadcrumb.instance.crumbs = nil
15
+ end
16
+
17
+ config.after(:each) do
18
+ Breadcrumb.instance.crumbs = @old_crumbs
19
+ Breadcrumb.instance.trails = @old_trails
20
+ end
21
+
22
+ public
23
+
24
+ def edit_account_url
25
+ "http://test.host/account/edit"
26
+ end
27
+
28
+ def user_url(user)
29
+ "http://test.host/f/#{user.login}"
30
+ end
31
+
32
+ def user_article_url(user, article)
33
+ "http://test.host/f/#{user.login}/articles/#{article.id}"
34
+ end
35
+
36
+ def search_url(params = nil)
37
+ if params.is_a?(Hash)
38
+ "http://test.host/search?#{params.collect{|key, value| "#{key.to_s}=#{value}"}.join('&')}"
39
+ else
40
+ "http://test.host/search/#{params}"
41
+ end
42
+ end
43
+
44
+ def url_for(params)
45
+ if params.is_a?(Hash)
46
+ "http://test.host/#{params[:controller]}/#{params[:action]}"
47
+ else
48
+ super
49
+ end
50
+ end
51
+
52
+ def is_it_false?
53
+ false
54
+ end
55
+
56
+ def its_true!
57
+ true
58
+ end
59
+
60
+ User = Struct.new(:login)
61
+ Article = Struct.new(:id)
62
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crumble
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mathias Meyer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-18 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: How did these breadcrumbs in your Rails application? Oh right, with this plugin!
17
+ email: meyer@paperplanes.de
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.md
24
+ files:
25
+ - .gitignore
26
+ - README.md
27
+ - Rakefile
28
+ - VERSION
29
+ - app/helpers/breadcrumbs_helper.rb
30
+ - lib/breadcrumb.rb
31
+ - rails/init.rb
32
+ - spec/breadcrumb_spec.rb
33
+ - spec/breadcrumbs_helper_spec.rb
34
+ - spec/spec_helper.rb
35
+ has_rdoc: true
36
+ homepage: http://github.com/mattmatt/crumble
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options:
41
+ - --charset=UTF-8
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.5
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Crumble - It's like breadcrumbs for your Rails application!
63
+ test_files:
64
+ - spec/breadcrumb_spec.rb
65
+ - spec/breadcrumbs_helper_spec.rb
66
+ - spec/spec_helper.rb