Rails: How to escape ampersand in URL formation - ruby-on-rails

I have a link_to helper like the following:
<%= link_to "example & text", url_for(:controller =>'example', :title=>"example & text") %>
It frames the URL http://localhost:3000/example?title=example&amp:text
In the sample controller it calls the index method but params[:title] returns
the value example&amp:text.
I want to have a value like "example & text". So I have tried
CGI::escape() and CGI::escapeHTML() but without luck.

The url needs to be escaped using CGI.escape:
link_to "example & text", :controller => "example", :title => CGI.escape("example & text")
This should generate something like:
example & text
Then, wherever you're wanting to use this, you can unescape it again to get it back to normal:
CGI.unescape params[:title] # => "example & text"

For this there is a nice rails method called raw.
You can use in this way :
<%= link_to raw("example & text"), url_for(:controller =>'example', :title=>raw("example & text")) %>
One more this & should not be used in the URL as it is used as params separator.

Related

Ruby - link_to - How to add data directly from DB

First of all, I am very new to ruby and I am trying to maintain an application already running in production.
I have been so far able to "interpret" the code well, but there is one thing I am stuck at.
I have a haml.html file where I am trying to display links from DB.
Imagine a DB structure like below
link_name - Home
URL - /home.html
class - clear
id - homeId
I display a link on the page as below
< a href="/home.html" class="clear" id="home" > Home </a>
To do this I use 'link_to' where I am adding code as follows
-link_to model.link_name , model.url, {:class => model.class ...... }
Now I have a new requirement where we have a free text in DB, something like -
data-help="home-help" data-redirect="home-redirect" which needs to come into the options.
So code in haml needs to directly display content versus assign it to a variable to display.
In other words I am able to do
attr= '"data-help="home-help" data-redirect="home-redirect"' inside the <a>, but not able to do
data-help="home-help" data-redirect="home-redirect" in <a> tag.
Any help would be greatly appreciated!
link_to accepts a hash :data => { :foo => "bar" } of key/val pairs that it will build into data- attributes on the anchor tag. The above will create an attr as follows data-foo="bar"
So you could write a method on the model to grab self.data_fields (or whatever it's called) and split it into attr pairs and then create a hash from that. Then you can just pass the hash directly to the :data param in link_to by :data => model.custom_data_fields_hash
This somewhat verbose method splits things out and returns a hash that'd contain: {"help"=>"home-help", "redirect"=>"home-redirect"}
def custom_data_fields_hash
# this would be replaced by self.your_models_attr
data_fields = 'data-help="home-help" data-redirect="home-redirect"'
# split the full string by spaces into attr pairs
field_pairs = data_fields.split " "
results = {}
field_pairs.each do |field_pair|
# split the attr and value by the =
data_attr, data_value = field_pair.split "="
# remove the 'data-' substring because the link_to will add that in automatically for :data fields
data_attr.gsub! "data-", ""
# Strip the quotes, the helper will add those
data_value.gsub! '"', ""
# add the processed pair to the results
results[data_attr] = data_value
end
results
end
Running this in a Rails console gives:
2.1.2 :065 > helper.link_to "Some Link", "http://foo.com/", :data => custom_data_fields_hash
=> "<a data-help=\"home-help\" data-redirect=\"home-redirect\" href=\"http://foo.com/\">Some Link</a>"
Alternatively you could make it a helper and just pass in the model.data_attr instead
link_to "Some Link", "http://foo.com/", :data => custom_data_fields_hash(model.data_fields_attr)
Not sure you can directly embed an attribute string. You could try to decode the string in order to pass it to link_to:
- link_to model.link_name, model.url,
{
:class => model.class
}.merge(Hash[
str.scan(/([\w-]+)="([^"]*)"/)
])
)

image_tag syntax with or without "" - with method - ruby

To "" or not to "" - that is the question.
<%= image_tag(#profile.image, :size => "80x80", :alt => "Picture") %>
or
<%= image_tag("#profile.image", :size => "80x80", :alt => "Picture") %>
Ask yourself this questions: Do you ever quote variable's in any programming language? Probably not. Some languages handle variables inside of double quotes so that you can write a string like this: "My name is <variable>". The other way to do it is "My name is "+<variable>
So basically no you do not want to quote "#profile.image".
Using "#profile.image" will put the src attribute equal to #profile.image, NOT the value of #profile.image.
Don't use the quotes, unless your image is called "#profile.image".
If the image's filename is #profile.image, then use quotes. If #profile.image contains the name of the image file, don't.

Rails - Render partial inside Twitter Bootstrap popover

I want to use a Twitter Bootstrap popover to display a user avatar and email address, with the possibility of adding in more details at a later date.
I am having an issue getting the partial to render inside the content field of the link. The view code is below (in HAML).
%span.comment-username
=link_to comment.user_name, "#", "title" => comment.user_name,
"data-content" => "=render 'users/name_popover'",
class: "comment-user-name"
Currently, this will only produce the content code as a string.
Is there a way to do this so the partial will be inserted instead of the code as a string?
You want rails to actually evaluate the content of the string and not just show the string. The easiest way to do that would be:
%span.comment-username
=link_to comment.user_name, "#", "title" => comment.user_name,
"data-content" => "#{render 'users/name_popover'}",
class: "comment-user-name"
That should pass the render statement to rails and render your partial as expected.
Thanks for the answer jrc - it helped me find a solution.
My solution might be useful for other non HAML people like me:
`<%= link_to('Service History' , '#', :class => "popover-history", :rel => "popover", :"data-placement" => "bottom", :title => "Service History", :"data-content" => "#{render 'services/service_history'}") %>`
with
`$(function () {
$('.popover-history').popover({ html : true });
});`

How to apply a link to a multiline text string in HAML?

I have a multiline chunk such as this:
%li
=link_to image_tag("image.jpg", :size => "48x48", :alt => "Something", :title => "Something", :class => "some-class"), some_path
%p.testi
"Some text right here that is divided up onto multiple lines &
%br
and just won't stop running on!”
I need a link to surround both the image and the text. Presently the image link works fine, however on the text link, I believe I have to start with a link_to block, but I'm not seeing the syntax that I should follow there.
How is this correctly done so that all of the multiple lines of text also have a link applied?
In slim (wich should be similar):
= link_to some_path, class: "some-class" do
h2 = "#{some_object.title}"
p.testi
"Some text right here that is divided up onto multiple lines &
br/
and just won't stop running on!”
See Multiline string in HAML
You want to use the | at the end of each line you are wrapping.

Using hyphen in link_to property?

In my Rails app, I need to set a value for a custom data-* attribute on an anchor tag. However, hashes can't have hyphens if I'm not mistaken. I essentially want to do this:
<%= link_to 'Example', example_path, :class => 'something', :data-id => '15' %>
:data-id is not valid, however. What can I do to work around this?
IIRC, for such purposes hashes and strings are equivalent, so you can use "data-id" instead of :data-id. Never checked for this particular method, though, so no guarantees.
I think in Rails 3 you can do
link_to "Click Here", root_path, :data => { :id => #model.id }
for all data attributes.

Resources