railsgarden-message_block 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ * [0.1.0] Initial Version
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Ben Hughes
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,59 @@
1
+ == Message Block
2
+
3
+ Implements the common view pattern by which a list of messages are shown at the top,
4
+ often a combination of flash messages and ActiveRecord validation issues on one or more models.
5
+ This allows for a nice, stylized block of messages at the top of the page with icons
6
+ indicating what type of message it is (error, confirmation, warning, etc.)
7
+
8
+ This view helper acts as a replacement for error_messages_for by taking error messages
9
+ from your models and combing them with flash messages (multiple types such as error, confirm, etc.)
10
+ and outputting them to your view. This plugin comes with an example stylesheet and images.
11
+
12
+ == Usage
13
+
14
+ Once you install this, you should now have a set of images at public/images/message_block and
15
+ a basic stylesheet installed at public/stylesheets/message_block.css. First you'll want to either
16
+ reference this in your layout or copy the declarations to your main layout. Then you can use
17
+ the helper <tt><%= message_block %></tt> as described below:
18
+
19
+ The first argument specifies a hash options:
20
+
21
+ * <tt>:on</tt> - specifies one or many model names for which to check error messages.
22
+ * <tt>:model_error_type</tt> - specifies the message type to use for validation errors; defaults to 'error'
23
+ * <tt>:flash_types</tt> - specifies the keys to check in the flash hash. Messages will be grouped in ul
24
+ lists according to this type. Defaults to: %w(back confirm error info warn)
25
+ * <tt>:html</tt> - Specifies HTML options for the containing div
26
+ * <tt>:id</tt> - Specifies ID of the containing div; defaults to 'message_block'
27
+ * <tt>:class</tt> - Specifies class name of the containing div; defaults to nothing.
28
+
29
+ === Example
30
+ Imagine you have a form for entering a user and a comment:
31
+
32
+ <%= message_block :on => [:user, :comment] %>
33
+
34
+ Imagine also you set these flash variables in the controller:
35
+ class CommentsController
36
+ def create
37
+ flash.now[:error] = "Error A"
38
+ flash.now[:confirm] = "Confirmation A" # Note you can use different types
39
+ flash.now[:warn] = ["Warn A", "Warn B"] # Can set to an array for multiple messages
40
+ end
41
+ end
42
+
43
+ And let's say that you want to show these messages but also show the validation issues
44
+ given that both user and comment fail ActiveRecord validation:
45
+
46
+ <div id="message_block">
47
+ <ul class="error">
48
+ <li>Error A</li>
49
+ <li>User first name is required.</li>
50
+ <li>Comment contents is required.</li>
51
+ </ul>
52
+ <ul class="confirm">
53
+ <li>Confirmation A</li>
54
+ </ul>
55
+ <ul class="warn">
56
+ <li>Warn A</li>
57
+ <li>Warn B</li>
58
+ </ul>
59
+ </div>
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'echoe'
3
+ require 'rake'
4
+ require 'rake/testtask'
5
+ require 'rake/rdoctask'
6
+
7
+ desc 'Default: run unit tests.'
8
+ task :default => :test
9
+
10
+ desc 'Test the message_block plugin.'
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.libs << 'lib'
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = true
16
+ end
17
+
18
+ desc 'Generate documentation for the message_block plugin.'
19
+ Rake::RDocTask.new(:rdoc) do |rdoc|
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = 'MessageBlock'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('README')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
26
+
27
+
28
+ Echoe.new('message_block', '0.1.0') do |p|
29
+ p.description = "Handle multiple flash messages and ActiveRecord validation errors with ease."
30
+ p.url = "http://github.com/railsgarden/message_block"
31
+ p.author = "Ben Hughes"
32
+ p.email = "ben@railsgarden.com"
33
+ p.ignore_pattern = ["tmp/*", "script/*"]
34
+ p.development_dependencies = []
35
+ end
36
+
37
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
38
+
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,38 @@
1
+ #message_block {
2
+ clear: both;
3
+ margin-top: 0.2em;
4
+ margin-bottom: 0.3em;
5
+ }
6
+
7
+ #message_block ul {
8
+ margin-bottom: 0;
9
+ list-style: none;
10
+ padding: 4px;
11
+ }
12
+ #message_block ul li {
13
+ margin-left: 3em;
14
+ }
15
+
16
+ #message_block ul.error {
17
+ border-top: 1px solid #ecd757;
18
+ border-bottom: 1px solid #ecd757;
19
+ background: #fcf6d0 url(../../images/message_block/error_m.gif) 1em 50% no-repeat;
20
+ }
21
+
22
+ #message_block ul.info {
23
+ border-top: 1px solid #ecd757;
24
+ border-bottom: 1px solid #ecd757;
25
+ background: #fcf6d0 url(../../images/message_block/info_m.gif) 1em 50% no-repeat;
26
+ }
27
+
28
+ #message_block ul.confirm {
29
+ border-top: 1px solid #ecd757;
30
+ border-bottom: 1px solid #ecd757;
31
+ background: #fcf6d0 url(../../images/message_block/confirmation_m.gif) 1em 50% no-repeat;
32
+ }
33
+
34
+ #message_block ul.warn {
35
+ border-top: 1px solid #ecd757;
36
+ border-bottom: 1px solid #ecd757;
37
+ background: #fcf6d0 url(../../images/message_block/warn_m.gif) 1em 50% no-repeat;
38
+ }
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'message_block'
data/install.rb ADDED
@@ -0,0 +1,21 @@
1
+ puts "Copying assets..."
2
+
3
+ images_source = File.join(File.dirname(__FILE__), "assets", "images")
4
+ stylesheets_source = File.join(File.dirname(__FILE__), "assets", "stylesheets", "message_block.css")
5
+
6
+ images_target = File.join(RAILS_ROOT, "public", "images", "message_block")
7
+ stylesheets_target = File.join(RAILS_ROOT, "public", "stylesheets", "message_block.css")
8
+
9
+ unless File.exists?(images_target)
10
+ FileUtils.cp_r(images_source, images_target)
11
+ puts " Copied Images"
12
+ else
13
+ puts " Images appear to already be installed, not copying."
14
+ end
15
+
16
+ unless File.exists?(stylesheets_target)
17
+ FileUtils.cp(stylesheets_source, stylesheets_target)
18
+ puts " Copied Stylesheet"
19
+ else
20
+ puts " Stylesheet appears to already be installed, not copying"
21
+ end
@@ -0,0 +1,3 @@
1
+ require_dependency 'message_block/helpers'
2
+
3
+ ActionView::Base.send(:include, Rubiety::MessageBlock::Helpers)
@@ -0,0 +1,51 @@
1
+ module Rubiety
2
+ module MessageBlock
3
+ module Helpers
4
+
5
+ def message_block(options = {})
6
+ options.assert_valid_keys(:on, :model_error_type, :flash_types, :html, :id, :class)
7
+
8
+ options[:model_error_type] ||= :error
9
+ options[:flash_types] ||= [:back, :confirm, :error, :info, :warn]
10
+ options[:on] ||= controller.controller_name.split('/').last.gsub(/\_controller$/, '').singularize.to_sym
11
+ options[:html] ||= {:id => 'message_block'}
12
+ options[:html][:id] = options[:id] if options[:id]
13
+ options[:html][:class] = options[:class] if options[:class]
14
+
15
+ flash_messages = {}
16
+
17
+ options[:flash_types].each do |type|
18
+ entries = flash[type.to_sym]
19
+ next if entries.nil?
20
+ entries = [entries] unless entries.is_a?(Array)
21
+
22
+ flash_messages[type.to_sym] ||= []
23
+ flash_messages[type.to_sym] += entries
24
+ end
25
+
26
+ options[:on] = [options[:on]] unless options[:on].is_a?(Array)
27
+
28
+ options[:on] = [options[:on]] unless options[:on].is_a?(Array)
29
+ model_objects = options[:on].map do |model_object|
30
+ if model_object.instance_of?(String) or model_object.instance_of?(Symbol)
31
+ instance_variable_get("@#{model_object}")
32
+ else
33
+ model_object
34
+ end
35
+ end.select {|m| !m.nil? }
36
+
37
+ model_errors = model_objects.inject([]) {|b, m| b += m.errors.full_messages }
38
+
39
+ flash_messages[options[:model_error_type].to_sym] ||= []
40
+ flash_messages[options[:model_error_type].to_sym] += model_errors
41
+
42
+ contents = flash_messages.keys.select {|type| !flash_messages[type.to_sym].empty? }.map do |type|
43
+ content_tag(:ul, flash_messages[type.to_sym].map {|message| content_tag(:li, message) }.join, :class => type)
44
+ end.join
45
+
46
+ content_tag(:div, contents, options[:html])
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{message_block}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Ben Hughes"]
9
+ s.date = %q{2009-01-16}
10
+ s.description = %q{Handle multiple flash messages and ActiveRecord validation errors with ease.}
11
+ s.email = %q{ben@railsgarden.com}
12
+ s.extra_rdoc_files = ["CHANGELOG", "lib/message_block/helpers.rb", "lib/message_block.rb", "README.rdoc"]
13
+ s.files = ["assets/images/back.gif", "assets/images/back_m.gif", "assets/images/confirmation.gif", "assets/images/confirmation_m.gif", "assets/images/error.gif", "assets/images/error_m.gif", "assets/images/info.gif", "assets/images/info_m.gif", "assets/images/warn.gif", "assets/images/warn_m.gif", "assets/stylesheets/message_block.css", "CHANGELOG", "init.rb", "install.rb", "lib/message_block/helpers.rb", "lib/message_block.rb", "MIT-LICENSE", "Rakefile", "README.rdoc", "test/message_block_helper_test.rb", "Manifest", "message_block.gemspec"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/railsgarden/message_block}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Message_block", "--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{message_block}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Handle multiple flash messages and ActiveRecord validation errors with ease.}
21
+ s.test_files = ["test/message_block_helper_test.rb"]
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 2
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ else
29
+ end
30
+ else
31
+ end
32
+ end
@@ -0,0 +1,193 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'action_pack'
4
+ require 'action_view'
5
+
6
+ $:.unshift File.dirname(__FILE__) + '/../lib'
7
+ require File.dirname(__FILE__) + '/../init'
8
+
9
+ class MessageBlockHelperTest < Test::Unit::TestCase
10
+ include ActionView::Helpers::TagHelper
11
+ include Rubiety::MessageBlock::Helpers
12
+
13
+ # Borrowed model stubs from Rails active_record_helper_test.rb
14
+ # TODO: Re-implement using mocha
15
+ Post = Struct.new("Post", :title, :author_name)
16
+ User = Struct.new("User", :email)
17
+
18
+ def setup_post
19
+ @post = Post.new
20
+ def @post.errors
21
+ Class.new do
22
+ def on(field)
23
+ case field.to_s
24
+ when "author_name"
25
+ "can't be empty"
26
+ when "body"
27
+ true
28
+ else
29
+ false
30
+ end
31
+ end
32
+ def empty?() false end
33
+ def count() 1 end
34
+ def full_messages() [ "Author name can't be empty" ] end
35
+ end.new
36
+ end
37
+
38
+ @post.title = "Hello World"
39
+ @post.author_name = ""
40
+ end
41
+
42
+ def setup_user
43
+ @user = User.new
44
+ def @user.errors
45
+ Class.new {
46
+ def on(field) field == "email" end
47
+ def empty?() false end
48
+ def count() 1 end
49
+ def full_messages() [ "User email can't be empty" ] end
50
+ }.new
51
+ end
52
+
53
+ @user.email = ""
54
+ end
55
+
56
+ def controller
57
+ @controller ||= Class.new {
58
+ def controller_name
59
+ "widgets_controller"
60
+ end
61
+ }.new
62
+ end
63
+
64
+ def posts_controller
65
+ Class.new {
66
+ def controller_name
67
+ "posts_controller"
68
+ end
69
+ }.new
70
+ end
71
+
72
+ def flash
73
+ @flash ||= {}
74
+ end
75
+
76
+
77
+ def setup
78
+ setup_post
79
+ setup_user
80
+ end
81
+
82
+
83
+ ### Generic Invocation
84
+ def test_doesnt_accept_invalid_options
85
+ assert_raise(ArgumentError) { message_block :invalid => 'value' }
86
+ end
87
+
88
+ def test_accepts_valid_options
89
+ assert_nothing_raised do
90
+ message_block :on => :post,
91
+ :model_error_type => "fail",
92
+ :flash_types => %w(error warn),
93
+ :html => {:style => 'height: 10em'},
94
+ :id => "block",
95
+ :class => "messages"
96
+ end
97
+ end
98
+
99
+
100
+ ### Grabbing model errors functionality
101
+ def test_without_errors_should_show_nothing
102
+ expected = %(<div id="message_block"></div>)
103
+ assert_equal expected, message_block
104
+ end
105
+
106
+ def test_automatically_find_post_errors_with_posts_controller
107
+ @controller = posts_controller
108
+ expected = %(<div id="message_block"><ul class="error"><li>Author name can't be empty</li></ul></div>)
109
+ assert_equal expected, message_block
110
+ end
111
+
112
+ def test_gives_error_for_post
113
+ expected = %(<div id="message_block"><ul class="error"><li>Author name can't be empty</li></ul></div>)
114
+ assert_equal expected, message_block(:on => :post)
115
+ end
116
+
117
+ def test_gives_error_for_user
118
+ expected = %(<div id="message_block"><ul class="error"><li>User email can't be empty</li></ul></div>)
119
+ assert_equal expected, message_block(:on => :user)
120
+ end
121
+
122
+ def test_gives_both_errors_for_post_and_user
123
+ expected = %(<div id="message_block"><ul class="error"><li>Author name can't be empty</li><li>User email can't be empty</li></ul></div>)
124
+ assert_equal expected, message_block(:on => [:post, :user])
125
+ end
126
+
127
+ def test_gives_both_errors_for_post_and_user_in_correct_order
128
+ expected = %(<div id="message_block"><ul class="error"><li>User email can't be empty</li><li>Author name can't be empty</li></ul></div>)
129
+ assert_equal expected, message_block(:on => [:user, :post])
130
+ end
131
+
132
+ def test_gives_error_for_user_given_direct_instance_variable
133
+ expected = %(<div id="message_block"><ul class="error"><li>User email can't be empty</li></ul></div>)
134
+ assert_equal expected, message_block(:on => @user)
135
+ end
136
+
137
+ def test_respects_model_error_type
138
+ expected = %(<div id="message_block"><ul class="fail"><li>User email can't be empty</li></ul></div>)
139
+ assert_equal expected, message_block(:on => :user, :model_error_type => "fail")
140
+ end
141
+
142
+
143
+ ### Extending HTML options for containing div functionality
144
+ def test_can_specify_id_for_containing_div
145
+ expected = %(<div id="messages"></div>)
146
+ assert_equal expected, message_block(:id => "messages")
147
+ end
148
+
149
+ def test_can_specify_class_for_containing_div
150
+ expected = %(<div class="messages" id="message_block"></div>)
151
+ assert_equal expected, message_block(:class => "messages")
152
+ end
153
+
154
+ def test_can_specify_html_options_for_containing_div
155
+ expected = %(<div class="messages" id="block"></div>)
156
+ assert_equal expected, message_block(:html => {:id => "block", :class => "messages"})
157
+ end
158
+
159
+
160
+ ### Flash messages functionality
161
+ def test_sees_flash_error_string
162
+ flash[:error] = "Error A"
163
+ expected = %(<div id="message_block"><ul class="error"><li>Error A</li></ul></div>)
164
+ assert_equal expected, message_block
165
+ end
166
+
167
+ def test_sees_flash_error_array
168
+ flash[:error] = ["Error A", "Error B"]
169
+ expected = %(<div id="message_block"><ul class="error"><li>Error A</li><li>Error B</li></ul></div>)
170
+ assert_equal expected, message_block
171
+ end
172
+
173
+ def test_sees_default_flash_types
174
+ default_types = [:back, :confirm, :error, :info, :warn]
175
+ default_types.each do |type|
176
+ flash[type] = type.to_s
177
+ end
178
+
179
+ expected_contents = default_types.map do |type|
180
+ content_tag(:ul, content_tag(:li, type.to_s), :class => type.to_s)
181
+ end.join
182
+
183
+ expected = %(<div id="message_block">#{expected_contents}</div>)
184
+ assert_equal expected, message_block
185
+ end
186
+
187
+ def test_sees_flash_error_alongside_model_error
188
+ flash[:error] = "Error A"
189
+ expected = %(<div id="message_block"><ul class="error"><li>Error A</li><li>Author name can't be empty</li></ul></div>)
190
+ assert_equal expected, message_block(:on => :post)
191
+ end
192
+
193
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: railsgarden-message_block
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben Hughes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-16 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Handle multiple flash messages and ActiveRecord validation errors with ease.
17
+ email: ben@railsgarden.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - CHANGELOG
24
+ - lib/message_block/helpers.rb
25
+ - lib/message_block.rb
26
+ - README.rdoc
27
+ files:
28
+ - assets/images/back.gif
29
+ - assets/images/back_m.gif
30
+ - assets/images/confirmation.gif
31
+ - assets/images/confirmation_m.gif
32
+ - assets/images/error.gif
33
+ - assets/images/error_m.gif
34
+ - assets/images/info.gif
35
+ - assets/images/info_m.gif
36
+ - assets/images/warn.gif
37
+ - assets/images/warn_m.gif
38
+ - assets/stylesheets/message_block.css
39
+ - CHANGELOG
40
+ - init.rb
41
+ - install.rb
42
+ - lib/message_block/helpers.rb
43
+ - lib/message_block.rb
44
+ - MIT-LICENSE
45
+ - Rakefile
46
+ - README.rdoc
47
+ - test/message_block_helper_test.rb
48
+ - Manifest
49
+ - message_block.gemspec
50
+ has_rdoc: true
51
+ homepage: http://github.com/railsgarden/message_block
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --line-numbers
55
+ - --inline-source
56
+ - --title
57
+ - Message_block
58
+ - --main
59
+ - README.rdoc
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "1.2"
73
+ version:
74
+ requirements: []
75
+
76
+ rubyforge_project: message_block
77
+ rubygems_version: 1.2.0
78
+ signing_key:
79
+ specification_version: 2
80
+ summary: Handle multiple flash messages and ActiveRecord validation errors with ease.
81
+ test_files:
82
+ - test/message_block_helper_test.rb