How to output greek symbols in html using ruby on rails - ruby-on-rails

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

Related

Does Rails' #link_to only accept one parameter in its block when used outside of ERB?

When I did this in ERB, it works as expected, giving me an a tag that wraps around an image and some text
<%= link_to(...) do %>
<img src="..." />
text
<% end %>
But when I tried to put this in a method, the a tag only wraps the last argument, which in this case, is the text.
def build_link
link_to(...) do
image_tag(...)
text
end
end
Looking at the docs, they only gave an example of using link_to in ERB, so is it smart to assume that using it in a method doesn't work as well and can't accept two parameters?
Following up to my comment:
The reason is behavior happens is because of how Ruby handles blocks, and how Rails handles the output for ActionController.
The trick here is to use handy-dandy concat.
def build_link
link_to("#") do
concat image_tag("http://placehold.it/300x300")
concat "hello world"
end
end
Pretend the block you pass to link_to is just another method, and it gets returned some object/value. In this case, your text object gets returned.
But because you want to output both image_tag and text, you need to pass that together to the output.

add <a> tag to all items in hash - Ruby on Rails

This is continuation from This one. Read following question&comments first before looking at this one.
I have following Replacement(Hash) below for switching text on html that I've got from desired url of website using open-uri library.
replacements = {'1杯の'=>'a cup of','たくさん'=>'a lot','たくさんの'=>'a lot of','1週間'=>'a week','午前'=>'a.m.','およそ'=>'about','住所'=>'adress','大人'=>'adult','アフリカ'=>'Africa',‌​'の後で'=>'after','のあとで'=>'after','午後'=>'afternoon','再び'=>'again','ふたたび'=>'again','空‌​港'=>'airport','全て'=>'all','一日中'=>'all day','1日中'=>'all day','いつも'=>'always'...}
And I want to add <a> tag to all english word at hash above, which is linked to online Japanese-English Dictionary service called "Weblio"
Weblio's url format is like this: http://ejje.weblio.jp/{desired english word}
so that <a>tag which should be added to all english word should be like below.
DESIRED+ENGLISH+WORD
Any way to do the easily? I just started learning Ruby on Rails recently, so it would be nice to have detailed and simple explanation for it with some examples.
EDIT
def submit
require 'uri'
require 'open-uri'
require 'nokogiri'
charset = nil
#html = open(params[:url]) do |f|
charset = f.charset
f.read
end
replacements = {'1杯の'=>'a cup of','たくさん'=>'a lot'...}
regex = Regexp.new(replacements.keys.map { |x| Regexp.escape(x) }.join('|'))
#html = Nokogiri::HTML::DocumentFragment.parse(#html)
#html.traverse do |x|
if x.text?
x.content = x.content.gsub(regex, replacements)
end
end
end
EDIT2:
I have a problem, which all <a> tag replaced actually displays as a part of <p> tag and not linking. How I can escape <a> tag form <p>?
EDIT3:
This is what actually happening.
https://techacademy-leoreo2247.c9users.io/result/?utf8=%E2%9C%93&url=https%3A%2F%2Fringo-12.com%2F
inspect element on windowsfor more details
EDIT4:
Seems like it has different problem.
When I inspected element on my app, the code it should display likeWindowsis displaying like <a href="http://ejje.weblio.jp/content/Windows">Windows</a>.
I guess the code "Windows"is encoded to some other format.
Weblio's url format is like this: http://ejje.weblio.jp/{desired
english word}
Well, not quite: you can't have spaces in a url, so you have to do something extra to a phrase like "a lot of".
In rails, by default you use something called ERB to substitute values into a view. ERB allows you to write ruby code in your html and execute it. All your view files have the extension .html.erb--that is a hint that rails first runs your views through the ERB templating engine to produce the .html files. So, you need to read a tutorial on ERB syntax, such as this one. Here is an example of what ERB looks like:
<%
replacements = {
'1杯の'=>'a cup of',
'たくさん'=>'a lot',
'たくさんの'=>'a lot of',
}
replacements.values.each do |phrase| %>
<%= phrase %>
<% end %>
A <%= .... %> block inserts the results of the ruby code contained in the block into the html.
A <% ..... %> block is for ruby code that you want to be executed but whose results are not to be inserted into the html.
If you create your replacements in an action, e.g.:
def dostuff
#replacements = {
...
}
end
then your view would simply look like this:
<% #replacements.values.each do |phrase| %>
<%= phrase %>
<% end %>
Below is an example that demonstrates the use of the ERB templating engine outside of rails.
require 'erb'
require 'uri'
template = %q{ #=> Another way in ruby to write an opening single quote for a string.
<%
replacements = {
'1杯の'=>'a cup of',
'たくさん'=>'a lot',
'たくさんの'=>'a lot of',
}
replacements.values.each do |phrase| %>
<%= phrase %>
<% end %>
} #=>Closing single quote for the string
renderer = ERB.new(template)
result = renderer.result()
puts result
--output:--
a cup of
a lot
a lot of
In rails, you don't need to write the require or ERB.new() or renderer.result()--rails does all that automatically for an .html.erb file
Once you write a few views using ERB, and you feel comfortable with the basics, you can promptly forget about ERB and use one of the better templating languages, like slim, which is much prettier and easier to type than ERB. Rails has the means for incorporating any templating engine of your choice--but the default is ERB.
Response to comment:
def dostuff
replacements = {
'1杯の'=>'a cup of',
'たくさん'=>'a lot',
'たくさんの'=>'a lot of',
}
replacements.each do |key, val|
replacements[key] = %Q{#{val}}
end
require 'pp' #pretty print
pp replacements
end
Output in server window:
{"1杯の"=>"a cup of",
"たくさん"=>"a lot",
"たくさんの"=>"a lot of"}
Response to comment:
Your str is html escaped. If you need to literally display all the characters in the string <a>hello</a> on a web page, you must replace the angle brackets with what are called html entities, otherwise the browser will render the <a> tag as a link. The html entity for the < character is <, where lt stands for less than, as in a less than symbol in a mathematical comparison: if x < 4. Similarly, the html entity for the > character is >, as in greater than.
require 'cgi'
str = %q{Windows}
puts "<div>This is an html instruction site. First we will start with link tags.</div>"
puts "<div>Link tags look like this:</div>"
puts "<div>#{CGI.escapeHTML str}</div>"
str = %q{<a href="http://ejje.weblio.jp/content/Windows">Windows</a>}
html = CGI.unescapeHTML str
puts "<div>Here is what that link looks like when it is rendered by a browser:</div>"
puts "<div>#{html}</div>"
--output:--
<div>This is an html instruction site. First we will start with link tags.</div>
<div>Link tags look like this:</div>
<div><a href="http://ejje.weblio.jp/content/Windows">Windows</a></div>
<div>Here is what that link looks like when it is rendered by a browser:</div>
<div>Windows</div>
If you take the output of that program and open it in a browser, you will see:
This is an html instruction site. First we will start with link tags.
Link tags look like this:
Windows
Here is what that link looks like when it is rendered by a browser:
Windows

Excess spaces wile rendering multiline string in Rails 5

I end up with strange bug (feature?):
Here is how test.html.erb file looks like:
<textarea><%= "a\nb\nc" %></textarea>
and in rendered textarea I expect something like that:
a
b
c
But I got:
Where these excess spaces came from?
Rails 5.0.0.beta2
UDP: I should mention it before, but I have the same problem while using f.text_area inside of form_for block. It looks like:
.form
=form_for article do |f|
.form-group
=field_label f, :text, true
=f.text_area :text, class: %w(form-control), rows: 20, placeholder: t('placeholder.article_text')
(HAML)
I end up with it, and just simplified the exploit to simple erb file with one string
UDP2:
Here how it looks with simple_format: <textarea><%= simple_format("a\nb\nc") %></textarea>
I should clearify some thing: this textarea is used to edit article text. And then it (text) will be processed with markdown processor (RDiscount) before appears in html page. I have no any idea, why I should use simple_format to display raw text in textarea and why this
should became this
after save?
In HAML, use
~ f.text_area :text
instead of
= f.text_area :text
The ~ operator suppresses "pretty" newlines in HAML, which is useful with TEXTAREA and PRE tags. See Whitespace preservation in HAML for more information.
<textarea><%= "a\r\nb\r\nc" %></textarea>
\n is new line it will take to next line at same position where you was in previous line \r is carriage return mean move to start of line.
But I wont recommend this approach You should use <br/> tag instead
so use
<textarea><%= WhatEverTheTextIs.gsub(/\n/, '<br/>').html_safe %></textarea>
This will replace all new line characters to <br> tag
One more easy solution is to use simple_format i-e:
<textarea><%= simple_format(YOUR_TEXT_HERE) %></textarea>
UPDATE
Here is the code to use for form helper
.form
=form_for article do |f|
.form-group
=field_label f, :text, true
=f.text_area :text,:value=>simple_format(article.text), class: %w(form-control), rows: 20, placeholder: t('placeholder.article_text')
I just ran into the exact same problem. It all comes down to whitespace in your templates and layouts. In my case my main application is using HAML and has an application.html.haml with a section like so
#content.container{tabindex: "-1"}
.row
- if content_for?(:left_nav)
.col-md-3.sidebar
= yield(:left_nav)
.col-md-9
= flash_helper
= yield
%footer
= render :partial => 'shared/footer'
That's at least 10 spaces before the "yield" of the main content.
Then I was using a view from a gem that was in ERB, not HAML. But, since my main application layout is HAML, the view rendering/handling goes through the HAML renderers. HAML has dealt with whitespace and texareas already, but when the final and complete view is rendered, all of the extra whitespace from the main layout is included in the html and causes the content of the textarea to be indented.
Why is the first row not indented? Because the HAML "preserve" function cleans up the whitespace for the first row in the text area. See https://github.com/haml/haml/issues/516.
For me, the easy fix is to configure HAML to use "ugly" mode. This gets rid of all the leading whitespace when rendering the views. There is more about "ugly" mode and newlines in textareas in the HAML FAQ. To configure HAML to use ugly mode:
To improve performance, Haml defaults to {Haml::Options#ugly "ugly" mode} in Rails apps running in production. Ugly mode is when whitespace is stripped out, and this can cause issues occassionally.
If you are using Rails, you can change the default behaviour by creating a config/initializers/haml.rb file and adding in the following line.
Haml::Template.options[:ugly] = true
Links I found helpful while researching this:
https://github.com/haml/haml/issues/643
ERB view embedded in a Haml layout: what to do about whitespace now? (although the proposed solution didn't work for me b/c the ERB view would always be picked up before the HAML view)
https://github.com/haml/haml/blob/master/lib/haml/buffer.rb (fix_textareas)
https://github.com/haml/haml/blob/master/lib/haml/helpers.rb (specifically the preserve method)
My versions are Rails 4.2.6 and HAML 4.0.7

Rails escapes string inside label tag

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

Line breaks not displaying in view

I have Person.description with the following stored in the database:
jnkl
fdsfdsf
fdsf
fsdfdsfs fds fd sf sdf ds
How do I display this with the line-breaks in the view? It is currently displaying all on one line and I don't understand why.
you should use the simple_format helper:
<%= simple_format #person.description %>
http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format
Source
# File actionview/lib/action_view/helpers/text_helper.rb, line 301
def simple_format(text, html_options = {}, options = {})
wrapper_tag = options.fetch(:wrapper_tag, :p)
text = sanitize(text) if options.fetch(:sanitize, true)
paragraphs = split_paragraphs(text)
if paragraphs.empty?
content_tag(wrapper_tag, nil, html_options)
else
paragraphs.map! { |paragraph|
content_tag(wrapper_tag, raw(paragraph), html_options)
}.join("\n\n").html_safe
end
end
The reason why, is that in plain HTML, outside of containing tags such as 'xmp', line breaks aren't rendered as linebreaks, for the most part they are ignored. For them to show up, you need to replace them with 'br' tags, or something else that has a style or structure associated with it, like p tags, or even divs, depending on the content is.
This should do what you ask:
#person.description.gsub(/\n/, '<br />')
The built in Rails helper simple_format will also work, using p tags
http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format
I also use
#person.description.gsub(/\n/, '<br/>').html_safe
to display them in the view
Instead of replacing \n to <br> tags, which would consume a lot of processing if its a huge text, use css white-space: pre to break lines on \n.
Source: An html tag other than a textarea where \n is correctly interpreted
simple_format did not suit my needs as I want to be able to show multiple line breaks. simple_format makes 2 or more line breaks a paragraph.
So, I used css white-space: break-spaces; instead. The only current drawback is the browser support is 89.5% now.

Resources