Localized country select plugin for Rails 28|10|2008 17 comments Comments for article feed

The `country_select` helper was recently kicked out from Rails core. Here's a replacement taking into account new Rails' internationalization framework and coming with Rake task for downloading country names for Unicode.org CLDR's 141 languages.

As you may know the country_select helper, giving you a dropdown menu with country names, was recently kicked out from Rails core into a "country select" plugin.

This was inevitable in a way, because the helper was storing country names in the database, making any localization or calculations kinda discursive. Neverthless, the primary reson for deprecation was a political debate, whether „Taiwan, Province of China“ is a String everybody is happy having in Rails codebase. (Read Michael Koziarski's recap if you're interested in political aspects of developing open-source software.)

On a current project, I needed a way to:

  1. store country codes, not names in the database,
  2. localize said codes in application's interface,

and developed a localized country_select Rails plugin, with source available at Github. It may solve your problem, if you have similar needs.

You can use it for rendering the <select> menu just as the original helper:

<%= localized_country_select(:user, :country) %>

When you need to translate the stored value in your application, you can do that just like this:

<%= I18n.t @user.country, :scope => 'countries' %>

The plugin code is based on Rails "country_select" plugin. Thanks to the Ruby/Rails i18n project the localization code was so simple, it almost hurts:

module LocalizedCountrySelect
  class << self
    def localized_countries_array
      I18n.translate(:countries).map { |key, value| [value, key.to_s.upcase] }.sort
    end
    def priority_countries_array(country_codes=[])
      countries = I18n.translate(:countries)
      country_codes.map { |code| [countries[code], code.to_s.upcase] }
    end
  end
end

The plugin code is quite well documented and has basic suite of unit tests.

If you still didn't checked Rails' new internationalization/localization capabilities, you should stop what you're doing and do that right now.

The plugin comes with two localization dictionaries: for English (en-US) and Czech (cz). But that's not all you have.

You can download and save country codes and names for more than one hundred languages, thanks to provided Rake task, which parses Unicode.org's vast Common Locale Data Repository (CLDR) archive. It doesn't download the XML sources from CLDR, because that would be kinda overkill, wouldn't it? It's deliberately very naive & procedural, so it's easy to follow what's going on.

However, if you're interested in this, keep tabs on the Ruby/Rails i18n team CLDR project at Github. Downloading, parsing and storing data from CLDR is definitely the future of Rails aplications' automatic/automagic localization: imagine not only be able get month names for most languages, but also parse complex pluralization rules for languages like Czech into Ruby lambdas... Now that I would call nice way how to work with localization.

Update I

I've added also complementary localized_country_select_tag method for a „named“ <select> menu with countries now. You can use the helper for "anonymous" or "inconsistent" data structures like "competition_submission[data][citizenship]" (like I have to do today). Looks like we are for another one, localized_nationality_select...

Update II

Beware with stuff in Rails' i18n moving very fast. Recently the default locale was changed from en-US to en. I am keeping the plugin updated.

# 1
Vaclav Vancura wrote on 28|10|2008:

First! Sitewide! :]

# 2
jan wrote on 30|10|2008:

"Marley is minimal blog engine without admin interface written in Sinatra framework"

Sounds punk enough for me to give it a try :-)

Thanks for the plugin btw! You can now have a badge here saying "As mentioned on the Rails Envy podcast" ;-) (http://railsenvy.com/2008/10/29/rails-envy-podcast-episode-053)

# 3
karmi wrote on 30|10|2008:

@jan: Thanks for the kind comment & thanks for the link to RailsEnvy podcast!, I didn't catch that :)

(Note: Apparently Akismet thinks just about every comment is spam here. Will try debug round #2, then kick it out and use Defensio or Typepad Antispam. I am curious if this comment ends up as a spam as well :)

# 4
christoph Sturm wrote on 30|10|2008:

Hey karmi! Congrats on your new blog! I like the design. Localized country select also looks very interesting, will read the source soon :)

best, chris

# 5
karmi wrote on 30|10|2008:

@christoph: Thanks! :) Nice to hear from after those months from Euruko :)

(Testing new anti-spam service from Six Apart [http://antispam.typepad.com/info/developers.html], because Akismet was marking everything as spam.)

# 6
Keff wrote on 31|10|2008:

Hi Karmi, I couldn't add your rss feed to Opera, so I made a feedburner feed: http://feeds.feedburner.com/RestafariorgByKarmi - for anyone else with a same problem.

# 7
karmi wrote on 31|10|2008:

@Keff: I'll be looking into that, please use http://feeds.feedburner.com/restafari if the feed is not working for you...

# 8
Fransky wrote on 27|05|2009:

I've been searching for an alternative to country_select and choose yours to give a try. Actually I'm a windows XP. Installed the plugin but having one error: undefined method localized_country_code_select&#39; for #&lt;ActionView::Base:0x49eb5ac&gt;

Can you give some help?

Thankyou!

# 9
Fransky wrote on 27|05|2009:

Ops, solved. Actually there is a diference between what is writen in this blog and the README.rdoc that comes with code. Just use what comes with code.

Thanks, anyway. Great plugin.

# 10
Karel Minarik wrote on 27|05|2009:

Opps, solved in the article as well. Sorry and thanks for the feedback!

--karmi

# 11
Alexander Ewering wrote on 31|05|2009:

Dude, don't people have better things to do than discuss about politically correct country names?

# 12
Anton Trapp wrote on 06|06|2009:

Hi! Great plugin, saves some work and works very well.

I have a suggestion: Is it possible to sort the countries correct (all umlauts are at the end of the list)?

A very simple solution that would work good enough for me could look like:

http://pragmatig.wordpress.com/2009/03/07/umlaut-aware-alphabetical-sorting/
# 13
Dave Brown wrote on 12|07|2009:

Hi - Just tried using the rake task for the ar Arabic locale. Problem was it was pulling down the <span> and other text as part of the country name.

After looking at your rake task code, I modified line 53 to use inner_text rather than inner_html and it worked correctly from then.

Rgds,

# 14
Karel Minařík wrote on 13|07|2009:

@Anton: Thanks for the tip, I'll have a look in the sorting, seems like sorting doesn't take into account the accented chars. This affects German locale?

@Dave: Thanks as well!, I remember there was some related issue with Japanese locale and will have a look into it.

--karmi

# 15
Aaron Vegh wrote on 28|09|2009:

Thanks very much for this code. It seems to work very well, but I can't get the prioritized country option to do what I need. I try:

<%= localized_country_select(:address, :country, ["US", "CA"], :include_blank => 'Please choose...') %>

And I get a select with only the values set, with empty labels. I've tried this every which way, but I'm getting no love. Your help would be appreciated!

# 16
Karel Minarik wrote on 30|09|2009:

Hi guys, thanks for the reports, all should be fixed now, though with delay...

@Anton: I have used the parameterize method natively in Rails for the sort_by, so the umlauts should be in the list, correctly, now.

@Dave: That was fixed in commit de2c5b559a669ecbff3c3c6a0bd2a24ffcc0db92, some time ago, it works with :ar locale for me?

@Aaron: That's because priority countries took symbols, not string. I have fixed it now so you can use symbol, string, lowercase, uppercase, whatever, and it gets converted correctly, see commits http://github.com/karmi/localized_country_select/commit/4bafeebc9eeb7af2f4cdc2db3e5bfca4811197fa and http://github.com/karmi/localized_country_select/commit/c96ea301df65b75df141a71d612df022dc4a7067

Best,

--karmi

# 17
Rasmus Bang Grouleff wrote on 28|12|2009:

Really nice plugin - I have an issue however with setting a default selected country in localized_country_select. I'm using the form builder method - and I've tried using the :selected symbol, as well as :selected_value, :default, and :default_value. The value I associate with this has been both "DK", "dk", :DK, and "Danmark" (I'm using the "da" locale).

None of this has worked though - can you provide an example where a default value is selected?

Thanks in advance. --Rasmus

Join the discussion
 

(required)
(required, won't be displayed)

(Use Markdown syntax)