Hello I am new to ruby on rails and I am struggling to understand I18n\'s flash messages. I am using devise, rails 4, and twitter bootstrap.I understand that devise only use
With Boostrap 3.1, for me works in this way:
html = <<-HTML
<div class="alert alert-danger alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<strong>#{sentence}</strong>
<ul>
#{messages}
</ul>
</div>
HTML
Actually bootstrap provide some alert class, please try for class with alert alert-warning
for yellow warning, alert alert-success
for green warning, alert alert-danger
for red warning.
And for the I18n you can just directly using that just like on the view.
Also if you want to forcing using your class rather than bootstrap class, you can using !important
at your class for example:
.alert
{
background: #f3f3f3 !important;
color: black !important;
}
Please correct me if I'm wrong.
The simplest solution I've found is to use a common partial for all flash messages while checking for :notice
and :alert
to replace with the necessary bootstrap class.
So make /views/shared/_alerts.html.erb
like this -
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= flash_class_name(message_type) %> alert-dismissable">
<span><%= message %></span>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<% end %>
Add a helper method (I've added it to the application helper) like this -
def flash_class_name(name)
case name
when "notice" then "success"
when "alert" then "danger"
else name
end
end
Include _alerts.html.erb
in the application layout (or the parent layout for your application).
That's it!
Here's my 2 cents.
Using a case statement to check if the flash names are the older syntax alert
or notice
and change them to success
or danger
if they are and leave everything else alone.
<div class="container">
<% flash.each do |name, msg| %>
<% if msg.is_a?(String) %>
<div class="alert alert-<%= flash_class_name(name) %>" role="alert">
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
<%= content_tag :div, msg, :id => "flash_#{name}" %>
</div>
<% end %>
<% end %>
</div>
and a helper method
def flash_class_name(name)
case name
when 'notice' then 'success'
when 'alert' then 'danger'
else name
end
end
I made a wiki page within the devise wiki on github for How To: Integrate I18n Flash Messages with Devise and Bootstrap
First we will make a rendered view to make the code concise. Within "app/views/layouts/application.html.erb" I added <%= render 'layouts/messages' %>
.
My file looks like:
<body>
<%= render 'layouts/header' %>
<div class="container">
<%= render 'layouts/messages' %>
<%= yield %>
<%= render 'layouts/footer' %>
</div>
</body>
Next we have to make the messages file. Make a new file in "app/views/layouts/_messages.html.erb" and add:
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>">
<a href="#" data-dismiss="alert" class="close">×</a>
<ul>
<li>
<%= value %>
</li>
</ul>
</div>
<% end %>
This will give us flash messages for the entire site.
For devise you need to override the way devise handles flash messages. Create a file called devise_helper in "app/helpers/devise_helper.rb".
Inside the file you have to create a method called devise_error_messages!, which is the name of the file that tells devise how to handle flash messages.
module DeviseHelper
def devise_error_messages!
return '' if resource.errors.empty?
messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
html = <<-HTML
<div class="alert alert-error alert-block"> <button type="button"
class="close" data-dismiss="alert">x</button>
#{messages}
</div>
HTML
html.html_safe
end
end
Next in your devise views you will have to define where you want the error messages to appear. You will need to enter <%= devise_error_messages! %>
within the devise pages. An example is entering this within "app/views/devise/registrations/.new.html.erb" (The sign up page)
It should already be within the file, but you can move the code around to customize where it is shown.
If you do not want to use the odd blue and yellow alerts that come default, I have set error and alert to have the same colorand success and notice to have the same color. I am using red for errors and alerts, and green for success and notice.
Within my "app/assets/stylesheets/custom.css.scss" I have:
/*flash*/
.alert-error {
background-color: #f2dede;
border-color: #eed3d7;
color: #b94a48;
text-align: left;
}
.alert-alert {
background-color: #f2dede;
border-color: #eed3d7;
color: #b94a48;
text-align: left;
}
.alert-success {
background-color: #dff0d8;
border-color: #d6e9c6;
color: #468847;
text-align: left;
}
.alert-notice {
background-color: #dff0d8;
border-color: #d6e9c6;
color: #468847;
text-align: left;
}
If you use Sass in your app, you can extend BS classes alert-info
and alert-danger
with Devise's alert-notice
and alert-alert
respectively, in a way like this:
.alert-notice {
@extend .alert-info
}
.alert-alert {
@extend .alert-danger
}
By adding this to your *.scss, Devise flash messages will inherit the styles of BS info
and danger
alerts.
http://sass-lang.com/guide (Extend/Inheritance section)