show_for 0.2.4 → 0.2.5

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.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,12 @@
1
+ == 0.2.5
2
+
3
+ * enhancements
4
+ * Add a :value option for attribute (by github.com/ml-gt)
5
+ * Add label_class, content_class, wrapper_class and content_class configuration options (by github.com/wojtekmach)
6
+
7
+ * bug fix
8
+ * Fix problem with label => false and html_safe (label => false) (by github.com/nashby)
9
+
1
10
  == 0.2.4
2
11
 
3
12
  * enhancements
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 PlataformaTec http://blog.plataformatec.com.br/
1
+ Copyright (c) 2012 PlataformaTec http://blog.plataformatec.com.br/
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -22,7 +22,7 @@ ShowFor.setup do |config|
22
22
  # config.collection_tag = :ul
23
23
 
24
24
  # The default iterator to be used when invoking a collection/association.
25
- # config.default_collection_proc = lambda { |value| "<li>#{value}</li>" }
25
+ # config.default_collection_proc = lambda { |value| "<li>#{ERB::Util.h(value)}</li>".html_safe }
26
26
 
27
27
  # The default format to be used in I18n when localizing a Date/Time.
28
28
  # config.i18n_format = :default
@@ -21,7 +21,7 @@ module ShowFor
21
21
  block
22
22
  else
23
23
  association = @object.send(association_name)
24
- values = retrieve_values_from_association(association, options)
24
+ values = values_from_association(association, options)
25
25
 
26
26
  if options.delete(:to_sentence)
27
27
  values.to_sentence
@@ -37,7 +37,7 @@ module ShowFor
37
37
 
38
38
  protected
39
39
 
40
- def retrieve_values_from_association(association, options) #:nodoc:
40
+ def values_from_association(association, options) #:nodoc:
41
41
  sample = association.is_a?(Array) ? association.first : association
42
42
 
43
43
  if options[:method]
@@ -2,15 +2,10 @@ module ShowFor
2
2
  module Attribute
3
3
  def attribute(attribute_name, options={}, &block)
4
4
  apply_default_options!(attribute_name, options)
5
+ block = block_from_value_option(attribute_name, options) unless block
5
6
  collection_block, block = block, nil if collection_block?(block)
6
7
 
7
- value = if block
8
- block
9
- elsif @object.respond_to?(:"human_#{attribute_name}")
10
- @object.send :"human_#{attribute_name}"
11
- else
12
- @object.send(attribute_name)
13
- end
8
+ value = attribute_value(attribute_name, &block)
14
9
 
15
10
  wrap_label_and_content(attribute_name, value, options, &collection_block)
16
11
  end
@@ -19,20 +14,48 @@ module ShowFor
19
14
  apply_default_options!(attribute_name, options)
20
15
  collection_block, block = block, nil if collection_block?(block)
21
16
 
22
- value = if block
17
+ value = attribute_value(attribute_name, &block)
18
+
19
+ wrap_content(attribute_name, value, options, &collection_block)
20
+ end
21
+
22
+ def attributes(*attribute_names)
23
+ attribute_names.map do |attribute_name|
24
+ attribute(attribute_name)
25
+ end.join.html_safe
26
+ end
27
+
28
+ private
29
+
30
+ def attribute_value(attribute_name, &block)
31
+ if block
23
32
  block
24
33
  elsif @object.respond_to?(:"human_#{attribute_name}")
25
34
  @object.send :"human_#{attribute_name}"
26
35
  else
27
36
  @object.send(attribute_name)
28
37
  end
29
- wrap_content(attribute_name, value, options, &collection_block)
30
38
  end
31
39
 
32
- def attributes(*attribute_names)
33
- attribute_names.map do |attribute_name|
34
- attribute(attribute_name)
35
- end.join.html_safe
40
+ def block_from_value_option(attribute_name, options)
41
+ case options[:value]
42
+ when nil
43
+ nil
44
+ when Symbol
45
+ block_from_symbol(attribute_name, options)
46
+ else
47
+ lambda { options[:value] }
48
+ end
49
+ end
50
+
51
+ def block_from_symbol(attribute_name, options)
52
+ attribute = @object.send(attribute_name)
53
+ case attribute
54
+ when Array, Hash
55
+ lambda { |element| element.send(options[:value]) }
56
+ else
57
+ lambda { attribute.send(options[:value]) }
58
+ end
36
59
  end
37
60
  end
38
61
  end
@@ -36,7 +36,7 @@ module ShowFor
36
36
  def apply_default_options!(name, options) #:nodoc:
37
37
  html_class = "#{object_name}_#{name}".gsub(/\W/, '')
38
38
  wrapper_html = options[:wrapper_html] ||= {}
39
- wrapper_html[:class] = "#{html_class} #{wrapper_html[:class]}".strip
39
+ wrapper_html[:class] = "#{html_class} #{wrapper_html[:class]}".rstrip
40
40
  end
41
41
 
42
42
  # Gets the default tag set in ShowFor module and apply (if defined)
@@ -45,15 +45,14 @@ module ShowFor
45
45
  def wrap_with(type, content, options) #:nodoc:
46
46
  tag = options.delete(:"#{type}_tag") || ShowFor.send(:"#{type}_tag")
47
47
 
48
- html = if tag
48
+ if tag
49
+ type_class = ShowFor.send :"#{type}_class"
49
50
  html_options = options.delete(:"#{type}_html") || {}
50
- html_options[:class] = "#{type} #{html_options[:class]}".strip
51
+ html_options[:class] = "#{type_class} #{html_options[:class]}".rstrip
51
52
  @template.content_tag(tag, content, html_options)
52
53
  else
53
54
  content
54
55
  end
55
-
56
- html
57
56
  end
58
57
 
59
58
  # Returns true if the block is supposed to iterate through a collection,
@@ -27,7 +27,7 @@ module ShowFor
27
27
  value
28
28
  end
29
29
 
30
- options[:content_html] = options.dup if apply_options
30
+ options[:content_html] = options.except(:content_tag) if apply_options
31
31
  wrap_with(:content, content, options)
32
32
  end
33
33
 
@@ -35,13 +35,12 @@ module ShowFor
35
35
 
36
36
  def collection_handler(value, options, &block) #:nodoc:
37
37
  iterator = collection_block?(block) ? block : ShowFor.default_collection_proc
38
- response = ""
39
38
 
40
- value.each do |item|
41
- response << template.capture(item, &iterator)
42
- end
39
+ response = value.map do |item|
40
+ template.capture(item, &iterator)
41
+ end.join.html_safe
43
42
 
44
- wrap_with(:collection, response.html_safe, options)
43
+ wrap_with(:collection, response, options)
45
44
  end
46
45
  end
47
- end
46
+ end
@@ -13,7 +13,7 @@ module ShowFor
13
13
  tag = html_options.delete(:show_for_tag) || ShowFor.show_for_tag
14
14
 
15
15
  html_options[:id] ||= dom_id(object)
16
- html_options[:class] = "show_for #{dom_class(object)} #{html_options[:class]}".strip
16
+ html_options[:class] = "show_for #{dom_class(object)} #{html_options[:class]}".rstrip
17
17
 
18
18
  builder = html_options.delete(:builder) || ShowFor::Builder
19
19
  content = capture(builder.new(object, self), &block)
@@ -9,7 +9,7 @@ module ShowFor
9
9
  human_attribute_name(text_or_attribute)
10
10
  end
11
11
 
12
- return nil.to_s if label == false
12
+ return ''.html_safe if label == false
13
13
  options[:label_html] = options.dup if apply_options
14
14
 
15
15
  label = ShowFor.label_proc.call(label) if options.fetch(:wrap_label, true) && ShowFor.label_proc
@@ -1,3 +1,3 @@
1
1
  module ShowFor
2
- VERSION = "0.2.4".freeze
2
+ VERSION = "0.2.5".freeze
3
3
  end
data/lib/show_for.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'action_view'
1
2
  require 'show_for/helper'
2
3
 
3
4
  module ShowFor
@@ -9,21 +10,33 @@ module ShowFor
9
10
  mattr_accessor :label_tag
10
11
  @@label_tag = :strong
11
12
 
13
+ mattr_accessor :label_class
14
+ @@label_class = :label
15
+
12
16
  mattr_accessor :separator
13
17
  @@separator = "<br />"
14
18
 
15
19
  mattr_accessor :content_tag
16
20
  @@content_tag = nil
17
21
 
22
+ mattr_accessor :content_class
23
+ @@content_class = :content
24
+
18
25
  mattr_accessor :blank_content_class
19
26
  @@blank_content_class = "blank"
20
27
 
21
28
  mattr_accessor :wrapper_tag
22
29
  @@wrapper_tag = :p
23
30
 
31
+ mattr_accessor :wrapper_class
32
+ @@wrapper_class = :wrapper
33
+
24
34
  mattr_accessor :collection_tag
25
35
  @@collection_tag = :ul
26
36
 
37
+ mattr_accessor :collection_class
38
+ @@collection_class = :collection
39
+
27
40
  mattr_accessor :default_collection_proc
28
41
  @@default_collection_proc = lambda { |value| "<li>#{ERB::Util.html_escape(value)}</li>".html_safe }
29
42
 
@@ -32,7 +45,7 @@ module ShowFor
32
45
 
33
46
  mattr_accessor :association_methods
34
47
  @@association_methods = [ :name, :title, :to_s ]
35
-
48
+
36
49
  mattr_accessor :label_proc
37
50
  @@label_proc = nil
38
51
 
@@ -45,4 +58,4 @@ module ShowFor
45
58
  def self.setup
46
59
  yield self
47
60
  end
48
- end
61
+ end
@@ -0,0 +1,72 @@
1
+ require 'test_helper'
2
+
3
+ class AssociationTest < ActionView::TestCase
4
+ test "show_for works with belongs_to/has_one associations" do
5
+ with_association_for @user, :company
6
+ assert_select "div.show_for p.wrapper", /PlataformaTec/
7
+ end
8
+
9
+ test "show_for accepts :using as option to tell how to retrieve association value" do
10
+ with_association_for @user, :company, :using => :alternate_name
11
+ assert_select "div.show_for p.wrapper", /Alternate PlataformaTec/
12
+ end
13
+
14
+ test "show_for accepts :in to tell to retrieve an attribute from association" do
15
+ with_attribute_for @user, :alternate_name, :in => :company
16
+ assert_select "div.show_for p.wrapper", /Alternate PlataformaTec/
17
+ end
18
+
19
+ test "show_for forwards all options send with :in to association" do
20
+ with_attribute_for @user, :alternate_name, :in => :tags, :to_sentence => true
21
+ assert_no_select "div.show_for p.wrapper ul.collection"
22
+ assert_select "div.show_for p.wrapper", /Alternate Tag 1, Alternate Tag 2, and Alternate Tag 3/
23
+ end
24
+
25
+ test "show_for works with has_many/has_and_belongs_to_many associations" do
26
+ with_association_for @user, :tags
27
+ assert_select "div.show_for p.wrapper ul.collection"
28
+ assert_select "div.show_for p.wrapper ul.collection li", "Tag 1"
29
+ assert_select "div.show_for p.wrapper ul.collection li", "Tag 2"
30
+ assert_select "div.show_for p.wrapper ul.collection li", "Tag 3"
31
+ end
32
+
33
+ test "show_for accepts :using as option to tell how to retrieve association values" do
34
+ with_association_for @user, :tags, :using => :alternate_name
35
+ assert_select "div.show_for p.wrapper ul.collection"
36
+ assert_select "div.show_for p.wrapper ul.collection li", "Alternate Tag 1"
37
+ assert_select "div.show_for p.wrapper ul.collection li", "Alternate Tag 2"
38
+ assert_select "div.show_for p.wrapper ul.collection li", "Alternate Tag 3"
39
+ end
40
+
41
+ test "show_for accepts :to_sentence as option in collection associations" do
42
+ with_association_for @user, :tags, :to_sentence => true
43
+ assert_no_select "div.show_for p.wrapper ul.collection"
44
+ assert_select "div.show_for p.wrapper", /Tag 1, Tag 2, and Tag 3/
45
+ end
46
+
47
+ test "show_for accepts :join as option in collection associations" do
48
+ with_association_for @user, :tags, :join => ", "
49
+ assert_no_select "div.show_for p.wrapper ul.collection"
50
+ assert_select "div.show_for p.wrapper", /Tag 1, Tag 2, Tag 3/
51
+ end
52
+
53
+ test "show_for accepts a block without argument in collection associations" do
54
+ with_association_for @user, :tags do
55
+ @user.tags.map(&:name).to_sentence
56
+ end
57
+ assert_no_select "div.show_for p.wrapper ul.collection"
58
+ assert_select "div.show_for p.wrapper", /Tag 1, Tag 2, and Tag 3/
59
+ end
60
+
61
+ test "show_for accepts a block with argument in collection associations" do
62
+ with_association_for @user, :tags, :collection_tag => :p do |tag|
63
+ assert_kind_of Tag, tag
64
+ content_tag(:span, tag.name)
65
+ end
66
+ assert_no_select "div.show_for p.wrapper ul.collection"
67
+ assert_select "div.show_for p.wrapper p.collection"
68
+ assert_select "div.show_for p.wrapper p.collection span", "Tag 1"
69
+ assert_select "div.show_for p.wrapper p.collection span", "Tag 2"
70
+ assert_select "div.show_for p.wrapper p.collection span", "Tag 3"
71
+ end
72
+ end
@@ -0,0 +1,167 @@
1
+ require 'test_helper'
2
+
3
+ class AttributeTest < ActionView::TestCase
4
+ # COLLECTIONS
5
+ test "show_for accepts an attribute as a collection" do
6
+ with_attribute_for @user, :scopes
7
+ assert_select "div.show_for p.wrapper ul.collection"
8
+ assert_select "div.show_for p.wrapper ul.collection li", :count => 3
9
+ end
10
+
11
+ test "show_for accepts an attribute as a collection with a block to iterate the collection" do
12
+ with_attribute_for @user, :scopes do |scope|
13
+ content_tag :span, scope
14
+ end
15
+ assert_select "div.show_for p.wrapper ul.collection"
16
+ assert_select "div.show_for p.wrapper ul.collection span", :count => 3
17
+ end
18
+
19
+ test "show_for treats symbol for :value as method on each element of collection" do
20
+ with_attribute_for @user, :scopes, :value => :upcase
21
+ @user.scopes.each do |scope|
22
+ assert_select "div.show_for p.wrapper ul.collection", /#{scope.upcase}/
23
+ end
24
+ end
25
+
26
+ test "show_for allows collection tag to be configured globally" do
27
+ swap ShowFor, :collection_tag => :ol, :collection_class => "my_collection" do
28
+ with_attribute_for @user, :scopes
29
+ assert_select "div.show_for p.wrapper ol.my_collection"
30
+ end
31
+ end
32
+
33
+ test "show_for allows collection tag to be changed by attribute" do
34
+ with_attribute_for @user, :scopes, :collection_tag => :ol
35
+ assert_select "div.show_for p.wrapper ol.collection"
36
+ end
37
+
38
+ test "show_for allows collection tag html to be configured by attribute" do
39
+ with_attribute_for @user, :scopes, :collection_html => { :id => "thecollection", :class => "special" }
40
+ assert_select "div.show_for p.wrapper ul#thecollection.special.collection"
41
+ end
42
+
43
+ # CONTENT
44
+ test "show_for allows content tag to be configured globally" do
45
+ swap ShowFor, :content_tag => :span, :content_class => :my_content do
46
+ with_attribute_for @user, :name
47
+ assert_select "div.show_for p.wrapper span.my_content"
48
+ end
49
+ end
50
+
51
+ test "show_for allows content tag to be changed by attribute" do
52
+ with_attribute_for @user, :name, :content_tag => :span
53
+ assert_select "div.show_for p.wrapper span.content"
54
+ end
55
+
56
+ test "show_for allows content tag html to be configured by attribute" do
57
+ with_attribute_for @user, :name, :content_tag => :span, :content_html => { :id => "thecontent", :class => "special" }
58
+ assert_select "div.show_for p.wrapper span#thecontent.special.content"
59
+ end
60
+
61
+ test "show_for accepts an attribute as string" do
62
+ with_attribute_for @user, :name
63
+ assert_select "div.show_for p.wrapper", /ShowFor/
64
+ end
65
+
66
+ test "show_for accepts an attribute as time" do
67
+ with_attribute_for @user, :created_at
68
+ assert_select "div.show_for p.wrapper", /#{Regexp.escape(I18n.l(@user.created_at))}/
69
+ end
70
+
71
+ test "show_for accepts an attribute as date" do
72
+ with_attribute_for @user, :updated_at
73
+ assert_select "div.show_for p.wrapper", /#{Regexp.escape(I18n.l(@user.updated_at))}/
74
+ end
75
+
76
+ test "show_for accepts an attribute as time with format options" do
77
+ with_attribute_for @user, :created_at, :format => :long
78
+ assert_select "div.show_for p.wrapper", /#{Regexp.escape(I18n.l(@user.created_at, :format => :long))}/
79
+ end
80
+
81
+ test "show_for accepts an attribute as true" do
82
+ with_attribute_for @user, :active
83
+ assert_select "div.show_for p.wrapper", /Yes/
84
+ end
85
+
86
+ test "show_for accepts an attribute as true which can be localized" do
87
+ store_translations(:en, :show_for => { :yes => "Hell yeah!" }) do
88
+ with_attribute_for @user, :active
89
+ assert_select "div.show_for p.wrapper", /Hell yeah!/
90
+ end
91
+ end
92
+
93
+ test "show_for accepts an attribute as false" do
94
+ with_attribute_for @user, :invalid
95
+ assert_select "div.show_for p.wrapper", /No/
96
+ end
97
+
98
+ test "show_for accepts an attribute as false which can be localized" do
99
+ store_translations(:en, :show_for => { :no => "Hell no!" }) do
100
+ with_attribute_for @user, :invalid
101
+ assert_select "div.show_for p.wrapper", /Hell no!/
102
+ end
103
+ end
104
+
105
+ test "show_for accepts nil and or blank attributes" do
106
+ with_attribute_for @user, :description
107
+ assert_select "div.show_for p.wrapper", /Not specified/
108
+ end
109
+
110
+ test "show_for accepts not spcified message can be localized" do
111
+ store_translations(:en, :show_for => { :blank => "OMG! It's blank!" }) do
112
+ with_attribute_for @user, :description
113
+ assert_select "div.show_for p.wrapper", /OMG! It's blank!/
114
+ end
115
+ end
116
+
117
+ test "show_for uses :if_blank if attribute is blank" do
118
+ with_attribute_for @user, :description, :if_blank => "No description provided"
119
+ assert_select "div.show_for p.wrapper", /No description provided/
120
+ end
121
+
122
+ test "show_for accepts a block to supply the content" do
123
+ with_attribute_for @user, :description do
124
+ "This description is not blank"
125
+ end
126
+ assert_select "div.show_for p.wrapper", /This description/
127
+ end
128
+
129
+ test "show_for escapes content by default" do
130
+ @user.name = "<b>hack you!</b>"
131
+ with_attribute_for @user, :name
132
+ assert_no_select "div.show_for p.wrapper b"
133
+ assert_select "div.show_for p.wrapper", /&lt;b&gt;/
134
+ end
135
+
136
+ test "show_for works with html_safe marked strings" do
137
+ @user.name = "<b>hack you!</b>".html_safe
138
+ with_attribute_for @user, :name
139
+ assert_select "div.show_for p.wrapper b", "hack you!"
140
+ end
141
+
142
+ test "show_for uses :value if supplied" do
143
+ with_attribute_for @user, :name, :value => "Calculated Value"
144
+ assert_select "div.show_for p.wrapper", /Calculated Value/
145
+ end
146
+
147
+ test "show_for ignores :value if a block is supplied" do
148
+ with_attribute_for @user, :name, :value => "Calculated Value" do
149
+ @user.name.upcase
150
+ end
151
+ assert_select "div.show_for p.wrapper", /#{@user.name.upcase}/
152
+ end
153
+
154
+ test "show_for treats symbol for :value as method on attribute" do
155
+ with_attribute_for @user, :name, :value => :upcase
156
+ assert_select "div.show_for p.wrapper", /#{@user.name.upcase}/
157
+ end
158
+
159
+ # ATTRIBUTES
160
+ test "show_for attributes wraps each attribute with a label and content" do
161
+ with_attributes_for @user, :name, :email
162
+ assert_select "div.show_for p.user_name.wrapper", /ShowFor/
163
+ assert_select "p.user_name strong.label", "Super User Name!"
164
+ assert_select "div.show_for p.user_email.wrapper", /Not specified/
165
+ assert_select "p.user_email strong.label", "Email"
166
+ end
167
+ end