Imagine in rails I have #template that is an instance of ActionTemplate::View.
Question is: How can I convert #template whose #template.source is <%= "hello from erb" %> to hello from erb?? thanks
Try this...
ERB.new(#template.source).result
ERB#new
Well... messing around with ActionView::Template.new outside of Rails is not really recommended. You need a ton of stuff setup beforehand (init and render)
If you do want to just use ERB, then go with this example
require 'erb'
x = 42
template = ERB.new <<-EOF
The value of x is: <%= x %>
EOF
puts template.result(binding)
And, you can use Kyle's answer to go from your template to ERB.
Related
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
Sometimes it's more convenient to print in <%%>. How to do it in Rails?
http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-concat
Should be what you are looking for.
E.g. the following statement using concat:
<% concat "Output" %>
is equivalent to:
<%= "Output" %>
In ERB:
The <% %> signify that there is Ruby code here to be interpreted.
The <%= %> says output the ruby code, ie display/print the result.
So it seems you need to use the extra = sign if you want to output in a standard ERB file.
Otherwise, you could look at alternatives to ERB which require less syntax,.. maybe try something like HAML. http://haml-lang.com/tutorial.html
Example:
# ERB
<strong><%= item.title %></strong>
# HAML
%strong= item.title
Is that more convenient?
erb has two method to evaluate inline ruby expressions. The <% which evaluates the expression and the <%= which evaluates and prints. There is no global object to print to within the binding context.
As mentioned by Omar, there is a concat method, which is part of ActionView. This will do what you want.
Unlike a scripting language escape, there is no default output for erb. Since erb is simply a function, and given a template and binding will return a variable, it returns the values of text and functions recursively.
There is hot debate as to how much logic should be allowed in a view, but as little as possible is what most people aim for. If you are putting more code than text in the view, you may want to consider refactoring your code.
I'm trying to create a Ruby gem that returns html mark up like so:
class Hola
def self.hi(name = "world")
"hello #{name}"
end
def self.hi_with_markup(name = "world")
"<strong>hello #{name}</strong>"
end
end
However, whenever I try to use it in a test.html.erb file like so:
<%= Hola.hi_with_markup(", please work!") %>
It returns the string with the tags printed instead of actually rendering the html. How can I fix this from the gem side?
Thanks!
In Rails 3 the default changed from "not" escaping HTML to escaping HTML (i.e. converting things like '>' to >) for any String deemed to be unsafe; which is generally any string that has the potential to have user characters, including the output of your gem. There are two ways around this raw() and .html_safe.
Here's a comprehensive answer: raw vs. html_safe vs. h to unescape html
The short answer is to do this:
<%= Hola.hi_with_markup(", please work!").html_safe %>
or
<%= raw(Hola.hi_with_markup(", please work!")) %>
Try this:
class Hola
def self.hi(name = "world")
"hello #{name}"
end
def self.hi_with_markup(name = "world")
"<strong>hello #{name}</strong>".to_html
end
end
I have a rails gem that uses a snippet like:
components = []
components << label_for(attribute)
components << ...
components << text_field(attribute)
return components.join
The gem worked fine in Rails 3.0.1, however it escapes (renders as text in a browser) all HTML after updating to Rails 3.0.2. What am I doing something wrong? Thanks.
As #sj26 points out, either use the rails built-in helper:
<%= safe_join(components) %>
Or use my rails_join gem to make Array#join html-safe aware, in which case your original code will work as is.
String#join isn't SafeBuffer-aware.
String#html_safe marks that you string is already HTML-escaped, preventing users sneaking bits of HTML into your pages. Check out this post by Yehuda Katz on SafeBuffer and why/how you should be using them.
If you have an array of String and SafeBuffer you want to concatenate, make sure you've run #html_safe on them all, or #concat them into a SafeBuffer like so:
['<one>', '<p>two</p>'.html_safe].inject ''.html_safe, &:concat
=> "<one><p>two</p>"
Rails has a built-in helper called safe_join which will do this for you.
http://makandra.com/notes/954-don-t-mix-array-join-and-string-html_safe
class Array
def html_safe_join(delimiter='')
''.html_safe.tap do |str|
each_with_index do |element, i|
str << delimiter if i > 0
str << element
end
end
end
end
[safe_string, unsafe_string].html_safe_join(' ')
# '<span>foo</span><span&t;bar</span>'
Strings are automatically HTML-escaped in Rails3. You need to change that last line to:
return components.join.html_safe
alternately, if editing the gem is too much hassle you can do it from the view:
<%= helper_name.html_safe %>
how about manual quoting?
<%= raw ['<div>', 'any', '</div>'].map{|val| h(val)}.join('<br />') %>
Sometimes it's more convenient to print in <%%>. How to do it in Rails?
http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-concat
Should be what you are looking for.
E.g. the following statement using concat:
<% concat "Output" %>
is equivalent to:
<%= "Output" %>
In ERB:
The <% %> signify that there is Ruby code here to be interpreted.
The <%= %> says output the ruby code, ie display/print the result.
So it seems you need to use the extra = sign if you want to output in a standard ERB file.
Otherwise, you could look at alternatives to ERB which require less syntax,.. maybe try something like HAML. http://haml-lang.com/tutorial.html
Example:
# ERB
<strong><%= item.title %></strong>
# HAML
%strong= item.title
Is that more convenient?
erb has two method to evaluate inline ruby expressions. The <% which evaluates the expression and the <%= which evaluates and prints. There is no global object to print to within the binding context.
As mentioned by Omar, there is a concat method, which is part of ActionView. This will do what you want.
Unlike a scripting language escape, there is no default output for erb. Since erb is simply a function, and given a template and binding will return a variable, it returns the values of text and functions recursively.
There is hot debate as to how much logic should be allowed in a view, but as little as possible is what most people aim for. If you are putting more code than text in the view, you may want to consider refactoring your code.