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.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +142 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +136 -0
  9. data/Rakefile +28 -0
  10. data/breadcrumb_trail.gemspec +30 -0
  11. data/lib/breadcrumb_trail/action_controller.rb +79 -0
  12. data/lib/breadcrumb_trail/breadcrumb.rb +95 -0
  13. data/lib/breadcrumb_trail/builder.rb +98 -0
  14. data/lib/breadcrumb_trail/railtie.rb +11 -0
  15. data/lib/breadcrumb_trail/version.rb +5 -0
  16. data/lib/breadcrumb_trail.rb +10 -0
  17. data/lib/tasks/breadcrumb_trail_tasks.rake +4 -0
  18. data/spec/block_builder_spec.rb +19 -0
  19. data/spec/breadcrumb_spec.rb +93 -0
  20. data/spec/builder_spec.rb +16 -0
  21. data/spec/dummy/README.rdoc +28 -0
  22. data/spec/dummy/Rakefile +6 -0
  23. data/spec/dummy/app/assets/images/.keep +0 -0
  24. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  25. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  26. data/spec/dummy/app/controllers/application_controller.rb +7 -0
  27. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  28. data/spec/dummy/app/controllers/welcome_controller.rb +11 -0
  29. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  30. data/spec/dummy/app/views/layouts/application.html.erb +11 -0
  31. data/spec/dummy/app/views/welcome/hello.html.erb +4 -0
  32. data/spec/dummy/app/views/welcome/index.html.erb +2 -0
  33. data/spec/dummy/bin/bundle +3 -0
  34. data/spec/dummy/bin/rails +4 -0
  35. data/spec/dummy/bin/rake +4 -0
  36. data/spec/dummy/bin/setup +21 -0
  37. data/spec/dummy/config/application.rb +28 -0
  38. data/spec/dummy/config/boot.rb +5 -0
  39. data/spec/dummy/config/environment.rb +5 -0
  40. data/spec/dummy/config/environments/test.rb +37 -0
  41. data/spec/dummy/config/initializers/assets.rb +11 -0
  42. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  43. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  44. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  45. data/spec/dummy/config/initializers/inflections.rb +16 -0
  46. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  47. data/spec/dummy/config/initializers/session_store.rb +3 -0
  48. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  49. data/spec/dummy/config/locales/en.yml +23 -0
  50. data/spec/dummy/config/routes.rb +5 -0
  51. data/spec/dummy/config/secrets.yml +22 -0
  52. data/spec/dummy/config.ru +4 -0
  53. data/spec/dummy/public/404.html +67 -0
  54. data/spec/dummy/public/422.html +67 -0
  55. data/spec/dummy/public/500.html +66 -0
  56. data/spec/dummy/public/favicon.ico +0 -0
  57. data/spec/html_builder_spec.rb +62 -0
  58. data/spec/integration/application_breadcrumbs_spec.rb +46 -0
  59. data/spec/spec_helper.rb +10 -0
  60. 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
@@ -0,0 +1,6 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ spec/dummy/log/*.log
5
+ spec/dummy/tmp/
6
+ spec/dummy/.sass-cache
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format d
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ cache: bundler
3
+ sudo: false
4
+ rvm:
5
+ - 2.0.0
6
+ - 2.1.5
7
+ - 2.2.0
8
+ script: bundle exec rspec spec
9
+ addons:
10
+ code_climate:
11
+ repo_token: 871ec12915a92c1f4f85af1b78f22652ff35f86de0dea210d8aeea1f35f31df2
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Declare your gem's dependencies in breadcrumb_trail.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
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
+ [![Code Climate](https://codeclimate.com/github/medcat/breadcrumb_trail/badges/gpa.svg)](https://codeclimate.com/github/medcat/breadcrumb_trail) [![Build Status](https://travis-ci.org/medcat/breadcrumb_trail.svg)](https://travis-ci.org/medcat/breadcrumb_trail) [![Test Coverage](https://codeclimate.com/github/medcat/breadcrumb_trail/badges/coverage.svg)](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
@@ -0,0 +1,5 @@
1
+ module BreadcrumbTrail
2
+
3
+ # The current version of BreadcrumbTrail.
4
+ VERSION = "0.1.0"
5
+ end