I'm using responders gem, and I want to show validation errors when form is not valid. In my controller I created the interpolation_action
def interpolation_options
{ resource_errors: #project_user.errors.full_messages.join(', ') }
end
and my reponders translation file has a proper key:
project_users:
create:
notice: "Member has been added"
alert: "%{resource_errors}"
It works well and I can see validation error message, the problem is that apostrophe is changed to ASCII code.
Does Responder still require you to add the flash in your html? In that case you could do something like <%= flash[:alert].html_safe %> to enforce html on your flash message, even for the escaped characters.
Related
I have a controller like this in my project:
class BriefcasesController < ApplicationController
...
def update
#super_power = SuperPower.find(params[:super_power_id])
#briefcase.contents.delete(params[:super_power_id].to_s)
flash[:notice] = "Successfully removed #{view_context.link_to(#super_power.title, super_power_path(#super_power)} from your briefcase."
redirect_back(fallback_location: '/briefcase'
end
end
The link_to helper is not rendering a link to the browser, rather it's printing the html: Successfully removed <a href=\"/powers/1\>flying</a> from your briefcase. I've also tried using the method #html_safe on the flash message to no avail. I'm wondering if there's a way to fix this using view_context or if there's a better way to include a link inside a Flash message.
You need to use html_safe when outputting the flash messages - not when storing them.
<% flash.each do |key, msg| -%>
<%= content_tag :div, msg.html_safe, class: name %>
<% end -%>
.html_safe just sets a flag on the string object that its trusted and should not be escaped.
The flash works by storing flash messages in the session storage - by default this means a cookie in the browser.
So when you do:
flash[:notice] = "foo"
You're storing the raw string "foo" in a cookie* and its unpacked back into the session on the next request. But the string is not the same Ruby object - so the html_safe flag on the string object is not persistent.
Note: the following only works with relatively old versions of Rails (confirmed in 4.0 and before, possibly in 4.1). Rails used to allow custom objects to be passed in flash messages, but later changed it to only allow primitive objects (documented at https://github.com/rails/rails/issues/15522).
You need to call html_safe on the entire string. Using string interpolation ("#{some_ruby_code}") changes the "safe" link_to string back into a regular string that gets escaped.
In my controller I have an if condition and I want an alert/confirmation box to pop up if it is satisfied, then when the user clicks "ok" to redirect to another page.
I've tried
flash[:alert] = 'Successfully checked in'
redirect_to check_in_path
However it just skips the alert part and goes straight to the redirect without an alert message.
My Ruby version is ruby 2.2.6p396 and rails is 5.0.1
Any help would be appreciated
You need to create a js.erb file. You can then use your existing rails code along with a js alert box. Js.erb files let you combine rails and JavaScript code in the same file. As mentioned flash[:alert] is not an alert box, alert is a css class.
Rails is limited to the respond to HTTP request with HTML. And what you describe sounds more like a JavaScript alert. What you tried, if configured properly*, will simply show the flash alert when the check_in_path page is rendered.
* Get familiar with how the flash works, Rails Guides
You have your controller set up correctly. The only other part I meant by configured correctly is that in your views you should display said flash message:
<% flash.each do |name, msg| -%>
<%= content_tag :div, msg, class: name %>
<% end -%>
It's common to use the name of the flash to style it to make to make it's intent clear; commonly red for failure, green for success.
you can do it as follows
render :update do |page|
page << "alert('Successfully checked in')"
page.redirect_to check_in_path
end
but partial rendering in controller is most commonly used together with Ajax calls. so you may have to make an ajax call to your action from your view page. Hope this will help you
I am using the rails 3.2.5 ActionMailer to send plain text mails. Given I have a mail view like this:
message_from_user.text.erb:
Hi <%= #recipient.name %>,
You got the following message from <%= #sender.name %>:
<%= #message %>
When #message is "quotes & ampersands", then the plain text mail contains "quotes & ampersands". So it seems like rails just treats this as a HTML view and escapes any html in order to prevent cross site scripting. However this is a plain text mail. The extension is .text.erb and ActionMailer detectes this and sets the MIME to text/plain. So I never want to escape any html in it.
I have quite a few mail templates in my application, they are all plain text. I would consider patching all of them to include <%=raw #message%> or <%= #message.html_safe %> bad style - not very DRY.
I tried varios work-arounds that included money patching Erubis. None of them seem to work. I am looking for some patch or config option or anything to disable escaping html for all .text.erb files.
Any help is greatly appreciated!
After some hours of debugging through the Erubis code, I found the following fix. You can just put it into config/initializers/fix_my_mails.rb. I've tested this with rails 3.2.7. It may work with other versions.
module ActionView
class Template
module Handlers
class ERB
def call(template)
if template.source.encoding_aware?
# First, convert to BINARY, so in case the encoding is
# wrong, we can still find an encoding tag
# (<%# encoding %>) inside the String using a regular
# expression
template_source = template.source.dup.force_encoding("BINARY")
erb = template_source.gsub(ENCODING_TAG, '')
encoding = $2
erb.force_encoding valid_encoding(template.source.dup, encoding)
# Always make sure we return a String in the default_internal
erb.encode!
else
erb = template.source.dup
end
self.class.erb_implementation.new(
erb,
:trim => (self.class.erb_trim_mode == "-"),
:escape => template.identifier =~ /\.text/ # only escape HTML templates
).src
end
end
end
end
end
It just disables HTML entities in every erb file containing .text in the file name.
Try
<%= #message.html_safe %>
You'd found this answer if you had used the search function. If that doesn't suit your needs, maybe check
https://rails.lighthouseapp.com/projects/8994/tickets/4858-actionmailer-is-html-escaping-ampersand-in-urls-in-plain-text-messages
If you haven't seen that yet, some options are discussed there
I have a rails 2.3 application and would like to integrate the premailer gem to it.
I found how can you do it for a rails 3.X application:
How to Integrate 'premailer' with Rails
Anyone knows how to do it for action mailer 2.3.10?
I've spent a good chunk of the last couple of days on this now and it seems there is no great solution. It is possible to render the message explicitly and then pass the result through Premailer, but it gets messy in combination with multipart emails and HTML layouts and if the template uses some other encoding than ASCII-8BIT.
In a straight HTML email without multiparts and assuming an ASCII-8BIT encoded template, this works for me:
def some_email
recipients "Reciever <reciever#example.com>"
from "Sender <sender#example.com>"
subject "Hello"
content_type "text/html"
message = render_message("some_email", { }) # second argument is a hash of locals
p.body = Premailer.new(message, with_html_string: true).to_inline_css
end
However, if the template is encoded with some other encoding than ASCII-8BIT, Premailer destroys all non-ASCII characters. There is a fix merged into the Premailer repo, but no version has been released since. Using the latest revision and calling Premailer.new(message, with_html_string: true, input_encoding: "UTF-8").to_inline_css or similar should work. The merge commit is https://github.com/alexdunae/premailer/commit/5f5cbb4ac181299a7e73d3eca11f3cf546585364.
In the case of multipart emails I haven't really gotten ActionMailer to use the correct content types internally for rendering the templates. This results in the implicit typing via template file names not working and, as a result, layouts being incorrectly applied to text versions. A workaround for this would be to explicitly use no layout for the text version, resulting in something like this (note the template names):
def some_multipart_email
recipients "Reciever <reciever#example.com>"
from "Sender <sender#example.com>"
subject "Hello"
content_type "text/html"
part "text/html" do |p|
message = render_message("some_email_html", { })
p.body = Premailer.new(message, with_html_string: true).to_inline_css
end
part "text/plain" do |p|
p.content_type = "text/plain"
p.body = render(file: "some_email_text", body: { }, layout: false)
end
end
I use flash[:error] to display a simple message to users that they cannot do a delete operation under certain conditions. I also have a link that will help them to get information about the entity that they wanted to delete and why they cannot do so.
Is it advisable to include this hyperlink in the flash message? Which would mean that I would have a HTML fragment in my controller. If not, how would I go about doing this?
If you want to include a link in your flash message from the controller there are 2 issues. Generating the link and then getting it displayed as HTML.
To use the link_to helper in the controller, fully qualify it.
To have the string display as html (instead of being escaped), call the html_safe method on the string. So the line in your controller might look like:
flash[:error] = "You can't do that. #{ActionController::Base.helpers.link_to "Here's why.", '/more_info.html'}".html_safe
the flash object is a holder for storing view fragments/messages and persist them for one redirection using the session.
I see absolutely no problem in storing a link, or better an URL.
example :
redirect_to posts_path, :alert => "You cannot do that", :flash => { :url => post_path(#post) }
and in layout view, the usual suspects :
- if flash[:alert]
...
- if flash[:url]
= link_to "blah blah", flash[:url]
You can. You can add some Helper in your controller too.
Or you can do it by i18n system.