Capitalization API - ruby-on-rails

Is there any good API or service that handles capitalization well? It should be able to handle input like "i need help fixing my iphone asap" with a desired output of "I Need Help Fixing My iPhone ASAP".
Edit: This is in conjunction with titleize. Titleize doesn't handle words like "iPhone" and acronyms. I'm currently getting user input like "ceo" and titleize returns "Ceo", when I'd like "CEO". I'd prefer not to write a list of special capitalizations, especially if there is a good alternative.
Another alternative would be a library of words and the correct capitalization.

Have a look at #titleize in ActiveSupport::Inflector

"man from the boondocks".titleize # => "Man From The Boondocks"
"x-men: the last stand".titleize # => "X Men: The Last Stand"
"TheManWithoutAPast".titleize # => "The Man Without A Past"
"raiders_of_the_lost_ark".titleize # => "Raiders Of The Lost Ark"
Cut and paste from http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-titleize

Related

Rails: i18n parameters that are also translated

I'm having difficulty finding the answer for my question, but it may just be that I have no idea how to phrase it. In svenfuchs's yml files in his rails-i18n repo, he has this listed under error:
format: #{attribute}#{message}
and below that he specifies possible error messages. It's really nifty, as it automatically translated error messages for me.
I'd like to use this format to translate headers and buttons. In Japanese, we'd say "FAQ Create" while in English we'd say "Create FAQ", so I can't just print out those translations and I'd like to not have to make each button's translation myself (a.k.a. create_faq: FAQを作る).
So far I've got in my view: t('button.format'), :attribute => "faq", :message => "create"
ja.yml:
model:
faq: FAQ
button:
format: #{attribute}#{message}
messages:
create: を作る
But that just prints out faqcreate for Japanese. What I'm trying to do is access the translations of model.faq and button.messages.create to pass as the parameters. Anybody know how?
p.s. messages: was also plural in the working errors message.
I'm sorry, I'm so stupid, I keep answering my questions right after I finally decided to ask for help;;; for anybody interested, just pass in another t(' '), so:
t('button.format', :attribute t('model.faq'), :message t('button.messages.create'))

How to automatically link to objects in text submission in Rails

So, you're in Github filing an issue and you refer to issue #31. Then, while writing this issue, you note that #johnmetta has suggested some possible solutions that he's working on. Then you hit "Submit New Issue" and when you do, "#31" and "#johnmetta" are links, and #johnmetta has been notified, and issue #31 has a notification that it has been referenced.
I realize that there are more than one technologies at work here (Javascript goodies, etc), but what I'm looking for are some examples of how to do this type of thing in the Rails world. It's an interestingly difficult subject to search for.
What I've come up with conceptually is:
Have some identifier, such as # or # that is reserved
Upon submission, search for that identifier in the appropriate attribute
Upon finding it, search for the appropriate model with a field matching what follows
Once finding that, replace that text string with a link
Optionally, do whatever necessary to notify the referenced object
That said, it seems like it's super simple (explicitly coded, assumes friendly_id).
def prettify_user_links(str, source):
result = str
str.scan(/(#\S+)+/).each do |mtch|
# Strip off whatever identifier we're using
search_string = mtch[0].gsub('#','')
# Search for the matching model in the appropriate table
user = User.find(search_string)
if user
# If we find a matching model, create some link text and link it
link_txt = "<a href=>'#{user.url}'>#{mtch}</a>"
result.gsub!(search_string, link_txt)
# Notification. Not sure how/where, maybe with a message bus, or something more brute-force like
Comment.create :user_id => user.id, :body => "You have been mentioned in #{link_to comment.excerpt, comment} by #{link_to comment.owner, owner}"
return result
That would be my first cut, but I feel there have to be much more elegant solutions.
An additional aspect to this question: How would you grab a snippit of surrounding text. The brute force way would be to search n words before and m words after that string and grab all of that, then grab that sub-string from the results and do the search. Still, seems like there'd be a more elegant solution.
What you've described is the basic way; anything else is not terribly more elegant. It's helpful to see it as two parts: one is on receipt of the comment (when you should do notifications) and the other is on display of the comment, when you should do linkification.
This allows you to keep the original comment in its original form, which is helpful.
Perhaps put an after_create (so notifications aren't sent on every edit) on the comment model (assuming a comment model that includes a 'body' field):
[edit: added contextual info]
after_create :notify_mentions
def notify_mentions
body.scan %r{(.{0,40})#(\w+)(.{0,20})} do |match|
username = match[1]
context = [match.first, match.last]
Notification.send(match, context, self) if User.exists?(:login => username)
end
end
I use \w+ in place of \S+ because people often say things like:
Hey #JohnMetta, how are you doing?
and \S+ will capture the , which might be wrong. Pulling the # out of the capture group lets me ignore it during notification.
The context in the above match groups consists of the 40 characters before and 20 characters after the matched username for your snippet. Adjust to taste.
Then when displaying the message, you essentially create a helper something like what you had:
def linkify(body)
body.gsub %r{#\w+} do |match|
link_to match, :controller => :users, :action => :show, :id => match
end
end
#gsub is awesome like that, in that it takes a block and replaces with the contents.
It's not a lot more elegant than what you had, but it should give a pretty decent result.

Which characters in a search query does Google ignore (versus treating them as spaces?)

I want to give my pages human-readable slugs, but Rails' built-in parameterize method isn't SEO-optimized. For example, if I have a post called "Notorious B.I.G. is the best", parameterize will give me this path:
/posts/notorious-b-i-g-is-the-best
which is suboptimal since Google construes the query "Notorious B.I.G." as "Notorious BIG" instead of "Notorious B I G" (i.e., the dots are removed rather than treated as spaces)
Likewise, "Tom's fave pizza" is converted to "tom-s-fave-pizza", when it should be "toms-fave-pizza" (since Google ignores apostrophe's as well)
To create a better parameterize, I need to know which characters Google removes from queries (so I can remove them from my URLs) and which characters Google treats as spaces (so I can convert them to dashes in my URLs).
Better still, does such a parameterize method exist?
(Besides stringex, which I think tries to be too clever. 2 representative problem cases:
[Dev]> "Notorious B.I.G. is the best".to_url
=> "notorious-b-dot-i-g-is-the-best"
[Dev]> "No, Curren$y is the best".to_url
=> "no-curren$y-is-the-best"
I would try using a gem that has been designed for generating slugs. They often make good design decisions and they have a way of updating the code for changing best practices. This document represents Google's best practices on URL design.
Here is a list of the best gems for solving this problem. They are sorted by rank which is computed based on development activity and how many people "watch" changes to the gems source code.
The top one right now is frendly_id and it looks like it will generate good slugs for your use in SEO. Here is a link to the features of the gem. You can also configure it and it looks like it is perfect for your needs.
Google appears to have good results for both the "b-i-g" and "big" in the url slugs.
For the rails side of things, yes a parameterize method exists.
"Notorious B.I.G. is the best".parameterize
=> "notorious-b-i-g-is-the-best"
I think you can create the URLs yourself... something like
class Album
before_create :set_permalink
def set_permalink
self.permalink = name.parameterize
end
def to_params
"#{id}-#{permalink}"
end
end
This will create a url structure of:
/albums/3453-notorious-b-i-g-is-the-best
You can remove the id section in to_params if you want to.
Use the title tag and description meta tag to tell google what the page is called: these carry more weight than the url. So, leave your url as /posts/notorious-b-i-g-is-the-best but put "Notorious B.I.G. is the best" in your title tag.

convert HASH into ARRAY

After saving some values into the database, I am
finding it difficult to print them out. Though I have been able to
pull the data out of the database, the output is like the following:
#vars={:object=>"46789620999001", :source_id=>1, :comment=>"["This is
my first commenttoday and tommorrow", "This is my first commenttoday
and tommorrow", "This is my first commenttoday and tommorrow", "This
is my first commenttoday and tommorrow", "This is my first comment",
"This is my first comment", "its nice!!!", "Many people do not take
this serious. In this life we have a big role to play in making
ourselves what we would be. It is only God that can help us to live
that life which we have planned, so we can only pray to Him who is the
all and all in our life to help
us."]", :title=>"", :content=>"<div>Life is beautiful. In this life,
whatever you see is what you will use to make out your way. People
around you can help you in many things and ways but can never live
your life for you. It is left for you to live your life, make and take
decisions that you think will help you in living out your dream life.
I believe everybody has a dream life he would like to live. Whatever
decisions one take today will go a long way in determining the kind of
life the one will live in future.<br />Take this as an advise.Bye </
div><div class="blogger-post-footer"><img width='1' height='1'
src='https://blogger.googleusercontent.com/tracker/
6876835757625487750-2447909010390406819?l=godwinagada.blogspot.com'
alt='' /></div>", :author=>"["Godwin",
"ken"]", :category=>"Reality", :post_id=>"", :date=>"2010-06-04", :FileName=>"first"}
>]
please can someone help out in referring to each of the data in this
output eg.
#output.each { |g|
puts g.FileName
puts g.post_id
}
etc
Don't you want:
#vars[:FileName]
#vars[:post_id]
You have a hash, which contains a set of keys with each key pointing to a value. There are several ways you can deal with them:
If you want to just view it to debug it. Load pretty print (require 'pp') and pretty print it (pp #vars). An even better choice is the Awesome Print gem.
If you output the value of each pair, just iterate with each passing a block for your action:
#vars.each do |key, value|
puts "#{key} => #{value}
end
Try pp, from the standard library.
require 'pp'
pp #vars
There is another alternative called awesome_print, you can dl the gem from http://rubygems.org/gems/awesome_print that would look like this
require 'rubygems'
require 'ap'
ap #vars
Either of these should print the hash in a format that is easier to read.

Shortest way of determining a name ends with an `s`, `x` or `z`, and then use the `I18n.t` method with it

I'm creating a Rails application where users can have a first and last name. Since I'm a perfectionist, the application may not show something like Dennis's profile or Xianx's profile, but rather Dennis' profile and Xianx' profile. I use I18n, so I wanted to ask what is the shortest way of implementing this? This grammar is the same for both English and Dutch, where the application will be translated to.
Oh, some important things:
I am not afraid of using helpers and the application controller
My language files are in Ruby, not YAML
Thanks!
It's hard to be perfect in Dutch
def having_s( word ) # maybe genitiv_s is a better name
case word[-1,1] # [-1] will do in ruby 1.9
when 's', 'x', 'z'
"#{word}'"
else
"#{word}'s"
end
end
names=%w(Alex Inez Kees Maria Bordeaux)
names.each{|name| puts having_s(name)}
The last testcase ("Bordeaux") yields a wrong result, according to this.
One way to implement this with little risk of not being correct:
Instead of:
Person X's profile
Do:
Profile: Person X
There's not going to be a way to do the first for all languages/countries/cultures. The 2nd option may not look ideal, but you won't ever present anything incorrectly.

Resources