0.04
Low commit activity in last 3 years
A long-lived project that still receives updates
Implements the common view pattern by which a list of messages are shown at the top, often a combination of flash messages and ActiveRecord validation issues on one or more models.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

 Project Readme

Message Block

CI

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.).

Requirements

  • Rails 6.1 or newer
  • Ruby 2.7 or newer

For older Rails versions, use message_block 2.x.

Installation

Add the gem to your Gemfile:

gem "message_block", "~> 3.0"

The gem ships an optional stylesheet. With Propshaft (the Rails 8 default), link it in your layout:

<%= stylesheet_link_tag "message_block" %>

With Sprockets, require it from application.css:

/*
 *= require message_block
 */

If you use Tailwind, Bootstrap or another CSS framework, you can skip the stylesheet and style the generated markup yourself.

Usage

Call the message_block helper in a view or layout:

<%= message_block on: [:user, :comment] %>

Given these flash messages in the controller:

class CommentsController < ApplicationController
  def create
    flash.now[:error] = "Error A"
    flash.now[:confirm] = "Confirmation A"   # Use whichever types you like
    flash.now[:warn] = ["Warn A", "Warn B"]  # Arrays show multiple messages
  end
end

and given that both @user and @comment fail validation, the helper renders:

<div id="message_block" class="message_block" role="alert">
  <ul class="confirm">
    <li>Confirmation A</li>
  </ul>
  <ul class="error">
    <li>Error A</li>
    <li>User first name can't be blank</li>
    <li>Comment contents can't be blank</li>
  </ul>
  <ul class="warn">
    <li>Warn A</li>
    <li>Warn B</li>
  </ul>
</div>

Nothing is rendered when there are no messages.

Options

Option Description Default
: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
:model_error_type The message type that validation errors are grouped under. :error
:flash_types The flash keys to show. [:alert, :back, :confirm, :error, :info, :notice, :warn]
:html HTML attributes for the container, merged with the defaults. { id: "message_block", class: "message_block", role: "alert" }
:id Shortcut for the container's id. "message_block"
:class Shortcut for the container's class. "message_block"
:container The element that wraps the lists, or false to render the lists alone. :div
:escape Set to false to render every message as raw HTML. See HTML in messages. true
:render_empty Render the container even when there are no messages. Useful as a Turbo Stream target. false

HTML in messages

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:

flash.now[:notice] = helpers.link_to("View your order", order_path(@order))

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.

Turbo

To update messages from a Turbo Stream response, render an empty container in your layout so there is always a target:

<%= message_block render_empty: true %>

Then update its contents from the stream:

<%# app/views/comments/create.turbo_stream.erb %>
<%= turbo_stream.update "message_block" do %>
  <%= message_block on: :comment, container: false %>
<% end %>

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.

Styling

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:

.message_block ul.error {
  --message-block-text: #7f1d1d;
  --message-block-background: #fef2f2;
  --message-block-border: #fecaca;
  --message-block-accent: #dc2626; /* icon color */
}

Upgrading from 2.x

  • Rails 6.1+ and Ruby 2.7+ are required.
  • 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.
  • The container has role="alert" by default. Pass html: { role: nil } to remove it.
  • The :html option is merged with the default id and class instead of replacing them.
  • The stylesheet has been rewritten as plain CSS with inline SVG icons, and the message_block/*.gif images have been removed.

Development

Run the specs against the current Rails version:

bundle install
bundle exec rspec

Run them against every supported Rails version with Appraisal:

bundle exec appraisal install
bundle exec appraisal rspec

License

Released under the MIT license. See LICENSE.