loaf 0.3.0 → 0.4.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 +21 -8
- data/.ruby-version +1 -0
- data/.travis.yml +23 -2
- data/Appraisals +18 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +16 -1
- data/README.md +69 -52
- data/Rakefile +5 -3
- data/bin/setup +7 -0
- data/gemfiles/rails3.2.gemfile +21 -0
- data/gemfiles/rails4.0.gemfile +22 -0
- data/gemfiles/rails4.1.gemfile +21 -0
- data/gemfiles/rails4.2.gemfile +21 -0
- data/lib/loaf.rb +24 -1
- data/lib/loaf/configuration.rb +15 -22
- data/lib/loaf/controller_extensions.rb +25 -12
- data/lib/loaf/crumb.rb +13 -1
- data/lib/loaf/crumb_formatter.rb +14 -13
- data/lib/loaf/options_validator.rb +10 -2
- data/lib/loaf/translation.rb +15 -8
- data/lib/loaf/version.rb +1 -8
- data/lib/loaf/view_extensions.rb +42 -15
- data/loaf.gemspec +10 -17
- data/spec/integration/configuration_spec.rb +7 -8
- data/spec/integration/crumbs_routing_spec.rb +31 -28
- data/spec/rails_app/app/controllers/application_controller.rb +0 -2
- data/spec/rails_app/app/controllers/posts_controller.rb +13 -2
- data/spec/rails_app/app/views/layouts/_breadcrumbs.html.erb +2 -0
- data/spec/rails_app/app/views/posts/index.html.erb +0 -2
- data/spec/rails_app/app/views/posts/new.html.erb +3 -0
- data/spec/rails_app/app/views/posts/show.html.erb +1 -0
- data/spec/rails_app/config/environments/development.rb +2 -0
- data/spec/rails_app/config/environments/production.rb +2 -0
- data/spec/rails_app/config/environments/test.rb +2 -3
- data/spec/rails_app/config/routes.rb +0 -2
- data/spec/rails_app/{app/mailers → log}/.gitkeep +0 -0
- data/spec/spec_helper.rb +42 -4
- data/spec/support/dummy_view.rb +7 -0
- data/spec/unit/controller_extensions_spec.rb +63 -0
- data/spec/unit/crumb_formatter_spec.rb +38 -0
- data/spec/unit/options_validator_spec.rb +17 -0
- data/spec/unit/translation_spec.rb +22 -0
- data/spec/unit/view_extensions/breadcrumb_spec.rb +24 -0
- data/spec/unit/view_extensions/breadcrumbs_spec.rb +128 -0
- data/spec/unit/view_extensions/has_breadcrumbs_spec.rb +12 -0
- data/tasks/console.rake +10 -0
- data/tasks/coverage.rake +11 -0
- data/tasks/spec.rake +29 -0
- metadata +50 -100
- data/.rvmrc +0 -28
- data/Gemfile.lock +0 -132
- data/spec/integration/nested_crumbs_spec.rb +0 -5
- data/spec/loaf/controller_extensions_spec.rb +0 -55
- data/spec/loaf/crumb_formatter_spec.rb +0 -33
- data/spec/loaf/options_validator_spec.rb +0 -29
- data/spec/loaf/translation_spec.rb +0 -23
- data/spec/loaf/view_extensions_spec.rb +0 -114
- data/spec/loaf_spec.rb +0 -5
- data/spec/rails_app/app/assets/images/rails.png +0 -0
- data/spec/rails_app/app/assets/javascripts/application.js +0 -9
- data/spec/rails_app/app/assets/stylesheets/application.css +0 -7
- data/spec/rails_app/app/helpers/application_helper.rb +0 -2
- data/spec/rails_app/app/models/.gitkeep +0 -0
data/lib/loaf/configuration.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Loaf
|
4
|
-
|
5
|
-
|
4
|
+
class Configuration
|
6
5
|
VALID_ATTRIBUTES = [
|
7
6
|
:locales_path,
|
8
7
|
:style_classes,
|
@@ -12,9 +11,9 @@ module Loaf
|
|
12
11
|
:root
|
13
12
|
]
|
14
13
|
|
15
|
-
attr_accessor
|
14
|
+
attr_accessor(*VALID_ATTRIBUTES)
|
16
15
|
|
17
|
-
DEFAULT_LOCALES_PATH =
|
16
|
+
DEFAULT_LOCALES_PATH = '/'
|
18
17
|
|
19
18
|
DEFAULT_STYLE_CLASSES = 'selected'
|
20
19
|
|
@@ -26,28 +25,22 @@ module Loaf
|
|
26
25
|
|
27
26
|
DEFAULT_ROOT = true
|
28
27
|
|
29
|
-
#
|
28
|
+
# Setup this configuration
|
30
29
|
#
|
31
|
-
#
|
32
|
-
|
33
|
-
# end
|
34
|
-
def configure
|
35
|
-
yield self
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.extended(base)
|
39
|
-
base.setup(self)
|
40
|
-
end
|
41
|
-
|
42
|
-
def config
|
43
|
-
VALID_ATTRIBUTES.inject({}) { |hash, k| hash[k] = send(k); hash }
|
44
|
-
end
|
45
|
-
|
46
|
-
def setup(parent)
|
30
|
+
# @api public
|
31
|
+
def initialize
|
47
32
|
VALID_ATTRIBUTES.each do |attr|
|
48
|
-
send("#{attr}=",
|
33
|
+
send("#{attr}=", self.class.const_get("DEFAULT_#{attr.to_s.upcase}"))
|
49
34
|
end
|
50
35
|
end
|
51
36
|
|
37
|
+
# Convert all properties into hash
|
38
|
+
#
|
39
|
+
# @return [Hash]
|
40
|
+
#
|
41
|
+
# @api public
|
42
|
+
def to_hash
|
43
|
+
VALID_ATTRIBUTES.reduce({}) { |acc, k| acc[k] = send(k); acc }
|
44
|
+
end
|
52
45
|
end # Configuration
|
53
46
|
end # Loaf
|
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
module Loaf
|
4
4
|
module ControllerExtensions
|
5
|
-
|
5
|
+
# Module injection
|
6
|
+
#
|
7
|
+
# @api private
|
6
8
|
def self.included(base)
|
7
9
|
base.extend ClassMethods
|
8
10
|
base.send :include, InstanceMethods
|
@@ -10,14 +12,16 @@ module Loaf
|
|
10
12
|
end
|
11
13
|
|
12
14
|
module ClassMethods
|
13
|
-
|
15
|
+
# @param [String]
|
16
|
+
#
|
17
|
+
# @api public
|
14
18
|
def breadcrumb(name, url, options = {})
|
15
19
|
before_filter(options) do |instance|
|
16
20
|
# instance.send(:add_breadcrumb, _normalize_name(name), url)
|
17
|
-
instance.send(:
|
21
|
+
instance.send(:breadcrumb, name, url, options)
|
18
22
|
end
|
19
23
|
end
|
20
|
-
|
24
|
+
alias_method :add_breadcrumb, :breadcrumb
|
21
25
|
|
22
26
|
private
|
23
27
|
|
@@ -32,16 +36,14 @@ module Loaf
|
|
32
36
|
name
|
33
37
|
end
|
34
38
|
end
|
35
|
-
|
36
39
|
end # ClassMethods
|
37
40
|
|
38
41
|
module InstanceMethods
|
39
|
-
|
40
42
|
# Add collection of nested breadcrumbs.
|
41
43
|
# * <tt>collection</tt> - required collection of object for iteration
|
42
44
|
# * <tt>field</tt> - required object attribute name
|
43
45
|
#
|
44
|
-
def add_breadcrumbs(collection, field, options={})
|
46
|
+
def add_breadcrumbs(collection, field, options = {})
|
45
47
|
namespace = nil
|
46
48
|
item_set = if _check_if_nested collection
|
47
49
|
items = collection.pop
|
@@ -55,15 +57,28 @@ module Loaf
|
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
+
# Add breadcrumb
|
61
|
+
#
|
62
|
+
# @param [String] name
|
63
|
+
#
|
64
|
+
# @param [Object] url
|
65
|
+
#
|
66
|
+
# @api public
|
67
|
+
def breadcrumb(name, url, options = {})
|
68
|
+
_breadcrumbs << Loaf::Crumb.new(name, url, options)
|
60
69
|
end
|
61
|
-
|
70
|
+
alias_method :add_breadcrumb, :breadcrumb
|
62
71
|
|
72
|
+
# Collection of breadcrumbs
|
73
|
+
#
|
74
|
+
# @api private
|
63
75
|
def _breadcrumbs
|
64
76
|
@_breadcrumbs ||= []
|
65
77
|
end
|
66
78
|
|
79
|
+
# Remove all current breadcrumbs
|
80
|
+
#
|
81
|
+
# @api public
|
67
82
|
def clear_breadcrumbs
|
68
83
|
_breadcrumbs.clear
|
69
84
|
end
|
@@ -73,8 +88,6 @@ module Loaf
|
|
73
88
|
def _check_if_nested(collection)
|
74
89
|
collection.last.is_a? Array
|
75
90
|
end
|
76
|
-
|
77
91
|
end # InstanceMethods
|
78
|
-
|
79
92
|
end # ControllerExtensions
|
80
93
|
end # Loaf
|
data/lib/loaf/crumb.rb
CHANGED
@@ -2,5 +2,17 @@
|
|
2
2
|
|
3
3
|
module Loaf
|
4
4
|
# Basic crumb container
|
5
|
-
Crumb
|
5
|
+
class Crumb
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
attr_reader :url
|
9
|
+
|
10
|
+
attr_reader :force
|
11
|
+
|
12
|
+
def initialize(name, url, options = {})
|
13
|
+
@name = name
|
14
|
+
@url = url
|
15
|
+
@force = options.fetch(:force) { false }
|
16
|
+
end
|
17
|
+
end
|
6
18
|
end # Loaf
|
data/lib/loaf/crumb_formatter.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Loaf
|
4
|
+
# A mixin for formatting crumb name
|
2
5
|
module CrumbFormatter
|
6
|
+
# @param [String] name
|
7
|
+
# the name to format
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
def format_name(name, options = {})
|
11
|
+
return if name.nil?
|
3
12
|
|
4
|
-
|
5
|
-
if
|
6
|
-
|
7
|
-
formatted =
|
8
|
-
formatted = if options[:crumb_length]
|
9
|
-
truncate(formatted, :length => options[:crumb_length])
|
10
|
-
else
|
11
|
-
formatted
|
12
|
-
end
|
13
|
-
formatted
|
14
|
-
else
|
15
|
-
'[name-error]'
|
13
|
+
formatted = name.to_s.dup
|
14
|
+
formatted = formatted.capitalize if options[:capitalize]
|
15
|
+
if options[:crumb_length]
|
16
|
+
formatted = truncate(formatted, length: options[:crumb_length])
|
16
17
|
end
|
18
|
+
formatted
|
17
19
|
end
|
18
|
-
|
19
20
|
end # CrumbFormatter
|
20
21
|
end # Loaf
|
@@ -3,12 +3,20 @@
|
|
3
3
|
require 'loaf/errors'
|
4
4
|
|
5
5
|
module Loaf
|
6
|
+
# A mixin to validate configuration options
|
6
7
|
module OptionsValidator
|
8
|
+
# Check if options are valid or not
|
9
|
+
#
|
10
|
+
# @param [Hash] options
|
11
|
+
#
|
12
|
+
# @return [Boolean]
|
13
|
+
#
|
14
|
+
# @api public
|
7
15
|
def valid?(options)
|
8
16
|
valid_options = Loaf::Configuration::VALID_ATTRIBUTES
|
9
17
|
options.each_key do |key|
|
10
|
-
|
11
|
-
|
18
|
+
unless valid_options.include?(key)
|
19
|
+
fail Loaf::InvalidOptions.new(key, valid_options)
|
12
20
|
end
|
13
21
|
end
|
14
22
|
true
|
data/lib/loaf/translation.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Loaf
|
2
4
|
module Translation
|
3
5
|
extend self
|
@@ -7,17 +9,22 @@ module Loaf
|
|
7
9
|
:breadcrumbs
|
8
10
|
end
|
9
11
|
|
10
|
-
#
|
11
|
-
|
12
|
+
# Translate breadcrumb title
|
13
|
+
#
|
14
|
+
# @param [String] :title
|
15
|
+
# @param [Hash] options
|
16
|
+
# @option options [String] :scope
|
17
|
+
# The translation scope
|
18
|
+
# @option options [String] :default
|
19
|
+
# The default translation
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
def breadcrumb_title(title, options = {})
|
12
23
|
defaults = []
|
13
|
-
|
14
|
-
actions = parts.pop
|
15
|
-
namespace = parts.pop
|
16
|
-
|
17
|
-
defaults << :"#{self.i18n_scope}.#{title}"
|
24
|
+
defaults << :"#{i18n_scope}.#{title}"
|
18
25
|
defaults << options.delete(:default) if options[:default]
|
19
26
|
|
20
|
-
options.reverse_merge! :
|
27
|
+
options.reverse_merge! count: 1, default: defaults
|
21
28
|
I18n.t(title, options)
|
22
29
|
end
|
23
30
|
end # Translation
|
data/lib/loaf/version.rb
CHANGED
data/lib/loaf/view_extensions.rb
CHANGED
@@ -4,43 +4,70 @@ require 'loaf/crumb_formatter'
|
|
4
4
|
require 'loaf/options_validator'
|
5
5
|
|
6
6
|
module Loaf
|
7
|
+
# A mixin to define view extensions
|
7
8
|
module ViewExtensions
|
8
9
|
include Loaf::CrumbFormatter
|
9
10
|
include Loaf::OptionsValidator
|
10
11
|
|
12
|
+
def initialize(*)
|
13
|
+
@_breadcrumbs ||= []
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
# Checks to see if any breadcrumbs have been added
|
18
|
+
#
|
19
|
+
# @return [Boolean]
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
def breadcrumbs?
|
23
|
+
_breadcrumbs.present?
|
24
|
+
end
|
25
|
+
|
11
26
|
# Adds breadcrumbs inside view.
|
12
27
|
#
|
13
|
-
|
14
|
-
|
28
|
+
# @param [String] name
|
29
|
+
# the breadcrumb name
|
30
|
+
# @param [Object] url
|
31
|
+
# the breadcrumb url
|
32
|
+
# @param [Hash] options
|
33
|
+
# the breadcrumb options
|
34
|
+
#
|
35
|
+
# @api public
|
36
|
+
def breadcrumb(name, url, options = {})
|
37
|
+
_breadcrumbs << Loaf::Crumb.new(name, url, options)
|
15
38
|
end
|
16
|
-
|
39
|
+
alias_method :add_breadcrumb, :breadcrumb
|
17
40
|
|
18
41
|
# Renders breadcrumbs inside view.
|
19
42
|
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
43
|
+
# @param [Hash] options
|
44
|
+
#
|
45
|
+
# @api public
|
46
|
+
def breadcrumbs(options = {}, &block)
|
47
|
+
# builder = Loaf::Builder.new(options)
|
48
|
+
return enum_for(:breadcrumbs) unless block_given?
|
49
|
+
valid?(options)
|
50
|
+
options = Loaf.configuration.to_hash.merge(options)
|
24
51
|
_breadcrumbs.each do |crumb|
|
25
|
-
name
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
52
|
+
name = format_name(crumb.name, options)
|
53
|
+
url = url_for(_process_url_for(crumb.url))
|
54
|
+
styles = ''
|
55
|
+
if current_page?(url) || crumb.force
|
56
|
+
styles << "#{options[:style_classes]}"
|
57
|
+
end
|
31
58
|
block.call(name, url, styles)
|
32
59
|
end
|
33
60
|
end
|
34
61
|
|
35
62
|
private
|
36
63
|
|
64
|
+
# @api private
|
37
65
|
def _process_url_for(url)
|
38
66
|
if url.is_a?(String) || url.is_a?(Symbol)
|
39
|
-
return send url
|
67
|
+
return respond_to?(url) ? send(url) : url
|
40
68
|
else
|
41
69
|
return url
|
42
70
|
end
|
43
71
|
end
|
44
|
-
|
45
72
|
end # ViewExtensions
|
46
73
|
end # Loaf
|
data/loaf.gemspec
CHANGED
@@ -1,28 +1,21 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
4
|
require 'loaf/version'
|
4
5
|
|
5
6
|
Gem::Specification.new do |s|
|
6
|
-
s.name =
|
7
|
-
s.version = Loaf::
|
8
|
-
s.authors = [
|
7
|
+
s.name = 'loaf'
|
8
|
+
s.version = Loaf::VERSION.dup
|
9
|
+
s.authors = ['Piotr Murach']
|
9
10
|
s.email = [""]
|
10
|
-
s.homepage =
|
11
|
-
s.summary = %q{Loaf
|
12
|
-
s.description = %q{Loaf
|
13
|
-
|
14
|
-
s.rubyforge_project = "tytus"
|
11
|
+
s.homepage = 'https://github.com/peter-murach/loaf'
|
12
|
+
s.summary = %q{Loaf manages and displays breadcrumb trails in your Rails application.}
|
13
|
+
s.description = %q{Loaf manages and displays breadcrumb trails in your Rails app. It aims to handle breadcrumb data through easy dsl and expose it through view helpers without any assumptions about markup.}
|
15
14
|
|
16
15
|
s.files = `git ls-files`.split("\n")
|
17
16
|
s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
|
18
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
18
|
s.require_paths = ["lib"]
|
20
19
|
|
21
|
-
s.add_dependency 'rails'
|
22
|
-
|
23
|
-
s.add_development_dependency 'rails', '~> 3.1'
|
24
|
-
s.add_development_dependency 'sqlite3'
|
25
|
-
s.add_development_dependency 'rspec-rails'
|
26
|
-
s.add_development_dependency 'capybara'
|
27
|
-
s.add_development_dependency 'bundler'
|
20
|
+
s.add_dependency 'rails', '>= 3.1'
|
28
21
|
end
|
@@ -1,13 +1,12 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
5
|
+
RSpec.describe 'setting configuration options' do
|
6
|
+
it "contains 'selected' inside the breadcrumb markup" do
|
7
|
+
visit posts_path
|
8
|
+
within '#breadcrumbs' do
|
9
|
+
expect(page).to have_selector('.selected')
|
11
10
|
end
|
12
11
|
end
|
13
12
|
end
|
@@ -1,43 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
|
-
describe "crumbs routing" do
|
5
|
+
RSpec.describe "crumbs routing" do
|
4
6
|
include ActionView::TestCase::Behavior
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
it "doens't show empty breadcrumbs" do
|
9
|
+
visit root_path
|
10
|
+
expect(page).to_not have_content("breadcrumbs")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "inherits controller breadcrumb and adds index action breadcrumb" do
|
14
|
+
visit posts_path
|
15
|
+
within '#breadcrumbs' do
|
16
|
+
expect(page.html).to include('<a href="/">Home</a>')
|
17
|
+
expect(page.html).to include('<a href="/posts">All Posts</a>')
|
12
18
|
end
|
13
19
|
end
|
14
20
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
page.should have_content 'All Posts'
|
21
|
-
page.should_not have_content 'New Post'
|
22
|
-
end
|
21
|
+
it 'filters out controller breadcrumb and adds new action breadcrumb' do
|
22
|
+
visit new_post_path
|
23
|
+
within '#breadcrumbs' do
|
24
|
+
expect(page).to_not have_content('Home')
|
25
|
+
expect(page).to have_content('New Post')
|
23
26
|
end
|
27
|
+
end
|
24
28
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
page.should have_content 'New Post'
|
30
|
-
end
|
29
|
+
it "adds breadcrumb in view with path variable" do
|
30
|
+
visit post_path(1)
|
31
|
+
within '#breadcrumbs' do
|
32
|
+
expect(page.html).to include('<a href="/posts/1">Show Post in view</a>')
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
it 'should be current when forced' do
|
37
|
+
visit new_post_path
|
38
|
+
click_button "Create"
|
39
|
+
|
40
|
+
expect(page.current_path).to eq(posts_path)
|
41
|
+
within '#breadcrumbs' do
|
42
|
+
expect(page).to have_content('New Post')
|
43
|
+
expect(page).to have_selector('.selected')
|
41
44
|
end
|
42
45
|
end
|
43
46
|
end
|