使用Twitter Bootstrap的Rails Devise I18n Flash消息

9

你好,我是一个新手,正在学习 Ruby on Rails,但我很难理解 I18n 的闪存消息。我正在使用 Devise、Rails 4 和 Twitter Bootstrap。我知道 Devise 只使用 flash[:notice]flash[:alert]

我能够让我的用户模型的闪存消息在登录和退出时正常工作。然而,我无法正确显示注册或忘记密码的闪存错误。它看起来像默认的错误消息。

我查看了很多相关问题,但对于如何使用漂亮的 CSS 显示所有闪存消息(错误、成功、通知)感到困惑。

也许答案已经在这篇文章中了?rails-Devise-Handling-devise_error_messages

目前,我的闪存消息基于 如何使用 Twitter Bootstrap Rails gem 定义 Flash 通知

这是我的示例:
'app/views/layouts/application.html.erb'

<%= render 'layouts/messages' %>

'app/views/layouts/_messages.html.erb'

<% flash.each do |name, msg| %>
  <% if msg.is_a?(String) %>
    <div class="alert alert-<%= name == :notice ? "success" : "error" %>">
      <a class="close" data-dismiss="alert">&#215;</a>
      <%= content_tag :div, msg, :id => "flash_#{name}" %>
    </div>
  <% end %>
<% end %>

如何使用自定义CSS显示所有flash消息(错误、成功、通知)?

更新:此帖子显示了我要做的正确版本。我的问题是样式看起来不一样。我认为这是由于HTML标记引起的。

html = <<-HTML
 <div class="alert alert-error alert-block"> <button type="button"
  class="close" data-dismiss="alert">x</button>
  <h4>#{sentence}</h4>
  #{messages}
 </div>
HTML

有什么办法可以使警告框具有相同的样式吗?或者在CSS中使用哪些标签?

signup error

您可以看到注册页面^^和登录页面(下方)之间的区别。

signin error

更新2

我已经发布了关于我的问题的新文章-可以在这里找到。


你尝试过这个问题吗?https://dev59.com/R2oy5IYBdhLWcg3wN7UX?rq=1。你的问题是关于使用你的CSS还是I18n? - ksugiarto
我刚刚看到了这个,然后尝试了一下。但是我无法让它工作。我仍然得到相同的结果。 - Daniel
我按照这个方案操作,它几乎可以正常工作。http://stackoverflow.com/questions/20171539/how-to-apply-customized-bootstrap-messages-errors-to-devise/20235279#20235279我已经为所有内容设置了颜色,但我不确定如何为每个警报更改颜色。 - Daniel
我的问题是关于I18n和css的。我不确定如何使其正确显示。我希望所有的错误字段都是红色的,而任何成功+好的东西都是绿色的。 - Daniel
6个回答

13

我在Github的Devise Wiki内创建了一个维基页面,讲解如何将I18n闪存消息与Devise和Bootstrap集成,页面链接为How To: Integrate I18n Flash Messages with Devise and Bootstrap

站点的闪存消息

首先,我们将创建一个呈现视图以使代码简洁。在"app/views/layouts/application.html.erb"中,我添加了<%= render 'layouts/messages' %>

我的文件如下:

<body>
  <%= render 'layouts/header' %>
  <div class="container">
    <%= render 'layouts/messages' %>
    <%= yield %>
    <%= render 'layouts/footer' %>
  </div>
</body>

接下来我们需要创建消息文件。在 "app/views/layouts/_messages.html.erb" 中新建一个文件,并添加以下内容:

<% 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 %>

这将为整个网站提供闪现消息。

为Devise设置闪现消息

对于Devise,您需要覆盖Devise处理闪现消息的方式。在"app/helpers/devise_helper.rb"中创建一个名为devise_helper的文件。

在文件中,您需要创建一个名为devise_error_messages!的方法,它是告诉Devise如何处理闪现消息的名称。

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
在你的设备视图中,你需要定义错误消息出现的位置。你需要在devise页面中输入<%= devise_error_messages! %>。例如,在"app/views/devise/registrations/.new.html.erb"(注册页面)中输入它。
它应该已经在文件中了,但是您可以移动代码以自定义其显示位置。
闪存消息的CSS
如果您不想使用默认的奇怪蓝色和黄色警报,我已将错误和警告设置为具有相同的颜色,并将成功和注释设置为具有相同的颜色。我正在使用红色表示错误和警告,绿色表示成功和通知。
在我的"app/assets/stylesheets/custom.css.scss" 中,我有:
/*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;
 }

虽然这理论上回答了问题,但最好在此处包含答案的基本部分,并提供参考链接。 - Bill the Lizard

9

这是我的意见。使用 case 语句检查 Flash 名称是否为旧语法的 alertnotice ,如果是,则将它们更改为 successdanger,否则不更改。

<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">&times;</span>
        <span class="sr-only">Close</span>
        </button>
        <%= content_tag :div, msg, :id => "flash_#{name}" %>
      </div>
    <% end %>
  <% end %>
</div>

还有一个辅助方法

def flash_class_name(name)
    case name
    when 'notice' then 'success'
    when 'alert'  then 'danger'
    else name
    end
end

1
这是最简单的解决方案。+1 - Michael

5
如果您在应用程序中使用Sass,可以通过以下方式扩展BS类alert-infoalert-danger,分别使用Devise的alert-noticealert-alert
.alert-notice {
  @extend .alert-info
}

.alert-alert {
  @extend .alert-danger
}

通过将以下内容添加到您的*.scss文件中,Devise闪现消息将继承BS info和danger警报的样式。 http://sass-lang.com/guide(Extend/Inheritance部分)

2
我找到的最简单的解决方案是使用一个通用的部分文件来处理所有闪现消息,同时检查:notice:alert并替换为必要的Bootstrap类。因此,请将/views/shared/_alerts.html.erb文件编写为以下内容 -
<% 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">&times;</span>
    </button>
  </div>
<% end %>

添加一个辅助方法(我已将其添加到应用程序辅助器)如下所示 -
def flash_class_name(name)
    case name
    when "notice" then "success"
    when "alert"  then "danger"
    else name
    end
end

在应用程序布局中(或您的应用程序的父布局中)包含_alerts.html.erb

就是这样!


1
使用Bootstrap 3.1,对我而言,它是这样工作的:

 html = <<-HTML
    <div class="alert alert-danger alert-dismissible" role="alert">
      <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
      <strong>#{sentence}</strong>
      <ul>
        #{messages}
      </ul>
    </div>

HTML

0
实际上Bootstrap提供了一些警告类,请尝试使用 alert alert-warning 类以获得黄色警告,alert alert-success 类以获得绿色警告,alert alert-danger 类以获得红色警告。
至于国际化(I18n),您可以直接像在视图中那样使用它。
另外,如果您想要强制使用自己的类而不是Bootstrap类,您可以在您的类中使用 !important,例如:
.alert
{
  background: #f3f3f3 !important;
  color: black !important;
}

如果我错了,请纠正我。


谢谢,我明白你的意思是将其强制应用于引导类。我想保留I18n提供的警告alert-danger和alert-success。但是,如果您查看我的图片,您会发现alert-danger为我提供了两个不同风格的警告框。我希望这两个框看起来一样。 (一个红线横跨页面,另一个不完全横跨) - Daniel
嗯,我认为两个框的样式是相同的,不同之处在于发送者,上面的来自Rails验证,而下面的来自Devise消息。很抱歉我不能给你更多的解决方案。但是对于Devise的I18n,您可以在config/locales/devise.en.yml上自行更改。如果还是不太理解,请见谅。 - ksugiarto
谢谢,你的回答帮助我理解了CSS如何与I18n配合使用,但这里有另一篇我发表的帖子,更清楚地说明了我的问题。我相信我的问题与Devise有关。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接