message_block 2.0.2 → 3.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 728d32717165e10254ee067aba8906309f06360e3b7e8bf76ca153cb453bde9e
4
+ data.tar.gz: 77e4d255bce525a787f6179d9bd2aaaac71729278c1eda95f6a736dd72e9fba7
5
+ SHA512:
6
+ metadata.gz: 9057573a87565d445102f2a2ecd2234be0e5cd8b1980075c36c3fe1679a148891cbacd5d05365635cbae742a05f1278e6fa2e1516e1e75f23098878a84591ec0
7
+ data.tar.gz: 29157998f8202c7ac07cdfd190104d5a338bc27006b8c52dd0cd76501379f64095cf28876c9bb2eece82d0923b8c8276ff6927d655a782a035db3a3c377dbbbb
data/CHANGELOG.md ADDED
@@ -0,0 +1,35 @@
1
+ # Changelog
2
+
3
+ ## 3.0.0 (October 14, 2026)
4
+
5
+ - Require Rails 6.1+ and Ruby 2.7+; depend on actionview, activemodel and
6
+ railties instead of all of rails
7
+ - **Security:** HTML-escape flash and validation error messages. Messages
8
+ that are already `html_safe` still render as HTML; pass `escape: false`
9
+ to restore the 2.x behavior
10
+ - Add `role="alert"` to the container by default
11
+ - Add the `render_empty` option to always render the container, for use as
12
+ a Turbo Stream target
13
+ - Merge the `:html` option with the default `id` and `class` instead of
14
+ replacing them
15
+ - Stop modifying the options hash passed to `message_block`
16
+ - Replace the ERB stylesheet and GIF icons with plain CSS and inline SVG
17
+ icons that work with both Propshaft and Sprockets
18
+ - Test against Rails 6.1 through 8.1 on GitHub Actions
19
+
20
+ ## 2.0.3 (June 14, 2013)
21
+
22
+ - Fixed path to confirm.gif
23
+
24
+ ## 2.0.2 (February 17, 2013)
25
+
26
+ - Fixed inclusion of vendor from gemspec
27
+
28
+ ## 2.0.1 (February 17, 2013)
29
+
30
+ - Added 'alert' flash message type
31
+
32
+ ## 2.0.0 (February 8, 2013)
33
+
34
+ - Converted assets to use the asset pipeline (instead of a rake task to copy
35
+ assets)
data/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # Message Block
2
+
3
+ [![CI](https://github.com/eigenben/message_block/actions/workflows/ci.yml/badge.svg)](https://github.com/eigenben/message_block/actions/workflows/ci.yml)
4
+
5
+ Implements the common view pattern by which a list of messages are shown at the top of a page, often a combination of flash messages and validation errors on one or more models. One helper call renders a styled block of messages grouped by type (error, confirmation, warning, etc.).
6
+
7
+ ## Requirements
8
+
9
+ - Rails 6.1 or newer
10
+ - Ruby 2.7 or newer
11
+
12
+ For older Rails versions, use message_block 2.x.
13
+
14
+ ## Installation
15
+
16
+ Add the gem to your Gemfile:
17
+
18
+ ```ruby
19
+ gem "message_block", "~> 3.0"
20
+ ```
21
+
22
+ The gem ships an optional stylesheet. With Propshaft (the Rails 8 default), link it in your layout:
23
+
24
+ ```erb
25
+ <%= stylesheet_link_tag "message_block" %>
26
+ ```
27
+
28
+ With Sprockets, require it from `application.css`:
29
+
30
+ ```css
31
+ /*
32
+ *= require message_block
33
+ */
34
+ ```
35
+
36
+ If you use Tailwind, Bootstrap or another CSS framework, you can skip the stylesheet and style the generated markup yourself.
37
+
38
+ ## Usage
39
+
40
+ Call the `message_block` helper in a view or layout:
41
+
42
+ ```erb
43
+ <%= message_block on: [:user, :comment] %>
44
+ ```
45
+
46
+ Given these flash messages in the controller:
47
+
48
+ ```ruby
49
+ class CommentsController < ApplicationController
50
+ def create
51
+ flash.now[:error] = "Error A"
52
+ flash.now[:confirm] = "Confirmation A" # Use whichever types you like
53
+ flash.now[:warn] = ["Warn A", "Warn B"] # Arrays show multiple messages
54
+ end
55
+ end
56
+ ```
57
+
58
+ and given that both `@user` and `@comment` fail validation, the helper renders:
59
+
60
+ ```html
61
+ <div id="message_block" class="message_block" role="alert">
62
+ <ul class="confirm">
63
+ <li>Confirmation A</li>
64
+ </ul>
65
+ <ul class="error">
66
+ <li>Error A</li>
67
+ <li>User first name can't be blank</li>
68
+ <li>Comment contents can't be blank</li>
69
+ </ul>
70
+ <ul class="warn">
71
+ <li>Warn A</li>
72
+ <li>Warn B</li>
73
+ </ul>
74
+ </div>
75
+ ```
76
+
77
+ Nothing is rendered when there are no messages.
78
+
79
+ ### Options
80
+
81
+ | Option | Description | Default |
82
+ | --- | --- | --- |
83
+ | `:on` | One or more models to show validation errors for. Symbols and strings name instance variables (`:user` reads `@user`); model objects are used directly. `:all` uses every view assign that has `ActiveModel::Errors`. | The singular of the controller name, so `PostsController` reads `@post` |
84
+ | `:model_error_type` | The message type that validation errors are grouped under. | `:error` |
85
+ | `:flash_types` | The flash keys to show. | `[:alert, :back, :confirm, :error, :info, :notice, :warn]` |
86
+ | `:html` | HTML attributes for the container, merged with the defaults. | `{ id: "message_block", class: "message_block", role: "alert" }` |
87
+ | `:id` | Shortcut for the container's `id`. | `"message_block"` |
88
+ | `:class` | Shortcut for the container's `class`. | `"message_block"` |
89
+ | `:container` | The element that wraps the lists, or `false` to render the lists alone. | `:div` |
90
+ | `:escape` | Set to `false` to render every message as raw HTML. See [HTML in messages](#html-in-messages). | `true` |
91
+ | `:render_empty` | Render the container even when there are no messages. Useful as a Turbo Stream target. | `false` |
92
+
93
+ ## HTML in messages
94
+
95
+ Messages are HTML-escaped, like any other string you output in a Rails view. Messages that are already `html_safe` are rendered as they are:
96
+
97
+ ```ruby
98
+ flash.now[:notice] = helpers.link_to("View your order", order_path(@order))
99
+ ```
100
+
101
+ Strings put in the flash before a redirect are stored in the session, and whether they stay `html_safe` depends on how the session is serialized. With the JSON cookie serializer (the default for apps on `load_defaults` 7.0 or newer), they come back as plain strings and are escaped. With the older Marshal serializer, they stay `html_safe` and render as HTML. If your app relies on HTML in flash messages across redirects and its session is serialized as JSON, pass `escape: false`. Only do this if no message can contain user input, since it renders every message as raw HTML.
102
+
103
+ ## Turbo
104
+
105
+ To update messages from a Turbo Stream response, render an empty container in your layout so there is always a target:
106
+
107
+ ```erb
108
+ <%= message_block render_empty: true %>
109
+ ```
110
+
111
+ Then update its contents from the stream:
112
+
113
+ ```erb
114
+ <%# app/views/comments/create.turbo_stream.erb %>
115
+ <%= turbo_stream.update "message_block" do %>
116
+ <%= message_block on: :comment, container: false %>
117
+ <% end %>
118
+ ```
119
+
120
+ Set flash messages with `flash.now` in actions that respond with a Turbo Stream. Because the container keeps `role="alert"`, screen readers announce the new messages.
121
+
122
+ ## Styling
123
+
124
+ The bundled stylesheet styles the `error`, `alert`, `warn`, `notice`, `info`, `confirm` and `back` types. Any other type gets a neutral style. Each type sets CSS custom properties that you can override:
125
+
126
+ ```css
127
+ .message_block ul.error {
128
+ --message-block-text: #7f1d1d;
129
+ --message-block-background: #fef2f2;
130
+ --message-block-border: #fecaca;
131
+ --message-block-accent: #dc2626; /* icon color */
132
+ }
133
+ ```
134
+
135
+ ## Upgrading from 2.x
136
+
137
+ - Rails 6.1+ and Ruby 2.7+ are required.
138
+ - Messages are now HTML-escaped. Messages marked `html_safe` still render as HTML. Pass `escape: false` to keep the 2.x behavior; see [HTML in messages](#html-in-messages).
139
+ - The container has `role="alert"` by default. Pass `html: { role: nil }` to remove it.
140
+ - The `:html` option is merged with the default `id` and `class` instead of replacing them.
141
+ - The stylesheet has been rewritten as plain CSS with inline SVG icons, and the `message_block/*.gif` images have been removed.
142
+
143
+ ## Development
144
+
145
+ Run the specs against the current Rails version:
146
+
147
+ ```sh
148
+ bundle install
149
+ bundle exec rspec
150
+ ```
151
+
152
+ Run them against every supported Rails version with [Appraisal](https://github.com/thoughtbot/appraisal):
153
+
154
+ ```sh
155
+ bundle exec appraisal install
156
+ bundle exec appraisal rspec
157
+ ```
158
+
159
+ ## License
160
+
161
+ Released under the MIT license. See [LICENSE](LICENSE).
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MessageBlock
2
- class Engine < Rails::Engine
4
+ class Engine < ::Rails::Engine
3
5
  initializer "message_block.insert_helpers" do
4
6
  ActiveSupport.on_load(:action_view) do
5
- ActionView::Base.send(:include, MessageBlock::Helpers)
7
+ include MessageBlock::Helpers
6
8
  end
7
9
  end
8
10
  end
@@ -1,56 +1,50 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MessageBlock
2
4
  module Helpers
3
-
5
+ DEFAULT_FLASH_TYPES = %i[alert back confirm error info notice warn].freeze
6
+ DEFAULT_HTML = { id: "message_block", class: "message_block", role: "alert" }.freeze
7
+
4
8
  def message_block(options = {})
5
- options[:model_error_type] ||= :error
6
- options[:flash_types] ||= [:notice, :back, :confirm, :error, :alert, :info, :warn].sort_by(&:to_s)
7
- options[:on] ||= controller.controller_name.split('/').last.gsub(/\_controller$/, '').singularize.to_sym
8
- options[:html] ||= {:id => "message_block", :class => "message_block"}
9
- options[:html][:id] = options[:id] if options[:id]
10
- options[:html][:class] = options[:class] if options[:class]
11
- options[:container] = :div if options[:container].nil?
12
-
13
- flash_messages = {}
14
-
15
- options[:flash_types].each do |type|
16
- entries = flash[type.to_sym]
17
- next if entries.nil?
18
- entries = [entries] unless entries.is_a?(Array)
19
-
20
- flash_messages[type.to_sym] ||= []
21
- flash_messages[type.to_sym] += entries
22
- end
23
-
24
- options[:on] = [options[:on]] unless options[:on].is_a?(Array)
25
-
26
- options[:on] = [options[:on]] unless options[:on].is_a?(Array)
27
- model_objects = options[:on].map do |model_object|
28
- if model_object == :all
29
- assigns.values.select {|o| o.respond_to?(:errors) && o.errors.is_a?(ActiveModel::Errors) }
30
- elsif model_object.instance_of?(String) or model_object.instance_of?(Symbol)
31
- instance_variable_get("@#{model_object}")
32
- else
33
- model_object
9
+ model_error_type = (options[:model_error_type] || :error).to_sym
10
+ flash_types = options[:flash_types] || DEFAULT_FLASH_TYPES
11
+ on = options[:on] || controller.controller_name.split("/").last.delete_suffix("_controller").singularize.to_sym
12
+ container = options[:container].nil? ? :div : options[:container]
13
+
14
+ html = DEFAULT_HTML.merge((options[:html] || {}).symbolize_keys)
15
+ html[:id] = options[:id] if options[:id]
16
+ html[:class] = options[:class] if options[:class]
17
+
18
+ messages = Hash.new { |hash, type| hash[type] = [] }
19
+ flash_types.each { |type| messages[type.to_sym].concat(Array.wrap(flash[type.to_sym])) }
20
+ messages[model_error_type].concat(message_block_models(on).flat_map { |model| model.errors.full_messages })
21
+
22
+ lists = messages.keys.sort_by(&:to_s).reject { |type| messages[type].empty? }.map do |type|
23
+ items = messages[type].map do |message|
24
+ message = message.to_s.html_safe if options[:escape] == false
25
+ content_tag(:li, message)
34
26
  end
35
- end.flatten.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.sort_by(&:to_s).select {|type| !flash_messages[type.to_sym].empty? }.map do |type|
43
- "<ul class=\"#{type}\">" + flash_messages[type.to_sym].map {|message| "<li>#{message}</li>" }.join + "</ul>"
44
- end.join
45
-
46
- unless contents.blank?
47
- if options[:container]
48
- content_tag(options[:container], contents, options[:html], false)
27
+ content_tag(:ul, safe_join(items), class: type)
28
+ end
29
+ return if lists.empty? && !(options[:render_empty] && container)
30
+
31
+ contents = safe_join(lists)
32
+ container ? content_tag(container, contents, html) : contents
33
+ end
34
+
35
+ private
36
+
37
+ def message_block_models(on)
38
+ Array.wrap(on).flat_map do |model|
39
+ case model
40
+ when :all
41
+ assigns.values.select { |object| object.respond_to?(:errors) && object.errors.is_a?(ActiveModel::Errors) }
42
+ when String, Symbol
43
+ instance_variable_get("@#{model}")
49
44
  else
50
- contents
45
+ model
51
46
  end
52
- end
47
+ end.compact
53
48
  end
54
-
55
49
  end
56
50
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MessageBlock
2
- VERSION = "2.0.2"
4
+ VERSION = "3.0.0"
3
5
  end
data/lib/message_block.rb CHANGED
@@ -1,5 +1,6 @@
1
- require "rubygems"
1
+ # frozen_string_literal: true
2
+
2
3
  require "rails"
3
- require "active_support"
4
+ require "message_block/version"
4
5
  require "message_block/helpers"
5
6
  require "message_block/engine"
@@ -0,0 +1,91 @@
1
+ /*
2
+ * message_block default styles.
3
+ *
4
+ * Plain CSS with inline SVG icons, so it works with both Propshaft and
5
+ * Sprockets. Restyle a message type by overriding the custom properties:
6
+ *
7
+ * .message_block ul.error { --message-block-accent: #b91c1c; }
8
+ */
9
+
10
+ .message_block {
11
+ margin: 1rem 0;
12
+ }
13
+
14
+ .message_block ul {
15
+ --message-block-text: #1f2937;
16
+ --message-block-background: #f9fafb;
17
+ --message-block-border: #e5e7eb;
18
+ --message-block-accent: #6b7280;
19
+ --message-block-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4M12 8h.01'/%3E%3C/svg%3E");
20
+
21
+ position: relative;
22
+ margin: 0 0 0.5em;
23
+ padding: 0.75em 1em 0.75em 2.75em;
24
+ list-style: none;
25
+ line-height: 1.5;
26
+ color: var(--message-block-text);
27
+ background: var(--message-block-background);
28
+ border: 1px solid var(--message-block-border);
29
+ border-radius: 0.375rem;
30
+ }
31
+
32
+ .message_block ul:last-child {
33
+ margin-bottom: 0;
34
+ }
35
+
36
+ .message_block ul::before {
37
+ content: "";
38
+ position: absolute;
39
+ top: 0.9375em;
40
+ left: 1em;
41
+ width: 1.125em;
42
+ height: 1.125em;
43
+ background-color: var(--message-block-accent);
44
+ -webkit-mask: var(--message-block-icon) center / contain no-repeat;
45
+ mask: var(--message-block-icon) center / contain no-repeat;
46
+ }
47
+
48
+ .message_block li {
49
+ margin: 0;
50
+ }
51
+
52
+ .message_block li + li {
53
+ margin-top: 0.25em;
54
+ }
55
+
56
+ .message_block ul.error,
57
+ .message_block ul.alert {
58
+ --message-block-text: #7f1d1d;
59
+ --message-block-background: #fef2f2;
60
+ --message-block-border: #fecaca;
61
+ --message-block-accent: #dc2626;
62
+ --message-block-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 7v6M12 17h.01'/%3E%3C/svg%3E");
63
+ }
64
+
65
+ .message_block ul.warn {
66
+ --message-block-text: #713f12;
67
+ --message-block-background: #fefce8;
68
+ --message-block-border: #fde68a;
69
+ --message-block-accent: #d97706;
70
+ --message-block-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z'/%3E%3Cpath d='M12 9v4M12 17h.01'/%3E%3C/svg%3E");
71
+ }
72
+
73
+ .message_block ul.notice,
74
+ .message_block ul.info {
75
+ --message-block-text: #1e3a8a;
76
+ --message-block-background: #eff6ff;
77
+ --message-block-border: #bfdbfe;
78
+ --message-block-accent: #2563eb;
79
+ }
80
+
81
+ .message_block ul.confirm {
82
+ --message-block-text: #14532d;
83
+ --message-block-background: #f0fdf4;
84
+ --message-block-border: #bbf7d0;
85
+ --message-block-accent: #16a34a;
86
+ --message-block-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='m8 12 3 3 5-6'/%3E%3C/svg%3E");
87
+ }
88
+
89
+ .message_block ul.back {
90
+ --message-block-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 12H5M12 19l-7-7 7-7'/%3E%3C/svg%3E");
91
+ }
metadata CHANGED
@@ -1,101 +1,95 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: message_block
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
5
- prerelease:
4
+ version: 3.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ben Hughes
9
- autorequire:
10
8
  bindir: bin
11
9
  cert_chain: []
12
- date: 2013-02-17 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
13
11
  dependencies:
14
12
  - !ruby/object:Gem::Dependency
15
- name: rails
16
- requirement: &70328085129660 !ruby/object:Gem::Requirement
17
- none: false
13
+ name: actionview
14
+ requirement: !ruby/object:Gem::Requirement
18
15
  requirements:
19
- - - ! '>='
16
+ - - ">="
20
17
  - !ruby/object:Gem::Version
21
- version: 3.1.0
18
+ version: '6.1'
22
19
  type: :runtime
23
20
  prerelease: false
24
- version_requirements: *70328085129660
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '6.1'
25
26
  - !ruby/object:Gem::Dependency
26
- name: rspec
27
- requirement: &70328085128980 !ruby/object:Gem::Requirement
28
- none: false
27
+ name: activemodel
28
+ requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
- - - ~>
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: '2.0'
33
- type: :development
32
+ version: '6.1'
33
+ type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70328085128980
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '6.1'
36
40
  - !ruby/object:Gem::Dependency
37
- name: sqlite3-ruby
38
- requirement: &70328085128400 !ruby/object:Gem::Requirement
39
- none: false
41
+ name: railties
42
+ requirement: !ruby/object:Gem::Requirement
40
43
  requirements:
41
- - - ~>
44
+ - - ">="
42
45
  - !ruby/object:Gem::Version
43
- version: 1.3.1
44
- type: :development
46
+ version: '6.1'
47
+ type: :runtime
45
48
  prerelease: false
46
- version_requirements: *70328085128400
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '6.1'
47
54
  description: Implements the common view pattern by which a list of messages are shown
48
55
  at the top, often a combination of flash messages and ActiveRecord validation issues
49
56
  on one or more models.
50
- email: ben@railsgarden.com
57
+ email: me@benhughes.name
51
58
  executables: []
52
59
  extensions: []
53
60
  extra_rdoc_files: []
54
61
  files:
62
+ - CHANGELOG.md
63
+ - LICENSE
64
+ - README.md
65
+ - lib/message_block.rb
55
66
  - lib/message_block/engine.rb
56
67
  - lib/message_block/helpers.rb
57
68
  - lib/message_block/version.rb
58
- - lib/message_block.rb
59
- - spec/message_block/helpers_spec.rb
60
- - spec/spec_helper.rb
61
- - vendor/assets/images/message_block/alert.gif
62
- - vendor/assets/images/message_block/back.gif
63
- - vendor/assets/images/message_block/confirmation.gif
64
- - vendor/assets/images/message_block/error.gif
65
- - vendor/assets/images/message_block/info.gif
66
- - vendor/assets/images/message_block/notice.gif
67
- - vendor/assets/images/message_block/warn.gif
68
- - vendor/assets/stylesheets/message_block.css.erb
69
- - CHANGELOG
70
- - Gemfile
71
- - Gemfile.lock
72
- - LICENSE
73
- - Rakefile
74
- - README.rdoc
75
- homepage: http://github.com/rubiety/message_block
76
- licenses: []
77
- post_install_message:
69
+ - vendor/assets/stylesheets/message_block.css
70
+ homepage: https://github.com/eigenben/message_block
71
+ licenses:
72
+ - MIT
73
+ metadata:
74
+ source_code_uri: https://github.com/eigenben/message_block
75
+ changelog_uri: https://github.com/eigenben/message_block/blob/master/CHANGELOG.md
76
+ bug_tracker_uri: https://github.com/eigenben/message_block/issues
77
+ rubygems_mfa_required: 'true'
78
78
  rdoc_options: []
79
79
  require_paths:
80
80
  - lib
81
81
  required_ruby_version: !ruby/object:Gem::Requirement
82
- none: false
83
82
  requirements:
84
- - - ! '>='
83
+ - - ">="
85
84
  - !ruby/object:Gem::Version
86
- version: '0'
85
+ version: '2.7'
87
86
  required_rubygems_version: !ruby/object:Gem::Requirement
88
- none: false
89
87
  requirements:
90
- - - ! '>='
88
+ - - ">="
91
89
  - !ruby/object:Gem::Version
92
- version: 1.3.4
90
+ version: '0'
93
91
  requirements: []
94
- rubyforge_project: message_block
95
- rubygems_version: 1.8.16
96
- signing_key:
97
- specification_version: 3
98
- summary: Flash message and error_messages_for handling with a common interface via
99
- the asset pipeline
92
+ rubygems_version: 3.6.7
93
+ specification_version: 4
94
+ summary: Flash message and model error handling with a common interface
100
95
  test_files: []
101
- has_rdoc:
data/CHANGELOG DELETED
@@ -1,13 +0,0 @@
1
- == Version 2.0.2 (Feburary 17, 2013)
2
-
3
- * Fixed inclusion of vendor from gemspec
4
-
5
- == Version 2.0.1 (eburary 17, 2013)
6
-
7
- * Added 'alert' flash message type
8
-
9
- == Version 2.0.0 (Feburary 8, 2013)
10
-
11
- * Converted assets to use the asset pipeline (instead of a rake task to copy
12
- assets)
13
-
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in testgem.gemspec
4
- gemspec
data/Gemfile.lock DELETED
@@ -1,106 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- message_block (2.0.1)
5
- rails (>= 3.1.0)
6
-
7
- GEM
8
- remote: http://rubygems.org/
9
- specs:
10
- actionmailer (3.2.12)
11
- actionpack (= 3.2.12)
12
- mail (~> 2.4.4)
13
- actionpack (3.2.12)
14
- activemodel (= 3.2.12)
15
- activesupport (= 3.2.12)
16
- builder (~> 3.0.0)
17
- erubis (~> 2.7.0)
18
- journey (~> 1.0.4)
19
- rack (~> 1.4.5)
20
- rack-cache (~> 1.2)
21
- rack-test (~> 0.6.1)
22
- sprockets (~> 2.2.1)
23
- activemodel (3.2.12)
24
- activesupport (= 3.2.12)
25
- builder (~> 3.0.0)
26
- activerecord (3.2.12)
27
- activemodel (= 3.2.12)
28
- activesupport (= 3.2.12)
29
- arel (~> 3.0.2)
30
- tzinfo (~> 0.3.29)
31
- activeresource (3.2.12)
32
- activemodel (= 3.2.12)
33
- activesupport (= 3.2.12)
34
- activesupport (3.2.12)
35
- i18n (~> 0.6)
36
- multi_json (~> 1.0)
37
- arel (3.0.2)
38
- builder (3.0.4)
39
- diff-lcs (1.1.2)
40
- erubis (2.7.0)
41
- hike (1.2.1)
42
- i18n (0.6.1)
43
- journey (1.0.4)
44
- json (1.7.7)
45
- mail (2.4.4)
46
- i18n (>= 0.4.0)
47
- mime-types (~> 1.16)
48
- treetop (~> 1.4.8)
49
- mime-types (1.21)
50
- multi_json (1.6.1)
51
- polyglot (0.3.3)
52
- rack (1.4.5)
53
- rack-cache (1.2)
54
- rack (>= 0.4)
55
- rack-ssl (1.3.3)
56
- rack
57
- rack-test (0.6.2)
58
- rack (>= 1.0)
59
- rails (3.2.12)
60
- actionmailer (= 3.2.12)
61
- actionpack (= 3.2.12)
62
- activerecord (= 3.2.12)
63
- activeresource (= 3.2.12)
64
- activesupport (= 3.2.12)
65
- bundler (~> 1.0)
66
- railties (= 3.2.12)
67
- railties (3.2.12)
68
- actionpack (= 3.2.12)
69
- activesupport (= 3.2.12)
70
- rack-ssl (~> 1.3.2)
71
- rake (>= 0.8.7)
72
- rdoc (~> 3.4)
73
- thor (>= 0.14.6, < 2.0)
74
- rake (10.0.3)
75
- rdoc (3.12.1)
76
- json (~> 1.4)
77
- rspec (2.0.0)
78
- rspec-core (= 2.0.0)
79
- rspec-expectations (= 2.0.0)
80
- rspec-mocks (= 2.0.0)
81
- rspec-core (2.0.0)
82
- rspec-expectations (2.0.0)
83
- diff-lcs (>= 1.1.2)
84
- rspec-mocks (2.0.0)
85
- rspec-core (= 2.0.0)
86
- rspec-expectations (= 2.0.0)
87
- sprockets (2.2.2)
88
- hike (~> 1.2)
89
- multi_json (~> 1.0)
90
- rack (~> 1.0)
91
- tilt (~> 1.1, != 1.3.0)
92
- sqlite3-ruby (1.3.1)
93
- thor (0.17.0)
94
- tilt (1.3.3)
95
- treetop (1.4.12)
96
- polyglot
97
- polyglot (>= 0.3.1)
98
- tzinfo (0.3.35)
99
-
100
- PLATFORMS
101
- ruby
102
-
103
- DEPENDENCIES
104
- message_block!
105
- rspec (~> 2.0)
106
- sqlite3-ruby (~> 1.3.1)
data/README.rdoc DELETED
@@ -1,94 +0,0 @@
1
- {<img src="https://secure.travis-ci.org/rubiety/message_block.png?branch=master" alt="Build Status" />}[http://travis-ci.org/rubiety/message_block]
2
-
3
- == Message Block
4
-
5
- Implements the common view pattern by which a list of messages are shown at the top,
6
- often a combination of flash messages and ActiveRecord validation issues on one or more models.
7
- This allows for a nice, stylized block of messages at the top of the page with icons
8
- indicating what type of message it is (error, confirmation, warning, etc.)
9
-
10
- This view helper acts as a replacement for error_messages_for by taking error messages
11
- from your models and combing them with flash messages (multiple types such as error, confirm, etc.)
12
- and outputting them to your view. This gem comes with an example stylesheet and images.
13
-
14
-
15
- == Installation: Rails 3.1+ Asset Pipeline (message_block 2.0)
16
-
17
- Include the gem using bundler in your Gemfile:
18
-
19
- gem "message_block", "~> 2.0"
20
-
21
- Include the stylesheet in your application.css:
22
-
23
- /*
24
- *= require message_block
25
- */
26
-
27
-
28
- == Installation: Rails 3.0 Without Asset Pipeline (message_block 1.1)
29
-
30
- Include the gem using bundler in your Gemfile:
31
-
32
- gem "message_block", "~> 1.1"
33
-
34
- Then run the rake task to install the static files:
35
-
36
- rake message_block:install
37
-
38
- Then be sure to include the CSS definitions:
39
-
40
- <%= stylesheet_include_tag "message_block" %>
41
-
42
-
43
- == Usage
44
-
45
- Once you install this, you should now have a set of images at public/images/message_block and
46
- a basic stylesheet installed at public/stylesheets/message_block.css. Then you can use
47
- the helper <tt><%= message_block %></tt>:
48
-
49
- The first argument specifies a hash options:
50
-
51
- * <tt>:on</tt> - specifies one or many model names for which to check error messages. You can specify the special value of :all which will grab all view assignments that contain an ActiveModel "errors" method.
52
- * <tt>:model_error_type</tt> - specifies the message type to use for validation errors; defaults to 'error'
53
- * <tt>:flash_types</tt> - specifies the keys to check in the flash hash. Messages will be grouped in ul
54
- lists according to this type. Defaults to: [:notice, :back, :confirm, :error, :alert, :info, :warn]
55
- * <tt>:html</tt> - Specifies HTML options for the containing div
56
- * <tt>:id</tt> - Specifies ID of the containing div; defaults to 'message_block'
57
- * <tt>:class</tt> - Specifies class name of the containing div; defaults to nothing.
58
- * <tt>:container</tt> - specifies which block-level element to contain the errors (defaults to :div).
59
-
60
- === Example
61
-
62
- Imagine you have a form for entering a user and a comment:
63
-
64
- <%= message_block :on => [:user, :comment] %>
65
-
66
- Imagine also you set these flash variables in the controller:
67
- class CommentsController
68
- def create
69
- flash.now[:error] = "Error A"
70
- flash.now[:confirm] = "Confirmation A" # Note you can use different types
71
- flash.now[:warn] = ["Warn A", "Warn B"] # Can set to an array for multiple messages
72
- end
73
- end
74
-
75
- And let's say that you want to show these messages but also show the validation issues
76
- given that both user and comment fail ActiveRecord validation:
77
-
78
- <div id="message_block" class="message_block">
79
- <ul class="error">
80
- <li>Error A</li>
81
- <li>User first name is required.</li>
82
- <li>Comment contents is required.</li>
83
- </ul>
84
- <ul class="confirm">
85
- <li>Confirmation A</li>
86
- </ul>
87
- <ul class="warn">
88
- <li>Warn A</li>
89
- <li>Warn B</li>
90
- </ul>
91
- </div>
92
-
93
- Note that instead of manually specifying models you wish to report errors on, you can instead use the special <tt>:all</tt> value which will automatically use all view assign values that contain an ActiveModel::Errors "errors" method.
94
-
data/Rakefile DELETED
@@ -1,39 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'rdoc/task'
4
-
5
- require 'rubygems'
6
- require 'bundler/setup'
7
-
8
- require 'rake'
9
- require 'rspec/core/rake_task'
10
-
11
- Bundler::GemHelper.install_tasks
12
-
13
- desc 'Default: run unit tests.'
14
- task :default => [:clean, :test]
15
-
16
- desc "Run Specs"
17
- RSpec::Core::RakeTask.new(:spec) do |t|
18
- end
19
-
20
- task :test => :spec
21
-
22
- desc "Clean up files."
23
- task :clean do |t|
24
- FileUtils.rm_rf "tmp"
25
- Dir.glob("message_block-*.gem").each {|f| FileUtils.rm f }
26
- end
27
-
28
- desc "Generate documentation for the plugin."
29
- Rake::RDocTask.new(:rdoc) do |rdoc|
30
- rdoc.rdoc_dir = "rdoc"
31
- rdoc.title = "message_block"
32
- rdoc.options << "--line-numbers" << "--inline-source"
33
- rdoc.rdoc_files.include('README')
34
- rdoc.rdoc_files.include('lib/**/*.rb')
35
- end
36
-
37
- Dir["#{File.dirname(__FILE__)}/lib/tasks/*.rake"].sort.each { |ext| load ext }
38
-
39
-
@@ -1,135 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe MessageBlock::Helpers do
4
- include ActionView::Helpers::TagHelper
5
- include MessageBlock::Helpers
6
-
7
- before do
8
- @post = Post.new
9
- @user = User.new
10
- stub!(:assigns).and_return(:user => @user, :post => @post)
11
- end
12
-
13
- it "should accept valid options" do
14
- lambda {
15
- message_block :on => :post,
16
- :model_error_type => "fail",
17
- :flash_types => %w(error warn),
18
- :html => {:style => 'height: 10em'},
19
- :id => "block",
20
- :class => "messages"
21
- }.should_not raise_error
22
- end
23
-
24
- it "should show nothing with no errors" do
25
- message_block.should be_nil
26
- end
27
-
28
- it "should automatically find post errors with posts controller" do
29
- @controller = posts_controller
30
- output = message_block
31
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>name can't be blank</li></ul></div>)
32
- end
33
-
34
- it "should give no error for post" do
35
- output = message_block(:on => :post)
36
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>name can't be blank</li></ul></div>)
37
- end
38
-
39
- it "should give error for user" do
40
- output = message_block(:on => :user)
41
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>name can't be blank</li></ul></div>)
42
- end
43
-
44
- it "should give error for both user and post when using :all" do
45
- output = message_block(:on => :all)
46
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>name can't be blank</li><li>name can't be blank</li></ul></div>)
47
- end
48
-
49
- it "should give errors for both post and user" do
50
- output = message_block(:on => [:post, :user])
51
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>name can't be blank</li><li>name can't be blank</li></ul></div>)
52
- end
53
-
54
- it "should give errors for both post and user in the correct order" do
55
- output = message_block(:on => [:user, :post])
56
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>name can't be blank</li><li>name can't be blank</li></ul></div>)
57
- end
58
-
59
- it "should give error for user given direct instance variable" do
60
- output = message_block(:on => @user)
61
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>name can't be blank</li></ul></div>)
62
- end
63
-
64
- it "should respect model error type" do
65
- output = message_block(:on => :user, :model_error_type => "fail")
66
- output.should == %(<div class="message_block" id="message_block"><ul class="fail"><li>name can't be blank</li></ul></div>)
67
- end
68
-
69
- it "should be able to specify id for containing div" do
70
- @controller = posts_controller
71
- output = message_block(:id => "messages")
72
- output.should == %(<div class="message_block" id="messages"><ul class="error"><li>name can't be blank</li></ul></div>)
73
- end
74
-
75
- it "should be able to specify class for containing div" do
76
- @controller = posts_controller
77
- output = message_block(:class => "messages")
78
- output.should == %(<div class="messages" id="message_block"><ul class="error"><li>name can't be blank</li></ul></div>)
79
- end
80
-
81
- it "should be able to specify html options for containing div" do
82
- @controller = posts_controller
83
- output = message_block(:html => {:id => "block", :class => "messages"})
84
- output.should == %(<div class="messages" id="block"><ul class="error"><li>name can't be blank</li></ul></div>)
85
- end
86
-
87
- it "should be able to specify container option as false" do
88
- output = message_block(:on => :post, :container => false)
89
- output.should == %(<ul class="error"><li>name can't be blank</li></ul>)
90
- end
91
-
92
- it "should be able to specify container option" do
93
- output = message_block(:on => :post, :container => :fieldset)
94
- output.should == %(<fieldset class="message_block" id="message_block"><ul class="error"><li>name can't be blank</li></ul></fieldset>)
95
- end
96
-
97
- it "should be able to see flash error string" do
98
- flash[:error] = "Error A"
99
- output = message_block
100
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>Error A</li></ul></div>)
101
- end
102
-
103
- it "should be able to see flash error array" do
104
- flash[:error] = ["Error A", "Error B"]
105
- output = message_block
106
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>Error A</li><li>Error B</li></ul></div>)
107
- end
108
-
109
- it "should be able to see default flash types" do
110
- default_types = [:notice, :back, :confirm, :error, :info, :warn].sort_by(&:to_s)
111
- default_types.each do |type|
112
- flash[type] = type.to_s
113
- end
114
-
115
- expected_contents = default_types.map do |type|
116
- content_tag(:ul, content_tag(:li, type.to_s), :class => type.to_s)
117
- end.join
118
-
119
- output = message_block
120
- output.should == %(<div class="message_block" id="message_block">#{expected_contents}</div>)
121
- end
122
-
123
- it "should be able to see flash error alongside model error" do
124
- flash[:error] = "Error A"
125
- output = message_block(:on => :post)
126
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>Error A</li><li>name can't be blank</li></ul></div>)
127
- end
128
-
129
- it "should be safe for html inside flash messages" do
130
- flash[:error] = ["Error <strong>A</strong>", "Error <strong>B</strong>"]
131
- output = message_block
132
- output.should == %(<div class="message_block" id="message_block"><ul class="error"><li>Error <strong>A</strong></li><li>Error <strong>B</strong></li></ul></div>)
133
- end
134
-
135
- end
data/spec/spec_helper.rb DELETED
@@ -1,75 +0,0 @@
1
- require "rubygems"
2
- require "message_block"
3
- require "active_support"
4
- require "active_model"
5
- require "action_pack"
6
- require "action_view"
7
-
8
- class Post
9
- extend ActiveModel::Naming
10
-
11
- attr_accessor :name
12
- attr_reader :errors
13
-
14
- def initialize
15
- @errors = ActiveModel::Errors.new(self)
16
- @errors.add(:name, "can't be blank")
17
- end
18
-
19
- def read_attribute_for_validation(attr)
20
- send(attr)
21
- end
22
-
23
- def self.human_attribute_name(attr, options = {})
24
- attr
25
- end
26
-
27
- def self.lookup_ancestors
28
- [self]
29
- end
30
- end
31
-
32
- class User
33
- extend ActiveModel::Naming
34
-
35
- attr_accessor :name
36
- attr_reader :errors
37
-
38
- def initialize
39
- @errors = ActiveModel::Errors.new(self)
40
- @errors.add(:name, "can't be blank")
41
- end
42
-
43
- def read_attribute_for_validation(attr)
44
- send(attr)
45
- end
46
-
47
- def self.human_attribute_name(attr, options = {})
48
- attr
49
- end
50
-
51
- def self.lookup_ancestors
52
- [self]
53
- end
54
- end
55
-
56
-
57
- def controller
58
- @controller ||= Class.new {
59
- def controller_name
60
- "widgets_controller"
61
- end
62
- }.new
63
- end
64
-
65
- def posts_controller
66
- Class.new {
67
- def controller_name
68
- "posts_controller"
69
- end
70
- }.new
71
- end
72
-
73
- def flash
74
- @flash ||= {}
75
- end
@@ -1,39 +0,0 @@
1
- .message_block {
2
- clear: both;
3
- margin: 12px 0;
4
- }
5
-
6
- .message_block ul {
7
- border-bottom: 1px solid #ecd757;
8
- border-top: 1px solid #ecd757;
9
- list-style: none;
10
- padding: 10px;
11
- }
12
- .message_block ul li {
13
- margin-left: 3em;
14
- }
15
-
16
- .message_block ul.error {
17
- background: #fcf6d0 url(<%= asset_path("message_block/error.gif") %>) 16px 50% no-repeat;
18
- }
19
-
20
- .message_block ul.alert {
21
- background: #fcf6d0 url(<%= asset_path("message_block/alert.gif") %>) 16px 50% no-repeat;
22
- }
23
-
24
- .message_block ul.info {
25
- background: #fcf6d0 url(<%= asset_path("message_block/info.gif") %>) 16px 50% no-repeat;
26
- }
27
-
28
- .message_block ul.notice {
29
- background: #fcf6d0 url(<%= asset_path("message_block/notice.gif") %>) 16px 50% no-repeat;
30
- }
31
-
32
- .message_block ul.confirm {
33
- background: #fcf6d0 url(<%= asset_path("message_block/confirm.gif") %>) 16px 50% no-repeat;
34
- }
35
-
36
- .message_block ul.warn {
37
- background: #fcf6d0 url(<%= asset_path("message_block/warn.gif") %>) 1em 50% no-repeat;
38
- }
39
-