gretel 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +4 -0
- data/README.md +142 -95
- data/gretel.gemspec +1 -1
- data/lib/generators/gretel/USAGE +2 -2
- data/lib/generators/gretel/install_generator.rb +3 -3
- data/lib/generators/gretel/templates/breadcrumbs.rb +28 -0
- data/lib/gretel.rb +46 -0
- data/lib/gretel/crumb.rb +2 -0
- data/lib/gretel/crumbs.rb +50 -12
- data/lib/gretel/deprecated.rb +27 -0
- data/lib/gretel/version.rb +1 -1
- data/lib/gretel/view_helpers.rb +2 -0
- data/test/deprecated_test.rb +30 -0
- data/test/dummy/config/breadcrumbs.rb +3 -0
- data/test/dummy/config/breadcrumbs/test_crumbs.rb +71 -0
- data/test/gretel_test.rb +14 -0
- data/test/helper_methods_test.rb +156 -3
- metadata +21 -28
- data/lib/generators/gretel/gretel_generator.rb +0 -10
- data/lib/generators/gretel/templates/initializer.rb +0 -29
- data/test/dummy/config/initializers/breadcrumbs.rb +0 -77
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 20b6074d04a88e299ce92a69065f183ba6e299ca
|
4
|
+
data.tar.gz: 33fa2c8f9ff4cb909a430786d1e4b467ffec40f5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 38c61ee418788d568672b173f8fb72e67d45b00c6022210c37009a0bb9a53b6885c71d286647a583ebf0390544ee495e094129945919147161e201a2d68164a9
|
7
|
+
data.tar.gz: af07be5e7434820b66b08f3e48959e8f123658ec5cd5f978264a80c2443480c70a46181f813ed38048d68fc2ff013490a3dfd03e067dca1e39f933be5084b104
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
Version 2.1
|
5
|
+
-----------
|
6
|
+
* Breadcrumbs are now configured in `config/breadcrumbs.rb` and `config/breadcrumbs/**/*.rb` and reloaded when changed in the development environment instead of the initializer that required restart when configuration changed.
|
7
|
+
|
4
8
|
Version 2.0
|
5
9
|
-----------
|
6
10
|
|
data/README.md
CHANGED
@@ -2,20 +2,40 @@
|
|
2
2
|
|
3
3
|
Gretel is a [Ruby on Rails](http://rubyonrails.org) plugin that makes it easy yet flexible to create breadcrumbs.
|
4
4
|
|
5
|
+
New in version 2.1
|
6
|
+
------------------
|
7
|
+
Instead of using the initializer that in Gretel version 2.0 and below required restarting the application after breadcrumb configuration changes, the configuration of the breadcrumbs is now loaded from `config/breadcrumbs.rb` (and `config/breadcrumbs/*.rb` if you want to split your breadcrumbs configuration across multiple files).
|
8
|
+
In the Rails development environment, these files are automatically reloaded when changed.
|
5
9
|
|
6
|
-
|
7
|
-
------------
|
10
|
+
Using the initializer (e.g. `config/initializers/breadcrumbs.rb`) is deprecated but still supported until Gretel version 3.0.
|
8
11
|
|
9
|
-
|
12
|
+
To update, use `bundle update gretel`. Then remove the `Gretel::Crumbs.layout do ... end` block, so instead of:
|
10
13
|
|
11
14
|
```ruby
|
12
|
-
|
15
|
+
Gretel::Crumbs.layout do
|
16
|
+
crumb :root do
|
17
|
+
link "Home", root_path
|
18
|
+
end
|
19
|
+
end
|
13
20
|
```
|
14
21
|
|
15
|
-
|
22
|
+
in the initializer, you write:
|
16
23
|
|
17
24
|
```ruby
|
18
|
-
|
25
|
+
crumb :root do
|
26
|
+
link "Home", root_path
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
in `config/breadcrumbs.rb`.
|
31
|
+
|
32
|
+
Installation
|
33
|
+
------------
|
34
|
+
|
35
|
+
In your *Gemfile*:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
gem "gretel"
|
19
39
|
```
|
20
40
|
|
21
41
|
And run:
|
@@ -27,31 +47,29 @@ $ bundle install
|
|
27
47
|
Example
|
28
48
|
-------
|
29
49
|
|
30
|
-
Start by generating
|
50
|
+
Start by generating breadcrumbs configuration file:
|
31
51
|
|
32
52
|
```bash
|
33
53
|
$ rails generate gretel:install
|
34
54
|
```
|
35
55
|
|
36
|
-
Then, in *config/
|
56
|
+
Then, in *config/breadcrumbs.rb*:
|
37
57
|
|
38
58
|
```ruby
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
59
|
+
# Root crumb
|
60
|
+
crumb :root do
|
61
|
+
link "Home", root_path
|
62
|
+
end
|
44
63
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
64
|
+
# Issue list
|
65
|
+
crumb :issues do
|
66
|
+
link "All issues", issues_path
|
67
|
+
end
|
49
68
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
69
|
+
# Issue
|
70
|
+
crumb :issue do |issue|
|
71
|
+
link issue.title, issue
|
72
|
+
parent :issues
|
55
73
|
end
|
56
74
|
```
|
57
75
|
|
@@ -97,6 +115,94 @@ Option | Description
|
|
97
115
|
:class | CSS class for the breadcrumbs container. | `"breadcrumbs"`
|
98
116
|
:current_class | CSS class for the current link or span. | `"current"`
|
99
117
|
|
118
|
+
More examples
|
119
|
+
-------------
|
120
|
+
|
121
|
+
In *config/breadcrumbs.rb*:
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
# Root crumb
|
125
|
+
crumb :root do
|
126
|
+
link "Home", root_path
|
127
|
+
end
|
128
|
+
|
129
|
+
# Regular crumb
|
130
|
+
crumb :projects do
|
131
|
+
link "Projects", projects_path
|
132
|
+
end
|
133
|
+
|
134
|
+
# Parent crumbs
|
135
|
+
crumb :project_issues do |project|
|
136
|
+
link "Issues", project_issues_path(project)
|
137
|
+
parent :project, project
|
138
|
+
end
|
139
|
+
|
140
|
+
# Child
|
141
|
+
crumb :issue do |issue|
|
142
|
+
link issue.name, issue_path(issue)
|
143
|
+
parent :project_issues, issue.project
|
144
|
+
end
|
145
|
+
|
146
|
+
# Multiple links per crumb (recursive links for parent categories)
|
147
|
+
crumb :category do |category|
|
148
|
+
parents = [category]
|
149
|
+
|
150
|
+
parent_category = category
|
151
|
+
while parent_category = parent_category.parent_category
|
152
|
+
parents.unshift parent_category
|
153
|
+
end
|
154
|
+
|
155
|
+
parents.each do |category|
|
156
|
+
link category.name, category
|
157
|
+
end
|
158
|
+
|
159
|
+
parent :categories
|
160
|
+
end
|
161
|
+
|
162
|
+
# Product crumb with recursive parent categories
|
163
|
+
crumb :product do |product|
|
164
|
+
link product.name, product
|
165
|
+
parent :category, product.category
|
166
|
+
end
|
167
|
+
|
168
|
+
# Example of using params to alter the parent, e.g. to
|
169
|
+
# match the user's actual navigation path
|
170
|
+
# URL: /products/123?q=my+search
|
171
|
+
crumb :search do |keyword|
|
172
|
+
link "Search for #{keyword}", search_path(:q => keyword)
|
173
|
+
end
|
174
|
+
|
175
|
+
crumb :product do |product|
|
176
|
+
if keyword = params[:q].presence
|
177
|
+
parent :search, keyword
|
178
|
+
else # default
|
179
|
+
parent :category, product.category
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Multiple arguments
|
184
|
+
crumb :multiple_test do |a, b, c|
|
185
|
+
link "Test #{a}, #{b}, #{c}", test_path
|
186
|
+
parent :other_test, 3, 4, 5
|
187
|
+
end
|
188
|
+
|
189
|
+
# Breadcrumb without link URL; will not generate a link
|
190
|
+
crumb :without_link do
|
191
|
+
link "Breadcrumb without link"
|
192
|
+
end
|
193
|
+
|
194
|
+
# Breadcrumb using view helper
|
195
|
+
module UsersHelper
|
196
|
+
def user_name_for(user)
|
197
|
+
user.name
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
crumb :user do |user|
|
202
|
+
link user_name_for(user), user
|
203
|
+
end
|
204
|
+
```
|
205
|
+
|
100
206
|
Building the breadcrumbs manually
|
101
207
|
---------------------------------
|
102
208
|
|
@@ -113,85 +219,21 @@ If you supply a block to the `breadcrumbs` method, it will yield an array with t
|
|
113
219
|
<% end %>
|
114
220
|
```
|
115
221
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
In *config/initializers/breadcrumbs.rb*:
|
120
|
-
|
121
|
-
```ruby
|
122
|
-
Gretel::Crumbs.layout do
|
123
|
-
# Root crumb
|
124
|
-
crumb :root do
|
125
|
-
link "Home", root_path
|
126
|
-
end
|
127
|
-
|
128
|
-
# Regular crumb
|
129
|
-
crumb :projects do
|
130
|
-
link "Projects", projects_path
|
131
|
-
end
|
132
|
-
|
133
|
-
# Parent crumbs
|
134
|
-
crumb :project_issues do |project|
|
135
|
-
link "Issues", project_issues_path(project)
|
136
|
-
parent :project, project
|
137
|
-
end
|
138
|
-
|
139
|
-
# Child
|
140
|
-
crumb :issue do |issue|
|
141
|
-
link issue.name, issue_path(issue)
|
142
|
-
parent :project_issues, issue.project
|
143
|
-
end
|
144
|
-
|
145
|
-
# Multiple links per crumb (recursive links for parent categories)
|
146
|
-
crumb :category do |category|
|
147
|
-
parents = [category]
|
148
|
-
|
149
|
-
parent_category = category
|
150
|
-
while parent_category = parent_category.parent_category
|
151
|
-
parents.unshift parent_category
|
152
|
-
end
|
153
|
-
|
154
|
-
parents.each do |category|
|
155
|
-
link category.name, category
|
156
|
-
end
|
157
|
-
|
158
|
-
parent :categories
|
159
|
-
end
|
160
|
-
|
161
|
-
# Product crumb with recursive parent categories
|
162
|
-
crumb :product do |product|
|
163
|
-
link product.name, product
|
164
|
-
parent :category, product.category
|
165
|
-
end
|
222
|
+
Nice to know
|
223
|
+
------------
|
166
224
|
|
167
|
-
|
168
|
-
crumb :multiple_test do |a, b, c|
|
169
|
-
link "Test #{a}, #{b}, #{c}", test_path
|
170
|
-
parent :other_test, 3, 4, 5
|
171
|
-
end
|
225
|
+
### Access to view helpers
|
172
226
|
|
173
|
-
|
174
|
-
crumb :without_link do
|
175
|
-
link "Breadcrumb without link"
|
176
|
-
end
|
227
|
+
When inside `Gretel::Crumbs.layout do .. end`, you have access to all view helpers of the current view where the breadcrumbs are inserted.
|
177
228
|
|
178
|
-
|
179
|
-
module UsersHelper
|
180
|
-
def user_name_for(user)
|
181
|
-
user.name
|
182
|
-
end
|
183
|
-
end
|
229
|
+
### Using multiple breadcrumb configuration files
|
184
230
|
|
185
|
-
|
186
|
-
|
187
|
-
end
|
188
|
-
end
|
189
|
-
```
|
231
|
+
If you have a large site and you want to split your breadcrumbs configuration over multiple files, you can create a folder named `config/breadcrumbs` and put your configuration files (e.g. `products.rb` or `frontend.rb`) in there.
|
232
|
+
The format is the same as `config/breadcrumbs.rb` which is also loaded.
|
190
233
|
|
191
|
-
|
192
|
-
----------------------
|
234
|
+
### Automatic reloading of breadcrumb configuration files
|
193
235
|
|
194
|
-
|
236
|
+
Since Gretel version 2.1.0, the breadcrumb configuration files are now reloaded in the Rails development environment if they change. In other environments, like production, the files are loaded once, when first needed.
|
195
237
|
|
196
238
|
Documentation
|
197
239
|
-------------
|
@@ -199,6 +241,11 @@ Documentation
|
|
199
241
|
* [Full documentation](http://rubydoc.info/gems/gretel)
|
200
242
|
* [Changelog](https://github.com/lassebunk/gretel/blob/master/CHANGELOG.md)
|
201
243
|
|
244
|
+
Versioning
|
245
|
+
----------
|
246
|
+
|
247
|
+
Follows [semantic versioning](http://semver.org/).
|
248
|
+
|
202
249
|
Contributors
|
203
250
|
------------
|
204
251
|
|
data/gretel.gemspec
CHANGED
@@ -17,6 +17,6 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^test/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
|
-
gem.add_development_dependency "rails", "~> 3.2.
|
20
|
+
gem.add_development_dependency "rails", "~> 3.2.13"
|
21
21
|
gem.add_development_dependency "sqlite3"
|
22
22
|
end
|
data/lib/generators/gretel/USAGE
CHANGED
@@ -4,9 +4,9 @@ module Gretel
|
|
4
4
|
class InstallGenerator < Rails::Generators::Base
|
5
5
|
source_root File.expand_path('../templates', __FILE__)
|
6
6
|
|
7
|
-
desc "Creates
|
8
|
-
def
|
9
|
-
copy_file "
|
7
|
+
desc "Creates a sample configuration file in config/breadcrumbs.rb"
|
8
|
+
def create_config_file
|
9
|
+
copy_file "breadcrumbs.rb", "config/breadcrumbs.rb"
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
crumb :root do
|
2
|
+
link "Home", root_path
|
3
|
+
end
|
4
|
+
|
5
|
+
# crumb :projects do
|
6
|
+
# link "Projects", projects_path
|
7
|
+
# end
|
8
|
+
|
9
|
+
# crumb :project do |project|
|
10
|
+
# link project.name, project_path(project)
|
11
|
+
# parent :projects
|
12
|
+
# end
|
13
|
+
|
14
|
+
# crumb :project_issues do |project|
|
15
|
+
# link "Issues", project_issues_path(project)
|
16
|
+
# parent :project, project
|
17
|
+
# end
|
18
|
+
|
19
|
+
# crumb :issue do |issue|
|
20
|
+
# link issue.title, issue_path(issue)
|
21
|
+
# parent :project_issues, issue.project
|
22
|
+
# end
|
23
|
+
|
24
|
+
# If you want to split your breadcrumbs configuration over multiple files, you
|
25
|
+
# can create a folder named `config/breadcrumbs` and put your configuration
|
26
|
+
# files there. All *.rb files (e.g. `frontend.rb` or `products.rb`) in that
|
27
|
+
# folder are loaded and reloaded automatically when you change them, just like
|
28
|
+
# this file (`config/breadcrumbs.rb`).
|
data/lib/gretel.rb
CHANGED
@@ -3,5 +3,51 @@ require 'gretel/crumbs'
|
|
3
3
|
require 'gretel/crumb'
|
4
4
|
require 'gretel/link'
|
5
5
|
require 'gretel/view_helpers'
|
6
|
+
require 'gretel/deprecated'
|
7
|
+
|
8
|
+
module Gretel
|
9
|
+
class << self
|
10
|
+
# Returns the path from with breadcrumbs are loaded. Default is +config/breadcrumbs.rb+.
|
11
|
+
def breadcrumb_paths
|
12
|
+
@breadcrumb_paths ||= [Rails.root.join("config", "breadcrumbs.rb"), Rails.root.join("config", "breadcrumbs", "**", "*.rb")]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Sets the path from with breadcrumbs are loaded. Default is +config/breadcrumbs.rb+.
|
16
|
+
def breadcrumb_paths=(paths)
|
17
|
+
@breadcrumb_paths = paths
|
18
|
+
end
|
19
|
+
|
20
|
+
# Whether to suppress deprecation warnings.
|
21
|
+
def suppress_deprecation_warnings?
|
22
|
+
!!@suppress_deprecation_warnings
|
23
|
+
end
|
24
|
+
|
25
|
+
# Sets whether to suppress deprecation warnings.
|
26
|
+
def suppress_deprecation_warnings=(value)
|
27
|
+
@suppress_deprecation_warnings = value
|
28
|
+
end
|
29
|
+
|
30
|
+
# Shows a deprecation warning.
|
31
|
+
def show_deprecation_warning(message)
|
32
|
+
return if suppress_deprecation_warnings?
|
33
|
+
puts message
|
34
|
+
Rails.logger.warn message
|
35
|
+
end
|
36
|
+
|
37
|
+
# Array of Rails environment names with automatic configuration reload. Default is +["development"]+.
|
38
|
+
def reload_environments
|
39
|
+
@reload_environments ||= ["development"]
|
40
|
+
end
|
41
|
+
|
42
|
+
# Sets the Rails environment names with automatic configuration reload. Default is +["development"]+.
|
43
|
+
attr_writer :reload_environments
|
44
|
+
|
45
|
+
# Resets all changes made to +Gretel+ and +Gretel::Crumbs+. Used for testing.
|
46
|
+
def reset!
|
47
|
+
instance_variables.each { |var| remove_instance_variable var }
|
48
|
+
Crumbs.reset!
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
6
52
|
|
7
53
|
ActionView::Base.send :include, Gretel::ViewHelpers
|
data/lib/gretel/crumb.rb
CHANGED
data/lib/gretel/crumbs.rb
CHANGED
@@ -1,18 +1,6 @@
|
|
1
1
|
module Gretel
|
2
2
|
module Crumbs
|
3
3
|
class << self
|
4
|
-
# Lay out the breadcrumbs.
|
5
|
-
#
|
6
|
-
# Example:
|
7
|
-
# Gretel::Crumbs.layout do
|
8
|
-
# crumb :root do
|
9
|
-
# link "Home", root_path
|
10
|
-
# end
|
11
|
-
# end
|
12
|
-
def layout(&block)
|
13
|
-
instance_eval &block
|
14
|
-
end
|
15
|
-
|
16
4
|
# Stores the supplied block for later use.
|
17
5
|
def crumb(key, &block)
|
18
6
|
crumbs[key] = block
|
@@ -27,6 +15,56 @@ module Gretel
|
|
27
15
|
def crumb_defined?(key)
|
28
16
|
crumbs.has_key?(key)
|
29
17
|
end
|
18
|
+
|
19
|
+
# Loads the breadcrumb configuration files.
|
20
|
+
def load_breadcrumbs
|
21
|
+
@crumbs = {}
|
22
|
+
|
23
|
+
# Deprecated in v2.1.0.
|
24
|
+
instance_eval &deprecated_breadcrumbs_block
|
25
|
+
|
26
|
+
loaded_file_mtimes.clear
|
27
|
+
breadcrumb_files.each do |file|
|
28
|
+
instance_eval open(file).read, file
|
29
|
+
loaded_file_mtimes << File.mtime(file)
|
30
|
+
end
|
31
|
+
|
32
|
+
@loaded = true
|
33
|
+
end
|
34
|
+
|
35
|
+
# Reloads the breadcrumb configuration files if they have changed.
|
36
|
+
def reload_if_needed
|
37
|
+
load_breadcrumbs if reload?
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns true if a breadcrumbs reload is needed based on configuration file changes.
|
41
|
+
def reload?
|
42
|
+
return true unless loaded?
|
43
|
+
return false unless Gretel.reload_environments.include?(Rails.env)
|
44
|
+
|
45
|
+
loaded_file_mtimes != breadcrumb_files.map { |file| File.mtime(file) }
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns true if the breadcrumb configuration files have been loaded.
|
49
|
+
def loaded?
|
50
|
+
!!@loaded
|
51
|
+
end
|
52
|
+
|
53
|
+
# List of breadcrumb configuration files.
|
54
|
+
def breadcrumb_files
|
55
|
+
Dir[*Gretel.breadcrumb_paths]
|
56
|
+
end
|
57
|
+
|
58
|
+
# Resets all changes made to +Gretel::Crumbs+. Used for testing.
|
59
|
+
def reset!
|
60
|
+
instance_variables.each { |var| remove_instance_variable var }
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def loaded_file_mtimes
|
66
|
+
@loaded_file_mtimes ||= []
|
67
|
+
end
|
30
68
|
end
|
31
69
|
end
|
32
70
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Gretel
|
2
|
+
module Crumbs
|
3
|
+
class << self
|
4
|
+
# Lay out the breadcrumbs.
|
5
|
+
# Deprecated since v2.1.0. Put breadcrumbs in +config/breadcrumbs.rb+ instead (see https://github.com/lassebunk/gretel/blob/master/README.md for details).
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# Gretel::Crumbs.layout do
|
9
|
+
# crumb :root do
|
10
|
+
# link "Home", root_path
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
def layout(&block)
|
14
|
+
Gretel.show_deprecation_warning(
|
15
|
+
"Gretel::Crumbs.layout has been deprecated and will be removed in Gretel version 3.0. " +
|
16
|
+
"Please put your breadcrumbs in `config/breadcrumbs.rb`. " +
|
17
|
+
"This will also automatically reload your breadcrumbs when you change them in the development environment. " +
|
18
|
+
"See https://github.com/lassebunk/gretel/blob/master/README.md for details.")
|
19
|
+
@deprecated_breadcrumbs_block = block
|
20
|
+
end
|
21
|
+
|
22
|
+
def deprecated_breadcrumbs_block
|
23
|
+
@deprecated_breadcrumbs_block ||= Proc.new {}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/gretel/version.rb
CHANGED
data/lib/gretel/view_helpers.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DeprecatedTest < ActionView::TestCase
|
4
|
+
include Gretel::ViewHelpers
|
5
|
+
fixtures :all
|
6
|
+
helper :application
|
7
|
+
|
8
|
+
setup do
|
9
|
+
Gretel.reset!
|
10
|
+
end
|
11
|
+
|
12
|
+
test "deprecated configuration block" do
|
13
|
+
Gretel.suppress_deprecation_warnings = true
|
14
|
+
|
15
|
+
Gretel::Crumbs.layout do
|
16
|
+
crumb :deprecated_parent do
|
17
|
+
link "Test deprecated", root_path
|
18
|
+
end
|
19
|
+
|
20
|
+
crumb :deprecated_child do
|
21
|
+
link "Child", about_path
|
22
|
+
parent :deprecated_parent
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
breadcrumb :deprecated_child
|
27
|
+
assert_equal %{<div class="breadcrumbs"><a href="/">Test deprecated</a> > <span class="current">Child</span></div>},
|
28
|
+
breadcrumbs(:autoroot => false)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
crumb :basic do
|
2
|
+
link "About", about_path
|
3
|
+
end
|
4
|
+
|
5
|
+
crumb :with_root do
|
6
|
+
link "About", about_path
|
7
|
+
parent :root
|
8
|
+
end
|
9
|
+
|
10
|
+
crumb :with_parent do
|
11
|
+
link "Contact", contact_path
|
12
|
+
parent :basic
|
13
|
+
end
|
14
|
+
|
15
|
+
crumb :object do |project|
|
16
|
+
link project.name, project
|
17
|
+
end
|
18
|
+
|
19
|
+
crumb :with_autopath do |project|
|
20
|
+
link project.name, project
|
21
|
+
end
|
22
|
+
|
23
|
+
crumb :with_parent_object do |issue|
|
24
|
+
link issue.title, project_issue_path(issue.project, issue)
|
25
|
+
parent :object, issue.project
|
26
|
+
end
|
27
|
+
|
28
|
+
crumb :multiple_links do
|
29
|
+
link "Contact", contact_path
|
30
|
+
link "Contact form", contact_form_path
|
31
|
+
end
|
32
|
+
|
33
|
+
crumb :multiple_links_with_parent do
|
34
|
+
link "Contact", contact_path
|
35
|
+
link "Contact form", contact_form_path
|
36
|
+
parent :basic
|
37
|
+
end
|
38
|
+
|
39
|
+
crumb :with_proc do
|
40
|
+
link Proc.new { "Name from proc" }, Proc.new { "URL from proc" }
|
41
|
+
end
|
42
|
+
|
43
|
+
crumb :with_multiple_arguments do |a, b, c|
|
44
|
+
link "#{a} and #{b} and #{c}", contact_path
|
45
|
+
parent :parent_with_multiple_arguments, a * 2, b * 2, c * 2
|
46
|
+
end
|
47
|
+
|
48
|
+
crumb :parent_with_multiple_arguments do |d, e, f|
|
49
|
+
link "First #{d} then #{e} then #{f}", about_path
|
50
|
+
end
|
51
|
+
|
52
|
+
crumb :with_unsafe_html do
|
53
|
+
link "Test <strong>bold text</strong>", about_path
|
54
|
+
end
|
55
|
+
|
56
|
+
crumb :with_safe_html do
|
57
|
+
link "Test <strong>bold text</strong>".html_safe, about_path
|
58
|
+
end
|
59
|
+
|
60
|
+
crumb :without_link do
|
61
|
+
link "Without link"
|
62
|
+
parent :parent_without_link
|
63
|
+
end
|
64
|
+
|
65
|
+
crumb :parent_without_link do
|
66
|
+
link "Also without link"
|
67
|
+
end
|
68
|
+
|
69
|
+
crumb :using_view_helper do
|
70
|
+
link times_two("Test"), about_path
|
71
|
+
end
|
data/test/gretel_test.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class GretelTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
Gretel.reset!
|
6
|
+
end
|
7
|
+
|
8
|
+
test "defaults" do
|
9
|
+
assert_equal [Rails.root.join("config", "breadcrumbs.rb"), Rails.root.join("config", "breadcrumbs", "**", "*.rb")],
|
10
|
+
Gretel.breadcrumb_paths
|
11
|
+
assert_equal ["development"], Gretel.reload_environments
|
12
|
+
assert !Gretel.suppress_deprecation_warnings?
|
13
|
+
end
|
14
|
+
end
|
data/test/helper_methods_test.rb
CHANGED
@@ -5,6 +5,10 @@ class HelperMethodsTest < ActionView::TestCase
|
|
5
5
|
fixtures :all
|
6
6
|
helper :application
|
7
7
|
|
8
|
+
setup do
|
9
|
+
Gretel.reset!
|
10
|
+
end
|
11
|
+
|
8
12
|
test "shows basic breadcrumb" do
|
9
13
|
breadcrumb :basic
|
10
14
|
assert_equal %{<div class="breadcrumbs"><a href="/">Home</a> > <span class="current">About</span></div>},
|
@@ -137,9 +141,8 @@ class HelperMethodsTest < ActionView::TestCase
|
|
137
141
|
test "yields a block containing breadcrumb links array" do
|
138
142
|
breadcrumb :multiple_links_with_parent
|
139
143
|
|
140
|
-
out =
|
141
|
-
|
142
|
-
out = links.map { |link| [link.key, link.text, link.url] }
|
144
|
+
out = breadcrumbs do |links|
|
145
|
+
links.map { |link| [link.key, link.text, link.url] }
|
143
146
|
end
|
144
147
|
|
145
148
|
assert_equal [[:root, "Home", "/"],
|
@@ -173,4 +176,154 @@ class HelperMethodsTest < ActionView::TestCase
|
|
173
176
|
breadcrumbs
|
174
177
|
end
|
175
178
|
end
|
179
|
+
|
180
|
+
test "reload configuration when file is changed" do
|
181
|
+
path = setup_loading_from_tmp_folder
|
182
|
+
Gretel.reload_environments << "test"
|
183
|
+
|
184
|
+
File.open(path.join("site.rb"), "w") do |f|
|
185
|
+
f.write <<-EOT
|
186
|
+
crumb :root do
|
187
|
+
link "Home (loaded)", root_path
|
188
|
+
end
|
189
|
+
crumb :about do
|
190
|
+
link "About (loaded)", about_path
|
191
|
+
end
|
192
|
+
EOT
|
193
|
+
end
|
194
|
+
|
195
|
+
breadcrumb :about
|
196
|
+
assert_equal %{<div class="breadcrumbs"><a href="/">Home (loaded)</a> > <span class="current">About (loaded)</span></div>}, breadcrumbs
|
197
|
+
|
198
|
+
sleep 1 # File change interval is 1 second
|
199
|
+
|
200
|
+
File.open(path.join("site.rb"), "w") do |f|
|
201
|
+
f.write <<-EOT
|
202
|
+
crumb :root do
|
203
|
+
link "Home (reloaded)", "/test"
|
204
|
+
end
|
205
|
+
crumb :about do
|
206
|
+
link "About (reloaded)", "/reloaded"
|
207
|
+
end
|
208
|
+
EOT
|
209
|
+
end
|
210
|
+
|
211
|
+
breadcrumb :about
|
212
|
+
assert_equal %{<div class="breadcrumbs"><a href="/test">Home (reloaded)</a> > <span class="current">About (reloaded)</span></div>}, breadcrumbs
|
213
|
+
end
|
214
|
+
|
215
|
+
test "reload configuration when file is added" do
|
216
|
+
path = setup_loading_from_tmp_folder
|
217
|
+
Gretel.reload_environments << "test"
|
218
|
+
|
219
|
+
File.open(path.join("site.rb"), "w") do |f|
|
220
|
+
f.write <<-EOT
|
221
|
+
crumb :root do
|
222
|
+
link "Home (loaded)", root_path
|
223
|
+
end
|
224
|
+
EOT
|
225
|
+
end
|
226
|
+
|
227
|
+
assert_raises ArgumentError do
|
228
|
+
breadcrumb :about
|
229
|
+
breadcrumbs
|
230
|
+
end
|
231
|
+
|
232
|
+
File.open(path.join("pages.rb"), "w") do |f|
|
233
|
+
f.write <<-EOT
|
234
|
+
crumb :about do
|
235
|
+
link "About (loaded)", about_path
|
236
|
+
end
|
237
|
+
EOT
|
238
|
+
end
|
239
|
+
|
240
|
+
breadcrumb :about
|
241
|
+
assert_equal %{<div class="breadcrumbs"><a href="/">Home (loaded)</a> > <span class="current">About (loaded)</span></div>}, breadcrumbs
|
242
|
+
end
|
243
|
+
|
244
|
+
test "reload configuration when file is deleted" do
|
245
|
+
path = setup_loading_from_tmp_folder
|
246
|
+
Gretel.reload_environments << "test"
|
247
|
+
|
248
|
+
File.open(path.join("site.rb"), "w") do |f|
|
249
|
+
f.write <<-EOT
|
250
|
+
crumb :root do
|
251
|
+
link "Home (loaded)", root_path
|
252
|
+
end
|
253
|
+
crumb :about do
|
254
|
+
link "About (loaded)", about_path
|
255
|
+
end
|
256
|
+
EOT
|
257
|
+
end
|
258
|
+
|
259
|
+
File.open(path.join("pages.rb"), "w") do |f|
|
260
|
+
f.write <<-EOT
|
261
|
+
crumb :contact do
|
262
|
+
link "Contact (loaded)", "/contact"
|
263
|
+
parent :about
|
264
|
+
end
|
265
|
+
EOT
|
266
|
+
end
|
267
|
+
|
268
|
+
breadcrumb :contact
|
269
|
+
assert_equal %{<div class="breadcrumbs"><a href="/">Home (loaded)</a> > <a href="/about">About (loaded)</a> > <span class="current">Contact (loaded)</span></div>}, breadcrumbs
|
270
|
+
|
271
|
+
File.delete path.join("pages.rb")
|
272
|
+
|
273
|
+
assert_raises ArgumentError do
|
274
|
+
breadcrumb :contact
|
275
|
+
breadcrumbs
|
276
|
+
end
|
277
|
+
|
278
|
+
breadcrumb :about
|
279
|
+
assert_equal %{<div class="breadcrumbs"><a href="/">Home (loaded)</a> > <span class="current">About (loaded)</span></div>}, breadcrumbs
|
280
|
+
end
|
281
|
+
|
282
|
+
test "reloads only in development environment" do
|
283
|
+
path = setup_loading_from_tmp_folder
|
284
|
+
|
285
|
+
assert_equal ["development"], Gretel.reload_environments
|
286
|
+
|
287
|
+
File.open(path.join("site.rb"), "w") do |f|
|
288
|
+
f.write <<-EOT
|
289
|
+
crumb :root do
|
290
|
+
link "Home (loaded)", root_path
|
291
|
+
end
|
292
|
+
crumb :about do
|
293
|
+
link "About (loaded)", about_path
|
294
|
+
end
|
295
|
+
EOT
|
296
|
+
end
|
297
|
+
|
298
|
+
breadcrumb :about
|
299
|
+
assert_equal %{<div class="breadcrumbs"><a href="/">Home (loaded)</a> > <span class="current">About (loaded)</span></div>}, breadcrumbs
|
300
|
+
|
301
|
+
sleep 1
|
302
|
+
|
303
|
+
File.open(path.join("site.rb"), "w") do |f|
|
304
|
+
f.write <<-EOT
|
305
|
+
crumb :root do
|
306
|
+
link "Home (reloaded)", "/test"
|
307
|
+
end
|
308
|
+
crumb :about do
|
309
|
+
link "About (reloaded)", "/reloaded"
|
310
|
+
end
|
311
|
+
EOT
|
312
|
+
end
|
313
|
+
|
314
|
+
breadcrumb :about
|
315
|
+
assert_equal %{<div class="breadcrumbs"><a href="/">Home (loaded)</a> > <span class="current">About (loaded)</span></div>}, breadcrumbs
|
316
|
+
end
|
317
|
+
|
318
|
+
private
|
319
|
+
|
320
|
+
def setup_loading_from_tmp_folder
|
321
|
+
path = Rails.root.join("tmp", "testcrumbs")
|
322
|
+
FileUtils.rm_rf path
|
323
|
+
FileUtils.mkdir_p path
|
324
|
+
|
325
|
+
Gretel.breadcrumb_paths = [path.join("*.rb")]
|
326
|
+
|
327
|
+
path
|
328
|
+
end
|
176
329
|
end
|
metadata
CHANGED
@@ -1,46 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gretel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
5
|
-
prerelease:
|
4
|
+
version: 2.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Lasse Bunk
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-07-23 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rails
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version: 3.2.
|
19
|
+
version: 3.2.13
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: 3.2.
|
26
|
+
version: 3.2.13
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: sqlite3
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
description: Gretel is a Ruby on Rails plugin that makes it easy yet flexible to create
|
@@ -55,21 +50,21 @@ files:
|
|
55
50
|
- .travis.yml
|
56
51
|
- CHANGELOG.md
|
57
52
|
- Gemfile
|
58
|
-
- Gemfile.lock
|
59
53
|
- LICENSE.txt
|
60
54
|
- README.md
|
61
55
|
- Rakefile
|
62
56
|
- gretel.gemspec
|
63
57
|
- lib/generators/gretel/USAGE
|
64
|
-
- lib/generators/gretel/gretel_generator.rb
|
65
58
|
- lib/generators/gretel/install_generator.rb
|
66
|
-
- lib/generators/gretel/templates/
|
59
|
+
- lib/generators/gretel/templates/breadcrumbs.rb
|
67
60
|
- lib/gretel.rb
|
68
61
|
- lib/gretel/crumb.rb
|
69
62
|
- lib/gretel/crumbs.rb
|
63
|
+
- lib/gretel/deprecated.rb
|
70
64
|
- lib/gretel/link.rb
|
71
65
|
- lib/gretel/version.rb
|
72
66
|
- lib/gretel/view_helpers.rb
|
67
|
+
- test/deprecated_test.rb
|
73
68
|
- test/dummy/Rakefile
|
74
69
|
- test/dummy/app/assets/javascripts/application.js
|
75
70
|
- test/dummy/app/assets/stylesheets/application.css
|
@@ -82,13 +77,14 @@ files:
|
|
82
77
|
- test/dummy/config.ru
|
83
78
|
- test/dummy/config/application.rb
|
84
79
|
- test/dummy/config/boot.rb
|
80
|
+
- test/dummy/config/breadcrumbs.rb
|
81
|
+
- test/dummy/config/breadcrumbs/test_crumbs.rb
|
85
82
|
- test/dummy/config/database.yml
|
86
83
|
- test/dummy/config/environment.rb
|
87
84
|
- test/dummy/config/environments/development.rb
|
88
85
|
- test/dummy/config/environments/production.rb
|
89
86
|
- test/dummy/config/environments/test.rb
|
90
87
|
- test/dummy/config/initializers/backtrace_silencers.rb
|
91
|
-
- test/dummy/config/initializers/breadcrumbs.rb
|
92
88
|
- test/dummy/config/initializers/inflections.rb
|
93
89
|
- test/dummy/config/initializers/mime_types.rb
|
94
90
|
- test/dummy/config/initializers/secret_token.rb
|
@@ -108,40 +104,35 @@ files:
|
|
108
104
|
- test/dummy/script/rails
|
109
105
|
- test/fixtures/issues.yml
|
110
106
|
- test/fixtures/projects.yml
|
107
|
+
- test/gretel_test.rb
|
111
108
|
- test/helper_methods_test.rb
|
112
109
|
- test/test_helper.rb
|
113
110
|
homepage: http://github.com/lassebunk/gretel
|
114
111
|
licenses:
|
115
112
|
- MIT
|
113
|
+
metadata: {}
|
116
114
|
post_install_message:
|
117
115
|
rdoc_options: []
|
118
116
|
require_paths:
|
119
117
|
- lib
|
120
118
|
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
119
|
requirements:
|
123
|
-
- -
|
120
|
+
- - '>='
|
124
121
|
- !ruby/object:Gem::Version
|
125
122
|
version: '0'
|
126
|
-
segments:
|
127
|
-
- 0
|
128
|
-
hash: -3983291336719230651
|
129
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
-
none: false
|
131
124
|
requirements:
|
132
|
-
- -
|
125
|
+
- - '>='
|
133
126
|
- !ruby/object:Gem::Version
|
134
127
|
version: '0'
|
135
|
-
segments:
|
136
|
-
- 0
|
137
|
-
hash: -3983291336719230651
|
138
128
|
requirements: []
|
139
129
|
rubyforge_project:
|
140
|
-
rubygems_version:
|
130
|
+
rubygems_version: 2.0.3
|
141
131
|
signing_key:
|
142
|
-
specification_version:
|
132
|
+
specification_version: 4
|
143
133
|
summary: Flexible Ruby on Rails breadcrumbs plugin.
|
144
134
|
test_files:
|
135
|
+
- test/deprecated_test.rb
|
145
136
|
- test/dummy/Rakefile
|
146
137
|
- test/dummy/app/assets/javascripts/application.js
|
147
138
|
- test/dummy/app/assets/stylesheets/application.css
|
@@ -154,13 +145,14 @@ test_files:
|
|
154
145
|
- test/dummy/config.ru
|
155
146
|
- test/dummy/config/application.rb
|
156
147
|
- test/dummy/config/boot.rb
|
148
|
+
- test/dummy/config/breadcrumbs.rb
|
149
|
+
- test/dummy/config/breadcrumbs/test_crumbs.rb
|
157
150
|
- test/dummy/config/database.yml
|
158
151
|
- test/dummy/config/environment.rb
|
159
152
|
- test/dummy/config/environments/development.rb
|
160
153
|
- test/dummy/config/environments/production.rb
|
161
154
|
- test/dummy/config/environments/test.rb
|
162
155
|
- test/dummy/config/initializers/backtrace_silencers.rb
|
163
|
-
- test/dummy/config/initializers/breadcrumbs.rb
|
164
156
|
- test/dummy/config/initializers/inflections.rb
|
165
157
|
- test/dummy/config/initializers/mime_types.rb
|
166
158
|
- test/dummy/config/initializers/secret_token.rb
|
@@ -180,5 +172,6 @@ test_files:
|
|
180
172
|
- test/dummy/script/rails
|
181
173
|
- test/fixtures/issues.yml
|
182
174
|
- test/fixtures/projects.yml
|
175
|
+
- test/gretel_test.rb
|
183
176
|
- test/helper_methods_test.rb
|
184
177
|
- test/test_helper.rb
|
@@ -1,10 +0,0 @@
|
|
1
|
-
module Gretel
|
2
|
-
class InstallGenerator < Rails::Generators::Base
|
3
|
-
source_root File.expand_path('../templates', __FILE__)
|
4
|
-
|
5
|
-
desc "Creates an initializer for breadcrumbs in config/initializers/breadcrumbs.rb"
|
6
|
-
def create_initializer
|
7
|
-
copy_file "initializer.rb", "config/initializers/breadcrumbs.rb"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# Remember to restart your application after editing this file.
|
2
|
-
|
3
|
-
Gretel::Crumbs.layout do
|
4
|
-
# Example crumbs:
|
5
|
-
|
6
|
-
# crumb :root do
|
7
|
-
# link "Home", root_path
|
8
|
-
# end
|
9
|
-
|
10
|
-
# crumb :projects do
|
11
|
-
# link "Projects", projects_path
|
12
|
-
# end
|
13
|
-
|
14
|
-
# crumb :project do |project|
|
15
|
-
# link lambda { |project| "#{project.name} (#{project.id.to_s})" }, project_path(project)
|
16
|
-
# parent :projects
|
17
|
-
# end
|
18
|
-
|
19
|
-
# crumb :project_issues do |project|
|
20
|
-
# link "Issues", project_issues_path(project)
|
21
|
-
# parent :project, project
|
22
|
-
# end
|
23
|
-
|
24
|
-
# crumb :issue do |issue|
|
25
|
-
# link issue.name, issue_path(issue)
|
26
|
-
# parent :project_issues, issue.project
|
27
|
-
# end
|
28
|
-
|
29
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
Gretel::Crumbs.layout do
|
2
|
-
crumb :root do
|
3
|
-
link "Home", root_path
|
4
|
-
end
|
5
|
-
|
6
|
-
crumb :basic do
|
7
|
-
link "About", about_path
|
8
|
-
end
|
9
|
-
|
10
|
-
crumb :with_root do
|
11
|
-
link "About", about_path
|
12
|
-
parent :root
|
13
|
-
end
|
14
|
-
|
15
|
-
crumb :with_parent do
|
16
|
-
link "Contact", contact_path
|
17
|
-
parent :basic
|
18
|
-
end
|
19
|
-
|
20
|
-
crumb :object do |project|
|
21
|
-
link project.name, project
|
22
|
-
end
|
23
|
-
|
24
|
-
crumb :with_autopath do |project|
|
25
|
-
link project.name, project
|
26
|
-
end
|
27
|
-
|
28
|
-
crumb :with_parent_object do |issue|
|
29
|
-
link issue.title, project_issue_path(issue.project, issue)
|
30
|
-
parent :object, issue.project
|
31
|
-
end
|
32
|
-
|
33
|
-
crumb :multiple_links do
|
34
|
-
link "Contact", contact_path
|
35
|
-
link "Contact form", contact_form_path
|
36
|
-
end
|
37
|
-
|
38
|
-
crumb :multiple_links_with_parent do
|
39
|
-
link "Contact", contact_path
|
40
|
-
link "Contact form", contact_form_path
|
41
|
-
parent :basic
|
42
|
-
end
|
43
|
-
|
44
|
-
crumb :with_proc do
|
45
|
-
link Proc.new { "Name from proc" }, Proc.new { "URL from proc" }
|
46
|
-
end
|
47
|
-
|
48
|
-
crumb :with_multiple_arguments do |a, b, c|
|
49
|
-
link "#{a} and #{b} and #{c}", contact_path
|
50
|
-
parent :parent_with_multiple_arguments, a * 2, b * 2, c * 2
|
51
|
-
end
|
52
|
-
|
53
|
-
crumb :parent_with_multiple_arguments do |d, e, f|
|
54
|
-
link "First #{d} then #{e} then #{f}", about_path
|
55
|
-
end
|
56
|
-
|
57
|
-
crumb :with_unsafe_html do
|
58
|
-
link "Test <strong>bold text</strong>", about_path
|
59
|
-
end
|
60
|
-
|
61
|
-
crumb :with_safe_html do
|
62
|
-
link "Test <strong>bold text</strong>".html_safe, about_path
|
63
|
-
end
|
64
|
-
|
65
|
-
crumb :without_link do
|
66
|
-
link "Without link"
|
67
|
-
parent :parent_without_link
|
68
|
-
end
|
69
|
-
|
70
|
-
crumb :parent_without_link do
|
71
|
-
link "Also without link"
|
72
|
-
end
|
73
|
-
|
74
|
-
crumb :using_view_helper do
|
75
|
-
link times_two("Test"), about_path
|
76
|
-
end
|
77
|
-
end
|