We're implementing SendGrid unsubscribe groups (documentation). They require tags such as <%asm_group_unsubscribe_url%> to be included raw in the email that is then sent to SendGrid where they replace that tag.
How can I put these raw tags into my ERB template output with ActionMailer?
I've tried something like <%= raw("<%asm_group_unsubscribe_url%>") %> but it fails compilation. I've also tried escaping like <%asm_group_unsubscribe_url%> but then SendGrid doesn't replace it correctly.
Is there anyway for me to output this tag raw without escaping it?
Did you try <%%= asm_group_unsubscribe_url %>?
Double percent symbol <%% indicates that you want the literal <%
Related
Rails 7 / Ruby 3
I'm currently working on a site that requires code examples to be displayed on a page - I can get these to display utilising the extra % character trick, however, for some of the examples I need to have a variable within them that is resolved (e.g. like the users' own API key etc...).
Consider I have #variable = "Resolved Variable"
<%%= link_to #variable, variable_path %>
Outputs on the page explicitly as
<%= link_to #variable, variable_path %>
But I really need the #variable to resolve and show on the page as:
<%= link_to "Resolved Variable", variable_path %>
I've tried all kinds of escaping the variable, but it seems that <%%= ensures that nothing following it can be resolved.
Any ideas?
Any text you haven't html_encodeed will be displayed as plain text.
My suggestion to you is to create a interpolated string that you could use to generate your intended result. For example:
output_text = "<%= link_to '#{#variable}', variable_path %>"
And, not sure if this is what you're looking for, but you can get a good UI by adding some Javascript library to format you code in the language in intend (in this case Ruby, it seems).
In case that's interesting to you, check the Prism lib, or check how to add it to your project here
I hope this helps.
With kind regards,
Rogerio
<%% in ERB will simply output <%, no more, no less. In particular, it won't attempt to parse the code after <%% as Ruby. However, this doesn't mean that you can't have another <%= ... %> after <%%:
require 'erb'
template = <<-EOD
<%%= link_to <%= #variable.inspect %>, variable_path %>
EOD
#variable = "Resolved Variable"
puts ERB.new(template).result
The inspect method will add quotes around your string and also escape certain characters as needed.
Output:
<%= link_to "Resolved Variable", variable_path %>
I want to take as input text that takes the full greek name for a letter and displays it as a single greek letter. e.g. take 'alpha' and replace it with α.
My code looks like this
def name(y1)
"&#{y1};"
end
with the output put into a html page using erb, i.e.
<%= name('alpha') %>
but the result is displayed in the html as α . How do I make it display α?
Based on: Disable HTML escaping in erb templates
The escaping occurs in the ERB so you need to specify that the string is safe in the ERB.
Try this:
def name(y1)
"&#{y1};"
end
<%= name('alpha').html_safe %>
I have a label tag, whose content is loaded from a en.yml file.
html.erb
<%=label_tag(:name, t(:name, scope:[:helpers, :form], name: person_name(person))).html_safe%>
person_name is a helper and outputs a string
persons_helper.rb
def person_name(person)
content_tag(:span,
formatted_name(person.name) || t("helpers.persons.default_name"),
class: 'name').html_safe
end
output string from the helper is passed on t method and concatenated as following
en.yml
name: "Person Name: (%{name})"
I want the output to be like
<label for="person">
Person Name:
<span class='name> John Doe </span>
</label>
but Instead I get
<label for="person">
Person Name:(<span class="name">John Doe</span>)
</label>
I understand that it got to do with html_safe, raw and escaping strings but I just could not get it to work!
Thanks!
Call .html_safe on the method call inside the label_tag. E.g:
<%=label_tag(:name, t(:name, scope:[:helpers, :form], name: person_name(person).html_safe))%>
It appears that the I18n.t method does not return a SafeBuffer (i.e. an html_safe string). So you should call .html_safe on the output from this method.
<%= label_tag(:name, t(:name, scope:[:helpers, :form], name: person_name(person)).html_safe) %>
Note the .html_safe call has been moved in one parenthesis from where you had it. This can also be made marginally easier to see by using the block form of the label_tag helper.
<%= label_tag(:name) { t("helpers.form.name", name: person_name(person)).html_safe } %>
Note: I also switched to the "helpers.form.name" method of selecting the I18n translation in this example to further increase readability (but this may be just a personal preference -- so use your original style if you prefer!).
Finally, for security purposes -- so that a user's name doesn't come through unescaped -- you should remove the .html_safe from your person_name helper and add a strict html_escape (or sanitize) so that it looks like this:
def person_name(person)
content_tag(:span,
h(formatted_name(person.name)) || t("helpers.persons.default_name"),
class: 'name')
end
In this form, the content_tag will make sure everything is html_safe except for the content. Meaning that the person.name will come through as is and be escaped as needed. However, this is not needed if the formatted_name method returns an already escaped or html_safe name. Basically the point is that you don't want to blindly mark strings as html_safe when they come from user inputted values because you don't know if they contain script tags or what. Hopefully this didn't confuse. :) In general, only mark strings as html_safe when you are 100% sure that they are actually always going to be safe (i.e. they come from within your system and not from user input of any sort).
Rails translations can be automatically marked as html_safe but using a naming convention. If a translation is suffixed with _html then the string is marked as html_safe, likewise keys named html are also marked as html_safe.
# config/locales/en.yml
en:
welcome: <b>welcome!</b>
hello_html: <b>hello!</b>
title:
html: <b>title!</b>
In the above t('hello_html') and t('title.html') will be html_safe strings and will not require a call to raw or .html_safe where as t('welcome') will not be html_safe and will require calling raw or .html_safe to avoid the html in the string being escaped.
See http://guides.rubyonrails.org/i18n.html#using-safe-html-translations
I'm trying to show the contents of a field from the database in a <p> element. In the html.erb template the code looks like:
<p><%= front.gsub(/(\r)?\n/, "<br>") %></p> ...
The issue I'm having is that to escape the breaks, I have to apply the .html_safe method at the end of the above gsub, but doing so opens the whole application to XSS attacks. How can I only allow the breaks to be escaped?
You can use the simple_formatmethod.
<%= simple_format(front) %>
More here => http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format
This is based on the simple_format helper. We can use sanitize to remove bad tags that allow XSS attacks.
<%= sanitize(front).gsub(/(\r)?\n/, "<br/>").html_safe %>
You can also use strip_tags if you want to remove all HTML tags before replacing new lines with <br>.
<%= strip_tags(front).gsub(/(\r)?\n/, "<br/>").html_safe %>
Have you considered wrapping the text into <pre>-tags instead? That will keep the basic formatting (newlines, spaces, ...).
I have this:
"<img src='#{picture.url(:tiny)}'>"
Which is output like this:
<img src='/system/pictures/2/tiny/Womacdsf.jpg?1294942797'>, <img src='/system/pictures/3/tiny/Womacdsf_3017.jpg?1294942797'>, <img src='/system/pictures/4/tiny/Womacdsf_8012.jpg?1294942797'>, … (8)
As you can see, this is encoding using < and > instead of using the raw < and >.
How can I tell Rails this is not what I want?
using
<%= image_tag picture.url(:tiny) %>
should work
for your problem you can also use this
"<img src='#{picture.url(:tiny)}'>".html_safe
If you're using Rails 3, XSS protection is on by default. That means that HTML is escaped by default.
Where you might have once used the "h" helper to generate escaped HTML, you no longer need to, but instead will need to use the "raw" helper to prevent escaping.
See http://asciicasts.com/episodes/204-xss-protection-in-rails-3
You have two options. Either un-escape the string using raw when you print it
<% image_string = "<img src='#{picture.url(:tiny)}'>" %>
<%= raw image_string %>
Or you can mark the string as html_safe
<% image_string = "<img src='#{picture.url(:tiny)}'>".html_safe %>
<%= image_string %>