breadcrumb_trail 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +3 -0
- data/.travis.yml +11 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +142 -0
- data/LICENSE.txt +22 -0
- data/README.md +136 -0
- data/Rakefile +28 -0
- data/breadcrumb_trail.gemspec +30 -0
- data/lib/breadcrumb_trail/action_controller.rb +79 -0
- data/lib/breadcrumb_trail/breadcrumb.rb +95 -0
- data/lib/breadcrumb_trail/builder.rb +98 -0
- data/lib/breadcrumb_trail/railtie.rb +11 -0
- data/lib/breadcrumb_trail/version.rb +5 -0
- data/lib/breadcrumb_trail.rb +10 -0
- data/lib/tasks/breadcrumb_trail_tasks.rake +4 -0
- data/spec/block_builder_spec.rb +19 -0
- data/spec/breadcrumb_spec.rb +93 -0
- data/spec/builder_spec.rb +16 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +7 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/welcome_controller.rb +11 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +11 -0
- data/spec/dummy/app/views/welcome/hello.html.erb +4 -0
- data/spec/dummy/app/views/welcome/index.html.erb +2 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +21 -0
- data/spec/dummy/config/application.rb +28 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/html_builder_spec.rb +62 -0
- data/spec/integration/application_breadcrumbs_spec.rb +46 -0
- data/spec/spec_helper.rb +10 -0
- metadata +235 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6d8214c00eb8560928ec5a0e2b977abb28a21a13
|
4
|
+
data.tar.gz: 4484fad9e6f341e0779cc8abdf334a9554fb1e9f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5c2caf6f7ccabf9ad5d60ca820044f20f948e8a7a9eda77fbff66c25a3af49dfa751d6cffe62dee52125afbeacfa1d56bddbbbbd7829566e59b47ff21f010e2c
|
7
|
+
data.tar.gz: faa2216d0e9f9aeda187e95912222fe9de9610e5967cc7854d3ebf36e4c9dd86de2d3bd434b22335c13b17b2c321fa8feb60ba6460ada3c8f048838ced21fc60
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
breadcrumb_trail (0.1.0)
|
5
|
+
rails (>= 3.0, < 5)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
actionmailer (4.2.0)
|
11
|
+
actionpack (= 4.2.0)
|
12
|
+
actionview (= 4.2.0)
|
13
|
+
activejob (= 4.2.0)
|
14
|
+
mail (~> 2.5, >= 2.5.4)
|
15
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
16
|
+
actionpack (4.2.0)
|
17
|
+
actionview (= 4.2.0)
|
18
|
+
activesupport (= 4.2.0)
|
19
|
+
rack (~> 1.6.0)
|
20
|
+
rack-test (~> 0.6.2)
|
21
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
22
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.1)
|
23
|
+
actionview (4.2.0)
|
24
|
+
activesupport (= 4.2.0)
|
25
|
+
builder (~> 3.1)
|
26
|
+
erubis (~> 2.7.0)
|
27
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
28
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.1)
|
29
|
+
activejob (4.2.0)
|
30
|
+
activesupport (= 4.2.0)
|
31
|
+
globalid (>= 0.3.0)
|
32
|
+
activemodel (4.2.0)
|
33
|
+
activesupport (= 4.2.0)
|
34
|
+
builder (~> 3.1)
|
35
|
+
activerecord (4.2.0)
|
36
|
+
activemodel (= 4.2.0)
|
37
|
+
activesupport (= 4.2.0)
|
38
|
+
arel (~> 6.0)
|
39
|
+
activesupport (4.2.0)
|
40
|
+
i18n (~> 0.7)
|
41
|
+
json (~> 1.7, >= 1.7.7)
|
42
|
+
minitest (~> 5.1)
|
43
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
44
|
+
tzinfo (~> 1.1)
|
45
|
+
arel (6.0.0)
|
46
|
+
builder (3.2.2)
|
47
|
+
codeclimate-test-reporter (0.4.6)
|
48
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
49
|
+
diff-lcs (1.2.5)
|
50
|
+
docile (1.1.5)
|
51
|
+
erubis (2.7.0)
|
52
|
+
globalid (0.3.3)
|
53
|
+
activesupport (>= 4.1.0)
|
54
|
+
hike (1.2.3)
|
55
|
+
i18n (0.7.0)
|
56
|
+
json (1.8.2)
|
57
|
+
loofah (2.0.1)
|
58
|
+
nokogiri (>= 1.5.9)
|
59
|
+
mail (2.6.3)
|
60
|
+
mime-types (>= 1.16, < 3)
|
61
|
+
mime-types (2.4.3)
|
62
|
+
mini_portile (0.6.2)
|
63
|
+
minitest (5.5.1)
|
64
|
+
multi_json (1.10.1)
|
65
|
+
nokogiri (1.6.6.2)
|
66
|
+
mini_portile (~> 0.6.0)
|
67
|
+
rack (1.6.0)
|
68
|
+
rack-test (0.6.3)
|
69
|
+
rack (>= 1.0)
|
70
|
+
rails (4.2.0)
|
71
|
+
actionmailer (= 4.2.0)
|
72
|
+
actionpack (= 4.2.0)
|
73
|
+
actionview (= 4.2.0)
|
74
|
+
activejob (= 4.2.0)
|
75
|
+
activemodel (= 4.2.0)
|
76
|
+
activerecord (= 4.2.0)
|
77
|
+
activesupport (= 4.2.0)
|
78
|
+
bundler (>= 1.3.0, < 2.0)
|
79
|
+
railties (= 4.2.0)
|
80
|
+
sprockets-rails
|
81
|
+
rails-deprecated_sanitizer (1.0.3)
|
82
|
+
activesupport (>= 4.2.0.alpha)
|
83
|
+
rails-dom-testing (1.0.5)
|
84
|
+
activesupport (>= 4.2.0.beta, < 5.0)
|
85
|
+
nokogiri (~> 1.6.0)
|
86
|
+
rails-deprecated_sanitizer (>= 1.0.1)
|
87
|
+
rails-html-sanitizer (1.0.1)
|
88
|
+
loofah (~> 2.0)
|
89
|
+
railties (4.2.0)
|
90
|
+
actionpack (= 4.2.0)
|
91
|
+
activesupport (= 4.2.0)
|
92
|
+
rake (>= 0.8.7)
|
93
|
+
thor (>= 0.18.1, < 2.0)
|
94
|
+
rake (10.4.2)
|
95
|
+
rspec-core (3.2.0)
|
96
|
+
rspec-support (~> 3.2.0)
|
97
|
+
rspec-expectations (3.2.0)
|
98
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
99
|
+
rspec-support (~> 3.2.0)
|
100
|
+
rspec-mocks (3.2.0)
|
101
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
102
|
+
rspec-support (~> 3.2.0)
|
103
|
+
rspec-rails (3.2.0)
|
104
|
+
actionpack (>= 3.0, <= 4.2)
|
105
|
+
activesupport (>= 3.0, <= 4.2)
|
106
|
+
railties (>= 3.0, <= 4.2)
|
107
|
+
rspec-core (~> 3.2.0)
|
108
|
+
rspec-expectations (~> 3.2.0)
|
109
|
+
rspec-mocks (~> 3.2.0)
|
110
|
+
rspec-support (~> 3.2.0)
|
111
|
+
rspec-support (3.2.1)
|
112
|
+
simplecov (0.9.1)
|
113
|
+
docile (~> 1.1.0)
|
114
|
+
multi_json (~> 1.0)
|
115
|
+
simplecov-html (~> 0.8.0)
|
116
|
+
simplecov-html (0.8.0)
|
117
|
+
sprockets (2.12.3)
|
118
|
+
hike (~> 1.2)
|
119
|
+
multi_json (~> 1.0)
|
120
|
+
rack (~> 1.0)
|
121
|
+
tilt (~> 1.1, != 1.3.0)
|
122
|
+
sprockets-rails (2.2.4)
|
123
|
+
actionpack (>= 3.0)
|
124
|
+
activesupport (>= 3.0)
|
125
|
+
sprockets (>= 2.8, < 4.0)
|
126
|
+
thor (0.19.1)
|
127
|
+
thread_safe (0.3.4)
|
128
|
+
tilt (1.4.1)
|
129
|
+
tzinfo (1.2.2)
|
130
|
+
thread_safe (~> 0.1)
|
131
|
+
yard (0.8.7.6)
|
132
|
+
|
133
|
+
PLATFORMS
|
134
|
+
ruby
|
135
|
+
|
136
|
+
DEPENDENCIES
|
137
|
+
breadcrumb_trail!
|
138
|
+
bundler (~> 1.7)
|
139
|
+
codeclimate-test-reporter
|
140
|
+
rake (~> 10.0)
|
141
|
+
rspec-rails (~> 3.0)
|
142
|
+
yard
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Jeremy Rodi
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
# Breadcrumb Trail
|
2
|
+
[](https://codeclimate.com/github/medcat/breadcrumb_trail) [](https://travis-ci.org/medcat/breadcrumb_trail) [](https://codeclimate.com/github/medcat/breadcrumb_trail)
|
3
|
+
|
4
|
+
Helps you create a breadcrumb system for your Rails application.
|
5
|
+
Better than any other library, guarenteed<sup>*</sup>.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'breadcrumb_trail'
|
13
|
+
```
|
14
|
+
|
15
|
+
And you're done!
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
The gem adds some nice methods to your controller:
|
20
|
+
|
21
|
+
```Ruby
|
22
|
+
# app/controllers/application_controller.rb
|
23
|
+
class ApplicationController < ActionController::Base
|
24
|
+
|
25
|
+
breadcrumb name: "Home", path: :root_path
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
```Ruby
|
30
|
+
# app/controllers/articles_controller.rb
|
31
|
+
class ArticlesController < ApplicationController
|
32
|
+
breadcrumb name: "Articles", path: :articles_path
|
33
|
+
|
34
|
+
def show
|
35
|
+
@article = Article.find(params[:id])
|
36
|
+
breadcrumb name: @article.name, path: article_path(@article)
|
37
|
+
breadcrumbs # => returns all of your breadcrumbs
|
38
|
+
end
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
```HTML
|
43
|
+
<!-- app/views/layouts/application.html.erb -->
|
44
|
+
<!-- ... -->
|
45
|
+
<%= render_breadcrumbs outer: "ul" %>
|
46
|
+
<!-- ... -->
|
47
|
+
```
|
48
|
+
|
49
|
+
...all results in _(with some assumptions)_:
|
50
|
+
|
51
|
+
```HTML
|
52
|
+
<!-- ... -->
|
53
|
+
<ul>
|
54
|
+
<li><a href="/">Home</a></li>
|
55
|
+
<li><a href="/articles">Articles</a></li>
|
56
|
+
<li><a href="/articles/1">Hello, World</a></li>
|
57
|
+
</ul>
|
58
|
+
<!-- ... -->
|
59
|
+
```
|
60
|
+
|
61
|
+
You can pass `#breadcrumb` some options, which it'll use as
|
62
|
+
HTML options by default.
|
63
|
+
|
64
|
+
Simple, right?
|
65
|
+
|
66
|
+
### Builders
|
67
|
+
|
68
|
+
`#render_breadcrumbs` takes an option for a builder, or defaults to
|
69
|
+
one if you don't provide it. There are two default builders:
|
70
|
+
`HTMLBuilder` and `BlockBuilder`. If you provide a block to
|
71
|
+
`#render_breadcrumbs`, then `BlockBuilder` is used; otherwise,
|
72
|
+
`HTMLBuilder` is used.
|
73
|
+
|
74
|
+
#### `HTMLBuilder`
|
75
|
+
|
76
|
+
`HTMLBuilder` builds a sensible block of HTML based on some options.
|
77
|
+
The exact options you can provide are:
|
78
|
+
|
79
|
+
- `outer`: The outer tag that is used. The default for this is `ol`.
|
80
|
+
If this is `nil`, then no outer tag is rendered.
|
81
|
+
- `inner`: The inner tag that is used. The default for this is `li`.
|
82
|
+
If this is `nil`, then no inner tag is rendered.
|
83
|
+
- `outer_options`: The html attributes that are used for the outer
|
84
|
+
tag. By default, there are no options. If you want to add
|
85
|
+
`class="some-class"`, this is the place to provide it.
|
86
|
+
- `inner_options`: The html attributes that are used for the inner
|
87
|
+
tag. By default, there are no options. If you want to add
|
88
|
+
`class="some-class"`, this is the place to provide it.
|
89
|
+
|
90
|
+
That's it!
|
91
|
+
|
92
|
+
#### `BlockBuilder`
|
93
|
+
|
94
|
+
`BlockBuilder` yields each breadcrumb to the given block. Each
|
95
|
+
breadcrumb has three attributes: `name`, `path`, and `options`.
|
96
|
+
To recreate the default output of `HTMLBuilder`, you'd have to do
|
97
|
+
this with `BlockBuilder`:
|
98
|
+
|
99
|
+
```
|
100
|
+
<!-- ... -->
|
101
|
+
<ol>
|
102
|
+
<%= render_breadcrumbs do |breadcrumb| %>
|
103
|
+
<li><%= link_to(breadcrumb.name, breadcrumb.path, breadcrumb.options) %></li>
|
104
|
+
<%= end %>
|
105
|
+
</ol>
|
106
|
+
<!-- ... -->
|
107
|
+
```
|
108
|
+
|
109
|
+
#### Your Own Builder
|
110
|
+
|
111
|
+
You don't have to use one of these. You can use your own builder.
|
112
|
+
However, if you're using a builder because the default builders don't
|
113
|
+
provide a feature you like, open an issue!
|
114
|
+
|
115
|
+
Your builder only needs to subclass `BreadcrumbTrail::Builder` and
|
116
|
+
define the method `#call`, and that's it! Then, you pass the builder
|
117
|
+
to `#render_breadcrumbs` with the `builder` option:
|
118
|
+
|
119
|
+
```
|
120
|
+
<!-- ... -->
|
121
|
+
<%= render_breadcrumbs builder: MyCustomBuilder %>
|
122
|
+
<!-- ... -->
|
123
|
+
```
|
124
|
+
|
125
|
+
Any options passed to `#render_breadcrumbs` are passed to your
|
126
|
+
builder's `#initialize` via the last argument.
|
127
|
+
|
128
|
+
## Contributing
|
129
|
+
|
130
|
+
1. Fork it (<https://github.com/medcat/breadcrumb_trail/fork>)
|
131
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
132
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
133
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
134
|
+
5. Create a new Pull Request
|
135
|
+
|
136
|
+
<sup>*</sup>: Not guarenteed.
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'BreadcrumbTrail'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
Bundler::GemHelper.install_tasks
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'lib'
|
23
|
+
t.libs << 'test'
|
24
|
+
t.pattern = 'test/**/*_test.rb'
|
25
|
+
t.verbose = false
|
26
|
+
end
|
27
|
+
|
28
|
+
task default: :test
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'breadcrumb_trail/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "breadcrumb_trail"
|
8
|
+
spec.version = BreadcrumbTrail::VERSION
|
9
|
+
spec.authors = ["Jeremy Rodi"]
|
10
|
+
spec.email = ["redjazz96@gmail.com"]
|
11
|
+
spec.summary = %q{A basic breadcrumb trail plugin.}
|
12
|
+
spec.description = %q{A breadcrumb trail plugin that provides shortcuts to make your life easier.}
|
13
|
+
spec.homepage = "https://github.com/medcat/breadcrumb_trail"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec-rails", "~> 3.0"
|
24
|
+
spec.add_development_dependency "yard"
|
25
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
26
|
+
|
27
|
+
# I don't know what 5 will be like...
|
28
|
+
spec.add_dependency "rails", ">= 3.0", "< 5"
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module BreadcrumbTrail
|
2
|
+
|
3
|
+
# A module to extend Controllers with. It provides the main methods
|
4
|
+
# that are used within the application, namely `breadcrumbs` and
|
5
|
+
# `render_breadcrumbs`.
|
6
|
+
module ActionController
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
include HelperMethods
|
11
|
+
helper HelperMethods
|
12
|
+
helper_method :breadcrumb, :breadcrumbs
|
13
|
+
end
|
14
|
+
|
15
|
+
# This extends a controller, providing the `breadcrumb` method to
|
16
|
+
# the class as a method.
|
17
|
+
module ClassMethods
|
18
|
+
|
19
|
+
# Creates a before action that defines a breadcrumb before the
|
20
|
+
# action takes place. See {HelperMethods#breadcrumb}.
|
21
|
+
#
|
22
|
+
# @param (see HelperMethods#breadcrumb)
|
23
|
+
# @return [void]
|
24
|
+
def breadcrumb(options, &block)
|
25
|
+
before_action(options.delete(:action) || {}) do
|
26
|
+
breadcrumb(options, &block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# This is both included in the controller and used as a helper,
|
32
|
+
# so any methods defined here are usable in both the controller
|
33
|
+
# and in the views. These methods are the primary interface
|
34
|
+
# that the developer uses to define and render breadcrumbs.
|
35
|
+
module HelperMethods
|
36
|
+
|
37
|
+
# Define a breadcrumb with the given options. All of this
|
38
|
+
# information is passed directly to the Breadcrumb initializer.
|
39
|
+
#
|
40
|
+
# @see Breadcrumb#initialize
|
41
|
+
# @params options [Hash] A hash of options to pass directly to
|
42
|
+
# the Breadcrumb.
|
43
|
+
# @yield
|
44
|
+
# @return [void]
|
45
|
+
def breadcrumb(options, &block)
|
46
|
+
breadcrumbs << Breadcrumb.new(**options, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
# All of the defined breadcrumbs, in order.
|
50
|
+
#
|
51
|
+
# @return [Array<Breadcrumb>]
|
52
|
+
def breadcrumbs
|
53
|
+
@_breadcrumbs ||= []
|
54
|
+
end
|
55
|
+
|
56
|
+
# Renders the defined breadcrumbs, with the given options.
|
57
|
+
#
|
58
|
+
# @param options [Hash] The options that are passed to the
|
59
|
+
# builder to help render the breadcrumbs.
|
60
|
+
# @option options [Hash] :builder (Builder) The builder to use.
|
61
|
+
# If this isn't provided, a sensible default is used.
|
62
|
+
# @yield
|
63
|
+
# @return [String]
|
64
|
+
def render_breadcrumbs(options = {}, &block)
|
65
|
+
block_given = block_given?
|
66
|
+
builder = options.fetch(:builder) do
|
67
|
+
if block_given
|
68
|
+
BlockBuilder
|
69
|
+
else
|
70
|
+
HTMLBuilder
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
builder.new(self, breadcrumbs, options, &block).call
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module BreadcrumbTrail
|
2
|
+
|
3
|
+
# A single representation of a breadcrumb.
|
4
|
+
class Breadcrumb
|
5
|
+
|
6
|
+
# The name of the breadcrumb. Normally, this represents the text
|
7
|
+
# that is displayed in place of the link to give meaning to the
|
8
|
+
# breadcrumb.
|
9
|
+
#
|
10
|
+
# @return [String, Symbol, Proc, nil]
|
11
|
+
attr_reader :name
|
12
|
+
|
13
|
+
# The path the breadcrumb represents. Normally, this is where the
|
14
|
+
# breadcrumb should take the user when clicked.
|
15
|
+
#
|
16
|
+
# @return [String, Symbol, Proc, Hash]
|
17
|
+
attr_reader :path
|
18
|
+
|
19
|
+
# Options for the breadcrumb. Normally, these are HTML attributes
|
20
|
+
# that are used for the link tag.
|
21
|
+
#
|
22
|
+
# @return [Hash]
|
23
|
+
attr_reader :options
|
24
|
+
|
25
|
+
# Initialize the breadcrumb. If a block is given, and a path is
|
26
|
+
# not, then the path is set to be the block.
|
27
|
+
#
|
28
|
+
# @param name [String, Symbol, Proc, nil] The name of the
|
29
|
+
# breadcrumb. See {#name}.
|
30
|
+
# @param path [String, Symbol, Proc, Hash] The path of the
|
31
|
+
# breadcrumb. See {#path}.
|
32
|
+
# @param options [Hash] Options that are used as HTML attributes.
|
33
|
+
# See {#options}.
|
34
|
+
#
|
35
|
+
def initialize(name: nil, path: nil, **options, &block)
|
36
|
+
@name = name
|
37
|
+
@path = path || block
|
38
|
+
@options = options
|
39
|
+
end
|
40
|
+
|
41
|
+
# Creates a version of the breadcrumb that has a computed name and
|
42
|
+
# path. This is used, for example, in a builder that exposes a
|
43
|
+
# breadcrumb to application code.
|
44
|
+
#
|
45
|
+
# @see #computed_path
|
46
|
+
# @see #computed_name
|
47
|
+
# @param context [ActionView::Base] The context to compute the
|
48
|
+
# elements under.
|
49
|
+
# @return [Breadcrumb]
|
50
|
+
def computed(context)
|
51
|
+
self.class.new(name: computed_name(context),
|
52
|
+
path: computed_path(context),
|
53
|
+
**@options)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Computes the path of the breadcrumb under the given context.
|
57
|
+
#
|
58
|
+
# @return [String, Hash]
|
59
|
+
def computed_path(context)
|
60
|
+
@_path ||= case @path
|
61
|
+
when String, Hash
|
62
|
+
@path
|
63
|
+
when Symbol
|
64
|
+
context.public_send(@path) # todo
|
65
|
+
when Proc
|
66
|
+
context.instance_exec(&@path)
|
67
|
+
else
|
68
|
+
raise ArgumentError,
|
69
|
+
"Expected one of String, Symbol, or Proc, " \
|
70
|
+
"got #{@path.class}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Computes the name of the breadcrumb under the given context.
|
75
|
+
#
|
76
|
+
# @return [String]
|
77
|
+
def computed_name(context)
|
78
|
+
@_name ||= case @name
|
79
|
+
when String
|
80
|
+
@name
|
81
|
+
when Symbol
|
82
|
+
context.public_send(@name) # todo
|
83
|
+
when Proc
|
84
|
+
context.instance_exec(&@name)
|
85
|
+
when nil
|
86
|
+
computed_path(context)
|
87
|
+
else
|
88
|
+
raise ArgumentError,
|
89
|
+
"Expected one of String, Symbol, or Proc, " \
|
90
|
+
"got #{@name.class}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module BreadcrumbTrail
|
2
|
+
|
3
|
+
# A Builder that is used by
|
4
|
+
# {ActionController::HelperMethods#render_breadcrumbs}. This should
|
5
|
+
# be subclassed and implemented.
|
6
|
+
#
|
7
|
+
# @abstract
|
8
|
+
class Builder
|
9
|
+
|
10
|
+
# Initialize the builder.
|
11
|
+
#
|
12
|
+
# @param context [ActionView::Base] The base of the view being
|
13
|
+
# rendered.
|
14
|
+
# @param breadcrumbs [Array<Breadcrumb>] The breadcrumbs to
|
15
|
+
# render.
|
16
|
+
# @param options [Hash] The options for the builder.
|
17
|
+
def initialize(context, breadcrumbs, options = {}, &block)
|
18
|
+
@context = context
|
19
|
+
@breadcrumbs = breadcrumbs
|
20
|
+
@options = options
|
21
|
+
@block = block
|
22
|
+
end
|
23
|
+
|
24
|
+
# Renders the breadcrumbs using the builder. However, since this
|
25
|
+
# is the base, it raises an error.
|
26
|
+
#
|
27
|
+
# @raise [NotImplementedError]
|
28
|
+
# @return [String]
|
29
|
+
def call
|
30
|
+
raise NotImplementedError
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
# Used along with a block given to the initializer, this renders
|
36
|
+
# the breadcrumbs.
|
37
|
+
class BlockBuilder < Builder
|
38
|
+
|
39
|
+
# Creates a buffer, and iterates over every breadcrumb, yielding
|
40
|
+
# the breadcrumb to the block given on initialization.
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
def call
|
44
|
+
buffer = ActiveSupport::SafeBuffer.new
|
45
|
+
@breadcrumbs.each do |breadcrumb|
|
46
|
+
buffer << @block.call(breadcrumb.computed(@context))
|
47
|
+
end
|
48
|
+
|
49
|
+
buffer
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Creates a structure of HTML elements to render the breadcrumbs.
|
54
|
+
class HTMLBuilder < Builder
|
55
|
+
|
56
|
+
include ActionView::Helpers
|
57
|
+
|
58
|
+
# Renders the breadcrumbs in HTML tags. If no options were
|
59
|
+
# provided on initialization, it uses defaults.
|
60
|
+
#
|
61
|
+
# @option @options [String] :outer ("ol") The outer tag element
|
62
|
+
# to use.
|
63
|
+
# @option @options [String] :inner ("li") The inner tag element
|
64
|
+
# to use.
|
65
|
+
# @option @options [Hash] :outer_options (nil) The outer tag
|
66
|
+
# element attributes to use. Things like `class="some-class"`
|
67
|
+
# are best placed here.
|
68
|
+
# @option @options [Hash] :inner_options (nil) The inner tag
|
69
|
+
# element attributes to use. Things like `class="some-class"`
|
70
|
+
# are best placed here.
|
71
|
+
# @return [String]
|
72
|
+
def call
|
73
|
+
outer_tag = @options.fetch(:outer, "ol")
|
74
|
+
inner_tag = @options.fetch(:inner, "li")
|
75
|
+
outer = tag(outer_tag,
|
76
|
+
@options.fetch(:outer_options, nil),
|
77
|
+
true) if outer_tag
|
78
|
+
inner = tag(inner_tag,
|
79
|
+
@options.fetch(:inner_options, nil),
|
80
|
+
true) if inner_tag
|
81
|
+
|
82
|
+
buffer = ActiveSupport::SafeBuffer.new
|
83
|
+
buffer.safe_concat(outer) if outer_tag
|
84
|
+
|
85
|
+
@breadcrumbs.each do |breadcrumb|
|
86
|
+
buffer.safe_concat(inner) if inner_tag
|
87
|
+
buffer << link_to(breadcrumb.computed_name(@context),
|
88
|
+
breadcrumb.computed_path(@context),
|
89
|
+
breadcrumb.options)
|
90
|
+
buffer.safe_concat("</#{inner_tag}>") if inner_tag
|
91
|
+
end
|
92
|
+
|
93
|
+
buffer.safe_concat("</#{outer_tag}>") if outer_tag
|
94
|
+
buffer
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module BreadcrumbTrail
|
2
|
+
|
3
|
+
# A railtie, to load the plugin when Rails is initialized.
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
initializer "breadcrumb_trail.modify_controller" do
|
6
|
+
ActiveSupport.on_load :action_controller do
|
7
|
+
include BreadcrumbTrail::ActionController
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|