How to escape all HTML in a block in Rails ERB view - html

Essentially I want something like the following:
<code class="snippet">
<%= html_escape do %>
My markup displayed to user
<% end %>
</code>
However the html_escape method does not accept a block. If this is not built into Rails API somewhere else, perhaps using some helper, does anyone have advice on how to make a custom helper where the yield statement output is captured into a string that I can then escape myself?
Thanks,
Keith

Rails' capture and escape_once helper methods can create a String from a block in an erb template and then output an escaped version of it:
<% snippet = capture do %>
My markup displayed to user
<% end %>
<code><%= escape_once snippet %></code>
content_for is another helper that provides similar functionality to capture, that you may consider using depending on the situation.
To explain, snippet is an ActiveSupport::SafeBuffer, and is why escape_once is needed. You could achieve the same by calling snippet.to_str instead of escape_once snippet (However .to_s will not work as that is different to .to_str in ActiveSupport::SafeBuffer).

Related

erb without rails helpers

I'm switching a python app to ruby and need to implement erb into the html and am clueless as to how to implement some of the most basic things. It seems like everything that I look up basically recommends using rails helpers that aren't available to me. I'm trying to get the below line to work. I figured anything in the loop would get interpolated, but my links aren't working. Any help would be much appreciated.
<% for employee in #employees %>
<div class="col-sm-6 col-md-3 employee">
<a style="text-align:center;" href="/employee/#{employee.id}" class="thumbnail">
<% if !employee.filename? %>
<img src='#{settings.employee_image_url}'>
<% else %>
<img src='#{settings.no_image_url}'>
<% end %>
The follow should fix the issue.
<img src="<%= settings.no_image_url %>">
String Interpolation is only executed by Ruby, "#{settings.no_image_url}" is not a Ruby string in the context that you're using it.
Try using double quotes here '#{settings.employee_image_url}' instead of single quotes. So "#{settings.employee_image_url}"
I moved the link and image tags into separate methods. That contain the strings. so..
def tag_string
"<a style='text-align:center;' href='/employee/#{employee.id}' class='thumbnail'>"
end
and call it in the view like this:
<%= tag_string %>
Basically, all you have to do is make whatever tag you're interpolating into a string with double quotes and put the erb tags on either side. This is the answer I wish I would've found with googling.

Dynamically modify id within html tag using embedded ruby

How can I dynamically set the id within an html tag?
Specifically, I'm trying to do the something like this:
<td <% "id=unit_" + unit.id.to_s %> > *content goes here* </td>
where unit.id is an integer variable.
Can I used embedded ruby (i.e. <% %>) within an html tag like this?
If not, how else can I achieve what I'm trying to do?
<td id="<%= unit.id.to_s %>">...</td>
Anywhere in your template you place a <% %> or <%= %> tag it will be evaluated as ruby code. It's not like an html tag that can't be stuck inside other tags like <li class=<p>> or something. That's just nonsense. But with erb, that would be cool: <td id="<%= unit.id %>">
Notice the extension on the file names used with erb - my_view.html.erb. This tells you the template is first processed by ERB (Embedded Ruby), aka ruby, and then it's read as an html document. So what you really care about is the document being valid html after it's processed by erb.
Hope that helps!
Also note that in your question you use the <% %> tag which will evaluate ruby but not output anything into your template. The = sign (<%=) tells erb to print out the result of the executed ruby code.

Writing a Ruby method in the model that outputs HTML in the view

I've got a method in my view that decides which HTML to print out depending on the class of the object it gets:
<% def laybricks(c,stream) %>
<% if c.is_a?(Post) %>
<article>
// Tons more HTML unique to posts
</article>
<% elsif c.is_a?(Photograph) %>
<article>
// Tons more HTML unique to photographs
</article>
<% end %>
<% end>
But I now know more about Rails since writing it. How can I transfer this to my model so that I can call the method in the view and have it print the HTML the same?
Method in a view would definitely be better moved to the helper.
But for your need the best solution is partials utilizing some rails magic:
<%= render #c %>
will magically render partial _post.html.erb if #c is an instance of Post and _photograph.html.erb if it is instance of Photograph. These partials should be in the same view folder, and you can reference your object as post and photograph in each partial respectively.
For more info see Rails Rendering Guide.
ADDON:
How can I transfer this to my model so that I can call the method in the view and have it print the HTML
It is usually not a responsibility of a model to generate HTML, but if you ultimately want to do this, the best way is to use a design pattern that is usually referred to as Presenter or Decorator. E.g. draper gem exists for this, but also many other. And there is many discussions in Rails community how this pattern should be called, how it should be implemented and is it worth it at all.
UPDATE:
Application Helper
def laybricks(c,stream)
content = []
if c.is_a?(Post)
content << "<article> </article>"
elsif c.is_a?(Photograph)
content << "<article> </article>"
end
end
Your View
<%= raw laybricks %>
OR
<%= laybricks.html_safe %>
NOTE: The raw helper will allow the plain html to get interpreted. You can also use html_safe method to interpret the same.

Rails content_tag helper for simple things?

Should I be using the content_tag helper for all html tags when working with Rails?
Is it The Rails Way to use content_tag for even simple things like Header tags?
<%= content_tag :h2, :class => "bla bla" do %>
Header
<% end %>
vs.
<h2>Header</h2>
Clearly just using straight html is much 'simpler' and 'shorter', but what is the correct Rails Way of doing things?
Using content_tag when you don't have to is a waste. There's no need to use ERBisms to generate static HTML so don't do it. If some other piece of code determines what tag to use, then you'd use content_tag to construct that tag.
If you are asking the rails way of doing this, then its defiantly using 'content_tag', but using tag_helpers has its own advantages and disadvantages
Personally for me I can see these things, (Using rails helpers instead of pure HTML)
Advantages
1 - Your code will be cleaner. (with less lines)
2 - You will have more control other the elements.
Ex: You can have your own helper tags like 'big_text_box' which will return a text box more than the normal with and you can use it across all the site
3 - You will be able to add attributes like class, id dynamically in the runtime
Disadvantages
1 - If you have a separate designer (I mean UI engineer) he/she will get confuse of by the code you have use. As its not pure html
2 - Its slow than the pure html (But this will not even noticeable unless otherwise your app is a damn major one...)
So its up to you to decide what to use, personally I prefer using rails helper tags as it makes me more comfortable
HTH
cheers
sameera
One useful method is the "div_for", which is somewhat similar to the content_tag. If you find yourself marking up HTML elements with data you can reference later, "div_for" makes your life much easier.
Let's say you have a bunch of people being shown on a page and you need to wrap each with a div that has a unique ID so you can modify these elements with JS. By hand and straight HTML you would have to do:
<% #people.each do |p| %>
<div id="person_<%= p.id %>"><%= p.name %></div>
<% end %>
That would get bothersome if you were doing LOTS of this with multiple attributes (I commonly use custom IDs, classes, and some data attributes). But using div_for you could write the above as:
<% #people.each do |p| %>
<%= div_for(p) do %><%= #person.name %><% end %>
<% end %>
Makes the HTML a little easier to read when things get long and complex. I found it is much cleaner when working with javascript a lot.
http://apidock.com/rails/ActionView/Helpers/RecordTagHelper/div_for

Avoid rendering comments in HTML

I have a lot of comments in Rails views.
How i can prevent rendering them ?
If I understand the question correctly, you're asking about Ruby/Rails comments vs HTML comments... Give this a try in your view:
<!-- This is an HTML comment and will show up in the HTML source! -->
Now try this:
<%# This is a comment that won't show up in the HTML source! %>
<%#
You can even use this for commenting multiple lines!
How useful!
%>
Does that help?
use =begin and =end to mark the beginning and end of your comment
There is no easy way to do that. You can monkey patch ERB sources, perhaps, but it is a bit nerdy.
I'm not a Rails programmer, but a quick but of Binging brought up this link:
http://blog.brijeshshah.com/strip-tags-in-rails-javascript-and-php/
The approach he's using is one that I've used in the past where you sanitize the view's output. sanitize being the name of the function you want to use before rendering the view.
Maybe you can use Haml Comments: -# allow to comment your haml code without them appearing in the generated html.
Kind of hackish, but you can wrap it in a helper method
In your view:
<% comment do %>
<%= "this won't be executed" %>
or displayed
<% end %>
in app/helpers/application_helper.rb
module ApplicationHelper
def comment(&block)
## you can do something with the block if you want
end
end