breadcrumbs 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +92 -0
- data/lib/breadcrumbs.rb +50 -0
- data/lib/breadcrumbs/action_controller_ext.rb +13 -0
- data/lib/breadcrumbs/render.rb +3 -0
- data/lib/breadcrumbs/render/base.rb +31 -0
- data/lib/breadcrumbs/render/inline.rb +40 -0
- data/lib/breadcrumbs/render/list.rb +34 -0
- data/lib/breadcrumbs/version.rb +8 -0
- data/test/breadcrumbs_test.rb +152 -0
- data/test/resources/pt.yml +6 -0
- data/test/test_helper.rb +9 -0
- metadata +84 -0
data/README.rdoc
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
= Breadcrumbs
|
2
|
+
|
3
|
+
Breadcrumbs is a simple plugin that adds a +breadcrumbs+ object to controllers and views.
|
4
|
+
|
5
|
+
== Instalation
|
6
|
+
|
7
|
+
Just run <tt>sudo gem install breadcrumbs</tt>
|
8
|
+
|
9
|
+
== Usage
|
10
|
+
|
11
|
+
On your controller (optional):
|
12
|
+
|
13
|
+
class ApplicationController < ActionController::Base
|
14
|
+
before_filter :add_initial_breadcrumbs
|
15
|
+
|
16
|
+
private
|
17
|
+
def add_initial_breadcrumbs
|
18
|
+
breadcrumbs.add 'Home', root_path
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class ThingsController < ApplicationController
|
23
|
+
def index
|
24
|
+
breadcrumbs.add 'Things', things_path
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
You don't need to provide an URL; in that case, a span will be generated
|
29
|
+
instead of a link:
|
30
|
+
|
31
|
+
breadcrumbs.add 'Some page'
|
32
|
+
|
33
|
+
You can set additional HTML attributes if you need to:
|
34
|
+
|
35
|
+
breadcrumbs.add 'Home', root_path, :id => 'home', :title => 'Go to the home page'
|
36
|
+
|
37
|
+
On your view (possibly application.html.erb):
|
38
|
+
|
39
|
+
<%= breadcrumbs.render %>
|
40
|
+
|
41
|
+
You can render as inline links.
|
42
|
+
|
43
|
+
<%= breadcrumbs.render(:format => :inline) %>
|
44
|
+
|
45
|
+
You can set your own separator:
|
46
|
+
|
47
|
+
<p>
|
48
|
+
You are here: <%= breadcrumbs.render(:format => :inline, :separator => '|') %>
|
49
|
+
</p>
|
50
|
+
|
51
|
+
=== I18n
|
52
|
+
|
53
|
+
Breadcrumbs is integrated with I18n. You can set translations like:
|
54
|
+
|
55
|
+
en:
|
56
|
+
breadcrumbs:
|
57
|
+
home: "Home"
|
58
|
+
|
59
|
+
And then you just call
|
60
|
+
|
61
|
+
breadcrumbs.add :home
|
62
|
+
|
63
|
+
In fact, you can provide any scope you want.
|
64
|
+
|
65
|
+
breadcrumbs.add "titles.home"
|
66
|
+
|
67
|
+
== Maintainer
|
68
|
+
|
69
|
+
* Nando Vieira - http://simplesideias.com.br
|
70
|
+
|
71
|
+
License
|
72
|
+
|
73
|
+
(The MIT License)
|
74
|
+
|
75
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
76
|
+
a copy of this software and associated documentation files (the
|
77
|
+
'Software'), to deal in the Software without restriction, including
|
78
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
79
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
80
|
+
permit persons to whom the Software is furnished to do so, subject to
|
81
|
+
the following conditions:
|
82
|
+
|
83
|
+
The above copyright notice and this permission notice shall be
|
84
|
+
included in all copies or substantial portions of the Software.
|
85
|
+
|
86
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
87
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
88
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
89
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
90
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
91
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
92
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/breadcrumbs.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require "i18n" unless defined?(I18n)
|
2
|
+
require "breadcrumbs/render"
|
3
|
+
require "breadcrumbs/action_controller_ext" if defined?(ActionController)
|
4
|
+
|
5
|
+
class Breadcrumbs
|
6
|
+
attr_accessor :items
|
7
|
+
|
8
|
+
def initialize # :nodoc:
|
9
|
+
self.items = []
|
10
|
+
end
|
11
|
+
|
12
|
+
# Add a new breadcrumbs.
|
13
|
+
#
|
14
|
+
# breadcrumbs.add "Home"
|
15
|
+
# breadcrumbs.add "Home", "/"
|
16
|
+
# breadcrumbs.add "Home", "/", :class => "home"
|
17
|
+
#
|
18
|
+
# If you provide a symbol as text, it will try to
|
19
|
+
# find it as I18n scope.
|
20
|
+
#
|
21
|
+
def add(text, url = nil, options = {})
|
22
|
+
items << [translate(text), url, options]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Render breadcrumbs using the specified format.
|
26
|
+
# Use HTML lists by default, but can be plain links.
|
27
|
+
#
|
28
|
+
# breadcrumbs.render
|
29
|
+
# breadcrumbs.render(:format => :inline)
|
30
|
+
# breadcrumbs.render(:format => :inline, :separator => "|")
|
31
|
+
# breadcrumbs.render(:format => :list)
|
32
|
+
# breadcrumbs.render(:id => "breadcrumbs")
|
33
|
+
# breadcrumbs.render(:class => "breadcrumbs")
|
34
|
+
#
|
35
|
+
def render(options = {})
|
36
|
+
if options[:format] == :inline
|
37
|
+
Breadcrumbs::Render::Inline.new(self, options).render
|
38
|
+
else
|
39
|
+
Breadcrumbs::Render::List.new(self, options).render
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
alias :<< :add
|
44
|
+
|
45
|
+
def translate(scope) # :nodoc:
|
46
|
+
text = I18n.t(scope, :scope => :breadcrumbs, :raise => true) rescue nil
|
47
|
+
text ||= I18n.t(scope, :default => scope)
|
48
|
+
text
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Breadcrumbs
|
2
|
+
module ActionController # :nodoc: all
|
3
|
+
def self.included(base)
|
4
|
+
base.send :helper_method, :breadcrumbs
|
5
|
+
end
|
6
|
+
|
7
|
+
def breadcrumbs
|
8
|
+
@breadcrumbs ||= Breadcrumbs.new
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
ActionController::Base.send :include, Breadcrumbs::ActionController
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Breadcrumbs
|
2
|
+
module Render
|
3
|
+
class Base # :nodoc: all
|
4
|
+
attr_accessor :breadcrumbs
|
5
|
+
attr_accessor :default_options
|
6
|
+
|
7
|
+
def initialize(breadcrumbs, default_options = {})
|
8
|
+
@breadcrumbs = breadcrumbs
|
9
|
+
@default_options = default_options
|
10
|
+
end
|
11
|
+
|
12
|
+
# Build a HTML tag.
|
13
|
+
#
|
14
|
+
# tag(:p, "Hello!")
|
15
|
+
# tag(:p, "Hello!", :class => "hello")
|
16
|
+
# tag(:p, :class => "phrase") { "Hello" }
|
17
|
+
#
|
18
|
+
def tag(name, *args, &block)
|
19
|
+
options = args.pop if args.last.kind_of?(Hash)
|
20
|
+
options ||= {}
|
21
|
+
|
22
|
+
content = args.first
|
23
|
+
content = self.instance_eval(&block) if block_given?
|
24
|
+
|
25
|
+
attrs = " " + options.collect {|n, v| %[%s="%s"] % [n, v] }.join(" ") unless options.empty?
|
26
|
+
|
27
|
+
%[<#{name}#{attrs}>#{content}</#{name}>]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Breadcrumbs
|
2
|
+
module Render
|
3
|
+
class Inline < Base # :nodoc: all
|
4
|
+
def render
|
5
|
+
options = {:class => "breadcrumbs", :separator => "»"}.merge(default_options)
|
6
|
+
|
7
|
+
html = []
|
8
|
+
items = breadcrumbs.items
|
9
|
+
size = items.size
|
10
|
+
|
11
|
+
items.each_with_index do |item, i|
|
12
|
+
html << render_item(item, i, size)
|
13
|
+
end
|
14
|
+
|
15
|
+
separator = tag(:span, options[:separator], :class => "separator")
|
16
|
+
|
17
|
+
html.join(" #{separator} ")
|
18
|
+
end
|
19
|
+
|
20
|
+
def render_item(item, i, size)
|
21
|
+
text, url, options = *item
|
22
|
+
options[:class] ||= ""
|
23
|
+
|
24
|
+
css = []
|
25
|
+
css << "first" if i == 0
|
26
|
+
css << "last" if i == size - 1
|
27
|
+
css << "item-#{i}"
|
28
|
+
|
29
|
+
options[:class] << " #{css.join(" ")}"
|
30
|
+
options[:class].gsub!(/^ *(.*?)$/, '\\1')
|
31
|
+
|
32
|
+
if url
|
33
|
+
text = tag(:a, text, options.merge(:href => url))
|
34
|
+
else
|
35
|
+
text = tag(:span, text, options)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Breadcrumbs
|
2
|
+
module Render
|
3
|
+
class List < Base # :nodoc: all
|
4
|
+
def render
|
5
|
+
options = {:class => "breadcrumbs"}.merge(default_options)
|
6
|
+
|
7
|
+
tag(:ul, options) do
|
8
|
+
html = ""
|
9
|
+
items = breadcrumbs.items
|
10
|
+
size = items.size
|
11
|
+
|
12
|
+
items.each_with_index do |item, i|
|
13
|
+
html << render_item(item, i, size)
|
14
|
+
end
|
15
|
+
|
16
|
+
html
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def render_item(item, i, size)
|
21
|
+
css = []
|
22
|
+
css << "first" if i == 0
|
23
|
+
css << "last" if i == size - 1
|
24
|
+
css << "item-#{i}"
|
25
|
+
|
26
|
+
text, url, options = *item
|
27
|
+
|
28
|
+
text = tag(:a, text, options.merge(:href => url)) if url
|
29
|
+
|
30
|
+
tag(:li, text, :class => css.join(" "))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class BreadcrumbsTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@breadcrumbs = Breadcrumbs.new
|
6
|
+
@inline = Breadcrumbs::Render::Inline.new(@breadcrumbs)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_add_item
|
10
|
+
@breadcrumbs.add "Home"
|
11
|
+
assert_equal 1, @breadcrumbs.items.count
|
12
|
+
|
13
|
+
@breadcrumbs << "Home"
|
14
|
+
assert_equal 2, @breadcrumbs.items.count
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_tag
|
18
|
+
assert_equal "<span>Hi!</span>", @inline.tag(:span, "Hi!")
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_tag_with_attributes
|
22
|
+
expected = %[<span class="greetings" id="hi">Hi!</span>]
|
23
|
+
assert_equal expected, @inline.tag(:span, "Hi!", :class => "greetings", :id => "hi")
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_tag_with_block
|
27
|
+
assert_equal "<span>Hi!</span>", @inline.tag(:span) { "Hi!" }
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_tag_with_block_and_attributes
|
31
|
+
expected = %[<span class="greetings" id="hi">Hi!</span>]
|
32
|
+
assert_equal expected, @inline.tag(:span, :class => "greetings", :id => "hi") { "Hi!" }
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_nested_tags
|
36
|
+
expected = %[<span class="greetings"><strong id="hi">Hi!</strong></span>]
|
37
|
+
actual = @inline.tag(:span, :class => "greetings") { tag(:strong, "Hi!", :id => "hi") }
|
38
|
+
assert_equal expected, actual
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_render_as_list
|
42
|
+
@breadcrumbs.add "Home", "/", :class => "home"
|
43
|
+
html = Nokogiri::HTML(@breadcrumbs.render)
|
44
|
+
|
45
|
+
assert_not_nil html.at("ul.breadcrumbs")
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_render_as_list_with_custom_attributes
|
49
|
+
@breadcrumbs.add "Home", "/", :class => "home"
|
50
|
+
html = Nokogiri::HTML(@breadcrumbs.render(:id => "breadcrumbs", :class => "top"))
|
51
|
+
|
52
|
+
assert_not_nil html.at("ul.top#breadcrumbs")
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_render_as_list_add_items
|
56
|
+
@breadcrumbs.add "Home", "/", :class => "home"
|
57
|
+
@breadcrumbs.add "About", "/about", :class => "about"
|
58
|
+
@breadcrumbs.add "People"
|
59
|
+
|
60
|
+
html = Nokogiri::HTML(@breadcrumbs.render)
|
61
|
+
items = html.search("li")
|
62
|
+
|
63
|
+
assert_equal 3, items.count
|
64
|
+
|
65
|
+
assert_equal "first item-0", items[0]["class"]
|
66
|
+
assert_equal "Home", items[0].inner_text
|
67
|
+
|
68
|
+
link = items[0].at("a")
|
69
|
+
assert_equal "home", link["class"]
|
70
|
+
assert_equal "/", link["href"]
|
71
|
+
|
72
|
+
assert_equal "item-1", items[1]["class"]
|
73
|
+
assert_equal "About", items[1].inner_text
|
74
|
+
|
75
|
+
link = items[1].at("a")
|
76
|
+
assert_equal "about", link["class"]
|
77
|
+
assert_equal "/about", link["href"]
|
78
|
+
|
79
|
+
assert_equal "last item-2", items[2]["class"]
|
80
|
+
assert_equal "People", items[2].inner_text
|
81
|
+
assert_nil items[2].at("a")
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_render_inline
|
85
|
+
@breadcrumbs.add "Home", "/", :class => "home"
|
86
|
+
html = Nokogiri::HTML(@breadcrumbs.render(:format => :inline))
|
87
|
+
|
88
|
+
assert_nil html.at("ul.breadcrumbs")
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_render_inline_add_items
|
92
|
+
@breadcrumbs.add "Home", "/", :class => "home"
|
93
|
+
@breadcrumbs.add "About", "/about", :class => "about"
|
94
|
+
@breadcrumbs.add "People"
|
95
|
+
|
96
|
+
html = @breadcrumbs.render(:format => :inline)
|
97
|
+
html = Nokogiri::HTML("<div>#{html}</div>")
|
98
|
+
separator = Nokogiri::HTML("<span>»</span>").at("span").inner_text
|
99
|
+
|
100
|
+
items = html.search("div *")
|
101
|
+
|
102
|
+
assert_equal 5, items.count
|
103
|
+
|
104
|
+
assert_equal "a", items[0].name
|
105
|
+
assert_equal "home first item-0", items[0]["class"]
|
106
|
+
assert_equal "Home", items[0].inner_text
|
107
|
+
assert_equal "/", items[0]["href"]
|
108
|
+
|
109
|
+
assert_equal "span", items[1].name
|
110
|
+
assert_equal "separator", items[1]["class"]
|
111
|
+
assert_equal separator, items[1].inner_text
|
112
|
+
|
113
|
+
assert_equal "a", items[2].name
|
114
|
+
assert_equal "about item-1", items[2]["class"]
|
115
|
+
assert_equal "About", items[2].inner_text
|
116
|
+
assert_equal "/about", items[2]["href"]
|
117
|
+
|
118
|
+
assert_equal "span", items[3].name
|
119
|
+
assert_equal "separator", items[3]["class"]
|
120
|
+
assert_equal separator, items[3].inner_text
|
121
|
+
|
122
|
+
assert_equal "span", items[4].name
|
123
|
+
assert_equal "last item-2", items[4]["class"]
|
124
|
+
assert_equal "People", items[4].inner_text
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_render_inline_with_custom_separator
|
128
|
+
@breadcrumbs.add "Home", "/", :class => "home"
|
129
|
+
@breadcrumbs.add "People"
|
130
|
+
|
131
|
+
html = Nokogiri::HTML(@breadcrumbs.render(:format => :inline, :separator => "|"))
|
132
|
+
|
133
|
+
assert_equal "|", html.at("span.separator").inner_text
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_render_internationalized_text_using_default_scope
|
137
|
+
@breadcrumbs.add :home
|
138
|
+
@breadcrumbs.add :people
|
139
|
+
|
140
|
+
html = Nokogiri::HTML(@breadcrumbs.render)
|
141
|
+
|
142
|
+
items = html.search("li")
|
143
|
+
|
144
|
+
assert_equal "Página inicial", items[0].inner_text
|
145
|
+
assert_equal "Nosso time", items[1].inner_text
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_pimp_action_controller
|
149
|
+
methods = ActionController::Base.instance_methods
|
150
|
+
assert (methods.include?(:breadcrumbs) || methods.include?("breadcrumbs"))
|
151
|
+
end
|
152
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: breadcrumbs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Nando Vieira
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-24 00:00:00 -03:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rails
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description: Breadcrumbs is a simple plugin that adds a `breadcrumbs` object to controllers and views.
|
33
|
+
email: fnando.vieira@gmail.com
|
34
|
+
executables: []
|
35
|
+
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files:
|
39
|
+
- README.rdoc
|
40
|
+
files:
|
41
|
+
- README.rdoc
|
42
|
+
- lib/breadcrumbs.rb
|
43
|
+
- lib/breadcrumbs/action_controller_ext.rb
|
44
|
+
- lib/breadcrumbs/render.rb
|
45
|
+
- lib/breadcrumbs/render/base.rb
|
46
|
+
- lib/breadcrumbs/render/inline.rb
|
47
|
+
- lib/breadcrumbs/render/list.rb
|
48
|
+
- lib/breadcrumbs/version.rb
|
49
|
+
- test/breadcrumbs_test.rb
|
50
|
+
- test/resources/pt.yml
|
51
|
+
- test/test_helper.rb
|
52
|
+
has_rdoc: true
|
53
|
+
homepage: http://github.com/fnando/games_radar
|
54
|
+
licenses: []
|
55
|
+
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options:
|
58
|
+
- --charset=UTF-8
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
requirements: []
|
76
|
+
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.3.6
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: Breadcrumbs is a simple plugin that adds a `breadcrumbs` object to controllers and views.
|
82
|
+
test_files:
|
83
|
+
- test/breadcrumbs_test.rb
|
84
|
+
- test/test_helper.rb
|