I am trying to work out the best way to replace multiple variables/placeholders within localized message string in my ruby on rails application. When replacing a single placeholder I have used the satisfactory:
In en.yml:
url_borked: "The URL: $url could not be loaded."
In view:
t(:url_borked)["$url"] = request.url
But this is not suitable for multiple placeholders. It looks ugly, and it doesn't actually work e.g:
In en.yml:
url_borked: "The URL: $url is badly formatted, perhaps you meant: $url_clean"
In view:
(t(:url_borked)["$url"] = request.url)["url_clean") = #suggested_url
I have tried using String::sub, but am not happy with that as it ugly. e.g.:
(t(:url_borked).sub("$url", request.url).sub("url_clean", #suggested_url)
It also doesn't work if you want to replace multiple instances of the one placeholder. e.g.:
bad_url: "$url cannot be loaded, please try $url another time"
I have also considered the printf function, but that does not work for localisation as the relative position of the placeholder can change depending on the translation.
Is there correct way to do this message placeholder substitution?
Thanks.
Why not:
t(:url_borked, :url=>request.url, :url_clean=>#suggested_url)
?
Ok, I had a brainwave and looked at the I18n::translate function a bit more closely and found the "interpolation" functionality within.
e.g.
I18n.t :foo, :bar => 'baz' # => 'foo baz'
Exactly what I needed. Funny that I would work it out after I finally decided to ask the crowd for a solution :-)
Cheers.
Related
In my view I'm displaying the link in a such way:
<%= #casino.play_now_link %>
So, #casino.play_now_link can be like this: https://www.spinstation.com/?page=blockedcountry&content=1 What I need, is to display only this part: www.spinstation.com. I tried gsub('http://', '').gsub('https://', ''), and it works, but how can I remove the part of url name after .com? Thanks in advance.
Don't use regexes at all for this sort of thing, use URI from the standard library:
URI.parse(#casino.play_now_link).hostname
or, for a more robust solution, use Addressable:
Addressable::URI.parse(#casino.play_now_link).hostname
Of course, this assumes that you've properly validated that your play_now_links are valid URIs. If you haven't then you can add validations that use URI or Addressable to do so and either clean up existing play_now_links that aren't valid URIs or wrap the parsing and hostname extraction in a method (which is a good idea anyway) with some error handling.
In a simple way one can use
.split('/')[2]
which is regex based and depends on the '/' in your url.
But as #mu is too short mentioned: URI is better for this.
I'm trying to create a dynamic url pattern for the following url:
http://domain.com/content/pagetitle
This is what I have added in the url.rules:
'content/<page:.*?>' => 'cms/default/home',
this works fine for /content/pagetitle.html but not for /content/pagetitle while my url suffix is empty. Does anyone know what I'm doing wrong?
Your problem might also be that the regex "any character" character . gets escape if outside of a named group.
<controller:[a-zA-Z]>/(.*)
turns into
<controller:[a-zA-Z]>/(\.*)
// ^ It escaped it for us even though we didn't want it
The solution is simply to make group for it:
<controller:[a-zA-Z]>/<wildcard:.*>
Not sure why you are adding the .*? there...
The following example should work
'content/<page:.+>' => 'cms/default/home',
You do not need a wildcard in this case:
'content/<page>' => 'cms/default/home',
I'm trying to store regexes in a database but they're not working when used in a .sub(), even though the same regex works when used directly in .sub() as a string.
regex = Class.object.field // Class.object is an active record containing "\w*\s\/\s"
mystring = "first / second"
mystring.sub(/#{regex}/, '')
// => nil
mystring.sub(/\w*\s\/\s/, '')
// => second
Any insight appreciated!
Thanks,
Matt.
Editing to correct class/object terminology (thanks) & correcting my 2nd example as I had shown #{} wrapped around the working regex (cut & paste SNAFU).
To answer your question: It is not quite what kind of thing your Class.object is. If it's an ActiveRecord, it won't work.
Edit: You obviously found that the problem is Rails escaping the regexp.
An ActiveRecord cannot "contain" your regular expression directly; the regexp will be in one of the fields of your record. In which case you'd want to do something like regexp = Class.object.field_containing_the_regexp.
Even if that is not the case, I suspect that the problem is that your regexp is something other than a string. You can quickly test this by using
puts "My regexp: #{regexp}"
The string that you will see in the output will be the one that is used for the regexp.
A String is not a Regexp. You have to create a Regexp object first.
regex = Regexp.new("\w*\s\/\s")
Turns out my regexp didn't cater for all cases - \w didn't account for symbols. After checking in rails console, and seeing the screwey escaping I was alreasdy half-way down the wrong track.
Thanks for the help.
I am somewhat of a Rails newbie so bear with me, I have most of the application figured out except for this one part.
def linkup_mentions_and_hashtags(text)
text.gsub!(/#([\w]+)(\W)?/, '#\1\2')
text.gsub!(/#([\w]+)(\W)?/, '#\1\2')
text
end
I found this example here: http://github.com/jnunemaker/twitter-app
The link to the helper method: http://github.com/jnunemaker/twitter-app/blob/master/app/helpers/statuses_helper.rb
Perhaps you could use Regular Expressions to look for "#..." and then replace the matches with the corresponding link?
You could use a regular expression to search for #sometext{whitespace_or_endofstring}
You can use regular expressions, i don't know ruby but the code should be almost exactly as my example:
Regex.Replace("this is an example #AlbertEin",
"(?<type>[##])(?<nick>\\w{1,}[^ ])",
"${type}${nick}");
This example would return
this is an example <a href="http://twitter.com/AlbertEin>#AlbertEin</a>
If you run it on .NET
The regex (?<type>[##])(?<nick>\\w{1,}[^ ]) means, capture and name it TYPE the text that starts with # or #, and then capture and name it NAME the text that follows that contains at least one text character until you fin a white space.
Perhaps you can use a regular expression to parse out the words starting with #, then update the string at that location with the proper link.
This regular expression will give you words starting with # symbols, but you might have to tweak it:
\#[\S]+\
You would use a regular expression to search for #username and then turn that to the corresponding link.
I use the following for the # in PHP:
$ret = preg_replace("#(^|[\n ])#([^ \"\t\n\r<]*)#ise",
"'\\1<a href=\"http://www.twitter.com/\\2\" >#\\2</a>'",
$ret);
I've also been working on this, I'm not sure that it's 100% perfect, but it seems to work:
def auto_link_twitter(txt, options = {:target => "_blank"})
txt.scan(/(^|\W|\s+)(#|#)(\w{1,25})/).each do |match|
if match[1] == "#"
txt.gsub!(/##{match.last}/, link_to("##{match.last}", "http://twitter.com/search/?q=##{match.last}", options))
elsif match[1] == "#"
txt.gsub!(/##{match.last}/, link_to("##{match.last}", "http://twitter.com/#{match.last}", options))
end
end
txt
end
I pieced it together with some google searching and some reading up on String.scan in the api docs.
I would like to develop URL's which look like the following:
http://mysite.com/products/1/best-product-in-the-world
Where all i need to get to the proper record is the following route:
http://mysite.com/products/1
When I add the product description piece to the URL ("best-product-in-the-world") I get URL encoding issues. I've tried to use Server.UrlEncode when constructing this portion of my URL in an ActionLink(...):
<%= Html.ActionLink(item.Subject, "../Post/Detail",
new { id = item.ID,
descriptiveUrl = Server.UrlEncode(Product.ShortDescription) },
new { rel = "canonical",
title = Product.ShortDescription,
#class = "product-hyperlink" })%>
But this renders regularly encoded elements for special characters and spaces, much like the following:
http://localhost:2392/Products/Detail/1/best+product+in+the+world253f
...which creates a 400, bad request exception. Not sure I've done the question justice, but can provide further clarification if need be.
Update: this post's URL is as follows, and i'm trying to do something very similar!
http://stackoverflow.com/questions/1148955/creating-search-engine-friendly-urls-in-asp-net-mvc
In a deeper Google search, I found the following link for generating slugs:
http://www.intrepidstudios.com/blog/2009/2/10/function-to-generate-a-url-friendly-string.aspx
Thanks #Rob and #Coding the Wheel for giving me the terminology I really needed to find this answer!
A simple option would be to add a property to your model object with an accessor that normalises the appropriate field (short description in this case) down to a suitable "slug"; that is, the bit of junk text after the identifier. You then use this when constructing the URI.
The normalisation process might be as simple as removing any non-alphanumeric characters and replacing spaces with hyphens.
The standard practice here is to store a 'slug' with each post that will function as the post's outward-facing URL. For example, your slug for the above post would be:
best-product-in-the-world
A decent CMS will do this for you automatically, and allow you to tweak the slug before saving.