Ruby hash syntax - ruby-on-rails

I'm new to ruby and trying to get used to the new syntax.
This is a line of code from the project i'm in, it's a simple description on the footer
that shows the local company number, but the syntax of the second line is a little confusing to me.
%dt Indonesia
%dd{ itemprop: 'telephone' }= I18n.with_locale(:id) { t('meta.phone_number') }
so {itemprop: 'telephone'} is just a block that maps a symbol itemprop to the value 'telephone', but then why do you have "=" in between the I18n.with_locale(:id)? what does it do?
Also, is the third block {t('meta.phone_number')} a parameter for the I18n.with_locale(:id)?
or is I18n.with_locale(:id) even a method call?
I would appreciate any help. Thank you

%dd: tell Haml to emit a <dd> tag.
{ itemprop: 'telephone' }: tell Haml that the current tag should have an attribute itemprop with value telephone.
=: tell Haml to set the text content of the current tag to whatever Ruby says the rest of the line evaluates to.
I18n.with_locale(:id) { ... }: tell Ruby to invoke the method with_locale on I18n, with one parameter (the symbol :id) and a block.
t('meta.phone_number'): tell Ruby to invoke the t helper method, with one parameter (string meta.phone_number).
All in all, it should generate something like this:
<dd itemprop="telephone">電話番号</dd>
if 電話番号 was a translation registered for meta.phone_number and the current locale was Japanese.

Related

Properly Escaping a String inside a View

I've read in multiple places that as of Rails 3 you no longer have to use html_escape "some string" to actually escape a string in a view and that simply writing <%= "some string" %> would escape the string by default. However, I cannot find this information in the docs. I read through the XSS in the Rails guides section that stated this:
https://guides.rubyonrails.org/security.html#cross-site-scripting-xss
As a second step, it is good practice to escape all output of the application, especially when re-displaying user input, which hasn't been input-filtered (as in the search form example earlier on). Use escapeHTML() (or its alias h()) method to replace the HTML input characters &, ", <, and > by their uninterpreted representations in HTML (&, ", <, and >).
Then I see several blogs that state that it is escaped by default. For example: https://www.netsparker.com/blog/web-security/preventing-xss-ruby-on-rails-web-applications/
https://dzone.com/articles/preventing-cross-site-scripting-vulnerabilities-wh
Found it:
https://guides.rubyonrails.org/3_0_release_notes.html
"7.4.3 Other Changes
You no longer need to call h(string) to escape HTML output, it is on by default in all view templates. If you want the unescaped string, call raw(string)."
escapeHTML() (or its alias h()) are from CGI::escapeHTML, which is a Ruby API implementation. If you aren't using Rails you still have a way to escape HTML. Rails may do some automagical handling of HTML in ERB files for display, and that is what you are probably referring to with html_escape "some string" and <%= "some string" %>. I think you are possibly confusing html_escape which you might need when displaying urls and such that are stored in the DB and you want the ERB processor to not mess it up? I know sometimes, particularly in .js.erb files I need to escape some things to get the result I was expecting. This is different than sanitizing. It seems in your example they are referring to something that you might accept and then redisplay, like a search string. If you put <i>hello</i> into a search box you would want to sanitize the input before passing it to the back end, or if you are using some javascript to filter you might want to escape it both for security reasons and to let it re-display correctly in the search box after you've filtered.
Edit: I was not able to find the answer to your comment in the ri doc either. But I tried:
<%= "<b>hello</b>" %>
<%= h("<b>hello</b>") %>
And got the same result in the browser:
<b>hello</b>
<b>hello</b>
So if you are asking if it is true, then I would say yes.

Ruby on rails: Id attribute of input elements generated by form helpers, with non english values

Some Rails form-helpers (for instance 'radio_button' helper), append the element's value to the generated id string.
But if the value is not in English - nothing gets appended to the id string. This may result in multiple elements (all with non English values) having the same id attribute.
What's the recommended way to tackle this problem ?
This is a very old post, but it's coming up first in Google so I thought I'd spare some other rails developers a bit of misery by giving a code example of how to get this to work.
<%= radio_button_tag "name", "value", false, :class => "test-class", :id => "radio-id" %>
I just spent 20 mins trying to figure out how to do it and realised I was missing the 3rd parameter (checked). Aaargh!
Rails documentation here: https://apidock.com/rails/ActionView/Helpers/FormTagHelper/radio_button_tag
You can pass your own custom id in the options hash
http://apidock.com/rails/ActionView/Helpers/FormHelper/radio_button

Haml::SyntaxError: Invalid attribute list

I am trying to interpolate a ruby variable in a HAML%img src tag, with the ruby interpolation operator #{}. In the following way:
-#locations.each do |location|
%li
%img(src: "#{location.thumbnail_url}")
However, I get the following error:
Invalid attribute list: "(src: \"\#{location.thumbnail_url}\")".
Is there a valid way to do this? I am sure it has been done before but can't see any literature/any other posts about it.
It looks like you’re mixing the two attribute styles, the normal style and the HTML style.
You want to either replace () with {} and use the normal style:
%img{src: "#{location.thumbnail_url}"}
or use the HTML style with = instead of :, like this:
%img(src = "#{location.thumbnail_url}")

Have trouble implement the variable loop in haml file

I use ruby on rails to get some variables and suppose to send them in email format to some email address.
%div
- #msg.each do |line|
%p = "#{line}"
%br
The msg is the string array I passed in and would like to get each element in separate line. How can I achieve that. The above code won't work.
One of the key things of coding HAML is you really are only going to have one item per line, plus you automatically get a div tag as the default tag. So you might as well add a class to your div to differentiate it. Additionally, make sure your indentation is correct:
.messages
- #msg.each do |line|
%p= line
You don't really need a br because the p will break for you, and following a tag with '=' will automatically give you the interpolation.

How do I use HAML in a dynamic link?

I am trying to create a link using HAML which looks like the this
=link_to("Last updated on<%=#last_data.date_from.month %>",'/member/abc/def?month={Time.now.month}&range=xyz&year={Time.now.year}')
It is not taking the Ruby code and it is displaying that as a string
Last updated on<%=#last_data.date_from.month %>
and in the URL as well it is not taking the function Time.now.month or Time.now.year .
How do I pass Ruby code in URL and in the string ?
You should probably use something like this:
= link_to("Last updated on #{#last_data.date_from.month}", "/member/abc/def?month=#{Time.now.month}&range=xyz&year=#{Time.now.year}")
Note that in the second string, it's necessary to change the ' to ". Also if the link text is getting long, you can use something like this:
= link_to("/member/abc/def?month=#{Time.now.month}&range=xyz&year=#{Time.now.year}") do
Last updated on #{#last_data.date_from.month}
Everything after the = in HAML is a Ruby expression. Ruby doesn't interpolate strings the way HAML does, it has own way of such interpolation.
In Ruby, when you want to have string value of some variable inside another string, you could do.
"Some string #{Time.now}"
So, it should be:
= link_to "Last updated on #{#last_data.date_from.month}", "/member/abc/def?month=#{Time.now.month}&range=xyz&year=#{Time.now.year}"
A simple example with easy syntax:
link_to "Profile #{rubycode}", "profile_path(#profile)/#{ruby_code}", class: "active"

Resources