ERB String interpolation generating incorrect HTML syntax - ruby-on-rails

I have these lines in a view:
<%
if current_user.is_fav?(a)
cls = "product fav"
else
cls = "product"
end
%>
and later
<div class=<%= cls %> >
This produces:
<div class="product" fav>
EDIT: as the answer says, it did NOT produce this, it was the browser "inspect" that showed it to me.
I can work my around it, but why doesn't the above code work?

This produces:
<div class="product" fav>
No, it doesn't. It produces <div class=product fav>. What you see (via something like "inspect element", correct?) is browser trying to interpret your broken markup as close to html spec as it can.
As noted in other answers, what you should do instead is something like this:
<div class="<%= cls %>">

<div class=<%= cls %> >
should probably be
<div class="<%= cls %>">
You're substituting a string into an erb placeholder, but the underlying template does not indicate that the placeholder itself is a string. ERB is likely making a best effort attempt to do a correction but it's oviously not able to cope. Edit: Sergio pointed out this is likely the browser doing this, not ERB.

Related

th:with what is the difference between the two examples

<p th:with="firstName1='James1'">
<p>Upper</p><p th:text="${firstName1}"></p>
</p>
<p th:with="df='today'">
Today is: <span th:text="${df}">13 February 2011</span>
Could you tell me what is the difference between the two code sections. They seem identical for me. But there is some difference as the results differ.
Alright, I've never encountered this before... but it looks like Thymeleaf is enforcing the rule that Any <p> (or other block-level element) will implicitly close any open <p>. This works, for example:
<div th:with="firstName1='James1'">
<p>Upper</p>
<p th:text="${firstName1}"></p>
</div>
<p th:with="df='today'">
Today is: <span th:text="${df}">13 February 2011</span>
</p>
In your example, the firstName1 variable is out of scope because the parser is treating your HTML like this (so firstName1 is considered null):
<p th:with="firstName1='James1'"></p>
<p>Upper</p>
<p th:text="${firstName1}"></p>

Trying to understand Rails ajax js code

Ive been trying to work out how to prepend a comment once its been created via Ajax, I added remote true to the form. Inserted the block in the controller but then it got the js file where i prepended the new comment. I couldn't figure it out. I came across this code on SO and quickly gave it a shot and it worked. But i cant work out why/how?
This is the code: JS file,
$("<%= escape_javascript(render #message) %>").prependTo(".view-messages");
Here is the div to which it is prepended
<div class="view-messages">
<%= nested_messages #messages.arrange(:order => :created_at) %>
</div>
Its this line here $("<%= escape_javascript(render #message) %>") Ive tried debugging it but cant,
What is that printing out, is it one of these rails magic things or am i being stupid?
Although it works i like to know why and how so if anyone can help me out me id be grateful.
Thanks
EDIT:
$("<div class=\"body body-144\">\n <span class=\"tip tip-left\"><\/span>\n <div class=\"message font-medium\">\n ellll <br />\n <\/div>\n <div class=\"flerowspb\">\n <span class=\"font-small\">\n <a href=\"/profiles/122\">Nyall2911(28)<\/a>\n <\/span>\n <span class=\"font-small\">\n <a href=\"/messages/new?entry_id=344&parent_id=144\">Reply<\/a>\n <a rel=\"nofollow\" data-method=\"delete\" href=\"/messages/144\">| Delete<\/a>\n <\/span>\n <\/div>\n<\/div>\n")
This is what its rendering, So i suppose my question is, how is rails getting all of the HTML from my comment partial by just calling (render #message)
Here's the escape_javascript method: https://github.com/rails/rails/blob/55f9b8129a50206513264824abb44088230793c2/actionview/lib/action_view/helpers/javascript_helper.rb#L25
Per the comment below the method, it looks like it replaces a few unsafe characters and returns raw HTML using the html_safe method. jQuery then prepends that raw HTML to your div.

HAML tags closing unexpectedly

I have a haml file with the following:
#test-zone
%p.test-class
%p
= "The test works!"
I am expecting the following output:
<div id='test-zone'>
<p class='test-class'>
<p>The test works!</p>
</p>
</div>
BUT what I'm seeing is this:
<div id='test-zone'>
<p class='test-class'></p>
<p>The test works!</p>
<p></p>
</div>
I'm very confused why the tags are closing themselves. I also don't know what's up with that extra tag. I do not have too much experience with haml and I have not been able to search out a solution to this problem. Any other information you need from me I am happy to provide.
Haml itself is producing the output you are expecting:
<div id='test-zone'>
<p class='test-class'>
<p>
The test works!
</p>
</p>
</div>
However this is invalid HTML, a <p> is not allowed inside another <p>. You are probably looking at the inspector window of your browser which shows the “corrected” markup. If you view the source directly you will see the expected (invalid) code.
The fix is simply to make sure you use valid HTML, perhaps make the test-class paragraph a div instead.

Objective c xpath query not working

I'm trying to get the content out of
<p>
<strong>Some headline</strong>
Some text here ...
</p>
I want to store the "some text here ..." in a NSString.
My XPath query looks like this
#"//div[#class='articleInfo']/div[#class='readMore description']/div[#class='readMoreContent']/p"
but that is returning null.
Please help!
if you have something like this:
<div class="articleInfo">
<div class="readMore description">
<div class="readMoreContent">
<p>
<strong>Some headline</strong>
Some text here ...
</p>
</div>
</div>
</div>
then yours xpath should work:
//div[#class='articleInfo']/div[#class='readMore description']/div[#class='readMoreContent']/p/text()
Also as #San said, can be typo. I see you have space here "readMore description", but not here "readMoreContent"

MVC, make conditional output in simplest way

hi
i have a variable called isEnglish
if it is true I want to output something like this:
<div orientation="left"> </div>
otherwise:
<div orientation="right"> </div>
the following code failed to compile :
<div orientation="<%=isEnglish?? %>left<%:%>right<% %>"> </div>
I know a way which is long, by using the (if) and Writer.Write method
is there another simple way ?
<div orientation="<%= isEnglish? "left" : "right" %>"> </div>
You could use a conditional statement:
<div orientation="<%= isEnglish ? "left" : "right" %>"></div>
Or, preferably (to me at least), you would remove this logic from the View altogether and create a ViewModel. You can then put the logic in the mapping between the Model and the ViewModel.
That way you don't have spaghetti code in your View. It might look something like:
<div orientation="<%= Model.Orientation %>"></div>
The code you want is this:
<div class="<%= isEnglish ? "left" : "right" %>"></div>
But check out Razor if you're using MVC, much cleaner syntax.

Resources