Rails 3 link_to inside a string - ruby

Everytime I am trying to combine a string with a link_to it is outputting in my browser as escaped HTML.
eg.
%(TEST #{link_to(object.title, object)})
OUTPUTS
TEST TEST OBJECT
Why is this happening ? Every example I see on net the link_to does not get escaped.

Output is escaped by default in Rails 3. If you append .html_safe to your string it will do what you expect.
%(TEST #{link_to(object.title, object)}).html_safe

This also do the job:
<%=raw %(TEST #{link_to(object.title, object)}) %>

Related

ActionView::SyntaxErrorInTemplate at /template_name

I need to dynamically load a sidebar's content into a sidebar partial based on the presence of a directory name-spaced as the controller_name (if present) and the action_name (always used). They both are derived from the Rails hash and map to the .../views/sidebars/[controller_name]/[action_name] if there is a directory for the controller_name and to .../views/sidebars/[action_name] if there isn't an associated directory namespaced with the Controller's name.
/views
/sidebars
/static
/_about.html.erb
/_contact.html.erb
/...
/_styles.html.erb #outside of any controller structure
I am trying to use the following code to dynamically load the correct sidebar partial:
<%= "sidebars/#{controller_name}".to_s.present? ? yield("sidebars/#{controller_name}/#{action_name}" : yield("sidebars/#{action_name}") %>
This checks to see if there is a directory called by the controller_name and it renders the correct partial based on the structure indicated.
I am getting the following error:
Encountered a syntax error while rendering template: check <div id='sidebar_left'>
<p>Template: [_sidebar-left.html.erb]</p>
<%= render "sidebars/#{action_name}" %>
<%= "sidebars/#{controller_name}".to_s.present? ? yield("sidebars/#{controller_name}/#{action_name}" : yield("sidebars/#{action_name}") %>
UPDATE
Ok so it turns out that ternary operators don't always return the value, particularly if it is a computed string value. In this case, I was expecting the value to return as either sidebars/static/home or sidebars/styles. For some reason I can't explain, ternary operators don't work that way, even though I (thought!) I was returning a string value from the operation.
To get rid of the syntax error, I had to assign the operator to a variable name, in this case sb_name and then render it on the next line. This is the final code:
<% sb_name = "sidebars/#{controller_name}".to_s.present? ? "sidebars/#{controller_name}/#{action_name}" : "sidebars/#{action_name}" %>
<%= render sb_name %>
Now, while this resolved the syntax error, I am now getting a Missing partial sidebars/_about error in the view. The _styles file exists as /views/sidebars/_styles.html.erb, right where it should. Since there is not a folder name-spaced to the controller being called (in this case StylesController), it should be pulling up the file directly underneath the /sidebars/ directory. However, this is not the case.
I found some help on SO here. I wasn't checking the directory/file structure properly. The final syntax is this:
<% sb_name = File.directory?("app/views/sidebars/#{controller_name}") ? "/sidebars/#{controller_name}/#{action_name}" : "/sidebars/#{action_name}" %>
<%= render partial: "#{sb_name}" %>

Error in a Phoenix template list

I'm trying to extract values form a list (<%= #evento %>) in a template but I'm getting this error:
lists in Phoenix.HTML and templates may only contain integers representing bytes, binaries or other lists, got invalid entry: %Skeleton.News.Evento{__meta__: #Ecto.Schema.Metadata<:loaded, "news_eventos">, date: "DEZ 2011", id: 69, imgPaths: ["images/fabasa/eventos/one/1.jpg", "images/fabasa/eventos/one/2.jpg", "images/fabasa/eventos/one/3.jpg", "images/fabasa/eventos/one/10.jpg"], inserted_at: ~N[2017-06-30 12:38:15.452214],...
So, my question is how to transform this in a datatype structure that I can still iterate in my template?
You cannot print a list like that in a template because templates only allow iolists to be printed, which are lists containing integers, binaries (also called String in Elixir), or iolists.
If you want to print the inspect representation of the list (the one you see in iex), you can do:
<%= inspect #evento %>
To iterate through the list, you can use for:
<%= for event <- #evento %>
<%= event.id %>
<% end %>

How to sanitalize string with nested html tags but keep <em> tag?

I am trying to sanitalize Solr search results, cause it has html tags inside:
ActionController::Base.helpers.sanitize( result_string )
It is easy to sanitalize not highlighted string like: I know <ul><li>ruby</li> <li>rails</li></ul>.
But when results is highlighted I have additional important tags inside - <em> and </em>:
I <em>know</em> <<em>ul</em>><<em>li</em>><em>ruby</em></<em>li</em>> <<em>li</em>><em>rails</em></<em>li</em>></<em>ul</em>>.
So, when I sanitalize string with nested html and highlighting tags, I get string with peaces of htmls tags. And it is bad :)
How can I sanitalize highlighted string with <em> tags inside to get correct result (string with <em> tags only)?
I found the way, but it's slow and not pretty:
string = 'I <em>know</em> <<em>ul</em>><<em>li</em>><em>ruby</em></<em>li</em>> <<em>li</em>><em>rails</em></<em>li</em>></<em>ul</em>>'
['p', 'ul', 'li', 'ol', 'span', 'b', 'br'].each do |tag|
string.gsub!( "<<em>#{tag}</em>>", '' )
string.gsub!( "</<em>#{tag}</em>>", '' )
end
string = ActionController::Base.helpers.sanitize string, tags: %w(em)
How can I optimize it or do it using some better solution?
to write some regex and remove html_tags, but keep <em> and </em> e.g.
Please help, thanks.
You could call gsub! to discard all tags but keep only tags that are independent, or that are not included in html tag.
result_string.gsub!(/(<\/?[^e][^m]>)|(<<em>\w*<\/em>>)|(<\/<em>\w*<\/em>>)/, '')
would do the trick
To explain:
# first group (<\/?[^e][^m]>)
# find all html tags that are not <em> or </em>
# second group (<<em>\w*<\/em>>)
# find all opening tags that have <em> </em> inside of them like:
# <<em>li</em>> or <<em>ul</em>>
# third group (<\/<em>\w*<\/em>>)
# find all closing tags that have <em> </em> inside of them:
# </<em>li</em>> or </<em>ul</em>>
# and gsub replaces all of this with empty string
I think you can use the sinitize:
Custom Use (only the mentioned tags and attributes are allowed, nothing else)
<%= sanitize #article.body, tags: %w(table tr td), attributes: %w(id class style) %>
So, something like that should work:
sanitize result_string, tags: %w(em)
With an additional parameter to sanitize, you can specify which tags are allowed.
In your example, try:
ActionController::Base.helpers.sanitize( result_string, tags: %w(em) )
It should do the trick

Rails I18n localication

I am developing a multilingual website in Ruby On Rail very first time, that's why i am converting a label of the forms of the website in different language like this <%=t (:artist) %> <%=t (:name) %>, can we translate this variable in one line like <%=t (:artist, :name) %>, actually when i use it give me error.
/var/www/musicradio/trunk/app/views/musicuploads/_searchtype.html.erb:17: syntax error, unexpected ',', expecting ')'
...put_buffer.append= (t (:artist,:or) );#output_buffer.append=...
... ^
Please help me....
It would be easier if you Group translations instead of translating markup.
Instead of having two separate tags, use this in your en.yml
log_in_or_sign_up:
text: "%{log_in} or %{sign_up} to do stuff."
log_in: "Log in"
sign_up: "Sign up"
Then on the .erb
<%= t(
:'log_in_or_sign_up.text',
log_in: link_to(t(:'log_in_or_sign_up.log_in'), login_path),
sign_up: link_to(t(:'log_in_or_sign_up.sign_up'), signup_path)
) %>
More info: http://thepugautomatic.com/2012/07/rails-i18n-tips/

Dynamic markup with MVC

I have markup stored in a database, which I am pulling out and placing onto a page.
below is a basic sample of what I have, without any db calls for ease of example;
The controller:
ViewData["testMarkup"] = "I was here <%= DateTime.Now.Year %>";
The View:
<%= ViewData["testMarkup"] %>
now this out puts: I was here
and no date, this is because it is ignoring the <%= %> part, is there anyway I can output the above said string and woudl include the year?
Many thanks,
Just do the following:
ViewData["testMarkup"] = "I was here " + DateTime.Now.Year.ToString();
Or am I missing something? Code blocks, such as <%= DateTime.Now.Year %> are only valid when they are part of the markup:
<div>The year is <%= DateTime.Now.Year %></div>
The markup in the database is being treated as a string, not as code in your view language, so it is simply writing it out as text, c# and all.
Two alternate methods:
1 - Use a templating system, such as
ViewData["testMarkup"] = "I was here #YEAR#";
and have a method that replaces your tokens (e.g. #YEAR#) with their values at render time, e.g.,
<%= ReplaceTokens((string)ViewData["testMarkup"]) %>
Where ReplaceTokens looks like:
public static ReplaceTokens(string s)
{
return s.Replace("#YEAR#", DateTime.Now.Year)
}
2 - Store your markup in a partial view, and save the name of the partial view in the database if necessary.
I do believe Phil Haack has the answer to my issue. http://haacked.com/archive/2009/04/22/scripted-db-views.aspx
I will have to check this out and see what happens

Resources