├── uninstall.rb ├── .gitignore ├── lib ├── localized_country_select │ ├── version.rb │ └── railtie.rb ├── localized_country_select.rb └── tasks │ └── localized_country_select_tasks.rake ├── install.rb ├── init.rb ├── Rakefile ├── MIT-LICENSE ├── localized_country_select.gemspec ├── README.rdoc ├── test └── localized_country_select_test.rb └── locale ├── cz.rb └── en.rb /uninstall.rb: -------------------------------------------------------------------------------- 1 | # Uninstall hook code here 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | */.DS_Store 3 | rdoc 4 | *.gem 5 | -------------------------------------------------------------------------------- /lib/localized_country_select/version.rb: -------------------------------------------------------------------------------- 1 | module LocalizedCountrySelect 2 | VERSION = '0.10.2' 3 | end 4 | -------------------------------------------------------------------------------- /install.rb: -------------------------------------------------------------------------------- 1 | # Show the README text file 2 | puts "\n\n" 3 | puts IO.read(File.join(File.dirname(__FILE__), 'README.rdoc')) 4 | puts "\n" -------------------------------------------------------------------------------- /init.rb: -------------------------------------------------------------------------------- 1 | # Require the plugin code 2 | require 'localized_country_select' 3 | 4 | # Load locales for countries from +locale+ directory into Rails 5 | I18n.load_path += Dir[ File.join(File.dirname(__FILE__), 'locale', '*.{rb,yml}') ] -------------------------------------------------------------------------------- /lib/localized_country_select/railtie.rb: -------------------------------------------------------------------------------- 1 | require 'localized_country_select' 2 | 3 | module LocalizedCountrySelect 4 | if defined? Rails::Railtie 5 | require 'rails' 6 | class Railtie < Rails::Railtie 7 | rake_tasks do 8 | load "tasks/localized_country_select_tasks.rake" 9 | end 10 | end 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'rake/testtask' 3 | require 'rake/task' 4 | 5 | load File.join(File.dirname(__FILE__), 'lib', 'tasks', 'localized_country_select_tasks.rake') 6 | 7 | desc 'Default: run unit tests.' 8 | task :default => :test 9 | 10 | desc 'Test the localized_country_select plugin.' 11 | Rake::TestTask.new(:test) do |t| 12 | t.libs << 'lib' 13 | t.pattern = 'test/**/*_test.rb' 14 | t.verbose = true 15 | end 16 | 17 | #desc 'Generate documentation for the localized_country_select plugin.' 18 | #Rake::Task.new(:rdoc) do |rdoc| 19 | #rdoc.rdoc_dir = 'rdoc' 20 | #rdoc.title = 'LocalizedCountrySelect' 21 | #rdoc.options << '--line-numbers' << '--inline-source' 22 | #rdoc.rdoc_files.include('README.rdoc') 23 | #rdoc.rdoc_files.include('lib/**/*.rb') 24 | #end 25 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008 [name of plugin creator] 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /localized_country_select.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | require File.expand_path('../lib/localized_country_select/version', __FILE__) 3 | 4 | Gem::Specification.new do |gem| 5 | gem.authors = ['karmi', 'mlitwiniuk', 'LIM SAS', 'Damien MATHIEU', 'Julien SANCHEZ', 'Herv\303\251 GAUCHER', 'RainerBlessing', 'bbenno'] 6 | gem.email = [nil, 'maciej@litwiniuk.net', nil, nil, nil, nil, nil, 'bbenno@digitize-it.de'] 7 | gem.description = %q( Localized "country_select" helper with Rake task for downloading locales from Unicode.org's CLDR ) 8 | gem.summary = %q( Localized "country_select" helper with Rake task for downloading locales from Unicode.org's CLDR ) 9 | gem.homepage = 'https://github.com/mlitwiniuk/localized_country_select' 10 | gem.license = 'MIT' 11 | 12 | gem.files = `git ls-files`.split("\n") - %w(localized_country_select.gemspec Gemfile init.rb) 13 | gem.executables = gem.files.grep(/^bin\//).map { |f| File.basename(f) } 14 | gem.test_files = gem.files.grep(/^(test|spec|features)\//) 15 | gem.name = 'localized_country_select' 16 | gem.require_paths = ['lib'] 17 | gem.version = LocalizedCountrySelect::VERSION 18 | gem.add_dependency 'actionpack', '>= 5.0' 19 | end 20 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = LocalizedCountrySelect 2 | 3 | Rails plugin to provide support for localized 49 | 50 | 51 | 52 | ... 53 | 54 | 55 | 56 | 57 | Show only country codes: 58 | 59 | <%= localized_country_select(:user, :country, [], {include_blank: 'Please choose...', description: :abbreviated}) %> 60 | 61 | will become: 62 | 63 | 70 | 71 | 72 | for the en locale. 73 | 74 | 75 | You can exclude countries by code using the exclude option (a single code or an array of country codes): 76 | 77 | localized_country_select(:user, :country, [], {exclude: [:ZZ, :US]}) 78 | 79 | 80 | == Formtastic and SimpleForm 81 | 82 | Gem supports (via alias_method) both formtastic and simple_form :country input 83 | 84 | == Other resources 85 | 86 | * http://github.com/rails/country_select (Default Rails plugin) 87 | * http://github.com/russ/country_code_select (Stores country code, not name) 88 | 89 | 90 | Copyright (c) 2008 Karel Minarik (www.karmi.cz), released under the MIT license 91 | -------------------------------------------------------------------------------- /test/localized_country_select_test.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | require 'test/unit' 3 | 4 | require 'rubygems' 5 | require 'active_support' 6 | require 'action_dispatch' 7 | require 'action_dispatch/testing/test_process' 8 | require 'action_view' 9 | require 'action_view/helpers' 10 | require 'action_view/helpers/tag_helper' 11 | require 'i18n' 12 | 13 | begin 14 | require 'redgreen' 15 | rescue LoadError 16 | puts "[!] Install redgreen gem for better test output ($ sudo gem install redgreen)" 17 | end unless ENV["TM_FILEPATH"] 18 | 19 | require 'localized_country_select' 20 | 21 | class LocalizedCountrySelectTest < Test::Unit::TestCase 22 | 23 | include ActionView::Helpers::TagHelper 24 | include ActionView::Helpers::FormOptionsHelper 25 | include ActionView::Helpers::FormTagHelper 26 | 27 | def test_action_view_should_include_helper_for_object 28 | assert ActionView::Helpers::FormBuilder.instance_methods.member?(:localized_country_select) 29 | assert ActionView::Helpers::FormOptionsHelper.instance_methods.include?(:localized_country_select) 30 | end 31 | 32 | def test_action_view_should_include_helper_tag 33 | assert ActionView::Helpers::FormOptionsHelper.instance_methods.include?(:localized_country_select_tag) 34 | end 35 | 36 | def test_should_return_select_tag_with_proper_name_for_object 37 | assert localized_country_select(:user, :country) =~ 38 | Regexp.new(Regexp.escape('') ), 46 | "Should have proper name" 47 | end 48 | 49 | def test_should_return_option_tags 50 | assert localized_country_select(:user, :country) =~ Regexp.new(Regexp.escape('')) 51 | end 52 | 53 | def test_should_return_localized_option_tags 54 | I18n.locale = 'cz' 55 | assert localized_country_select(:user, :country) =~ Regexp.new(Regexp.escape('')) 56 | end 57 | 58 | def test_should_return_priority_countries_first 59 | assert localized_country_options_for_select(nil, [:ES, :CZ]) =~ Regexp.new( 60 | Regexp.escape("\n\n\n")) 61 | end 62 | 63 | def test_i18n_should_know_about_countries 64 | assert_equal 'Spain', I18n.t('ES', :scope => 'countries') 65 | I18n.locale = 'cz' 66 | assert_equal 'Španělsko', I18n.t('ES', :scope => 'countries') 67 | end 68 | 69 | def test_excludes_countries 70 | assert_nothing_raised { LocalizedCountrySelect::localized_countries_array(:exclude => :ZZ) } 71 | 72 | assert_block do 73 | not LocalizedCountrySelect::localized_countries_array(:exclude => :ZZ).any? {|country| country.last == "ZZ"} 74 | end 75 | 76 | assert_block do 77 | not LocalizedCountrySelect::localized_countries_array(:exclude => [:ZZ, :US]).any? {|country| country.last == "ZZ" or country.last == "US"} 78 | end 79 | end 80 | 81 | def test_localized_countries_array_returns_correctly 82 | assert_nothing_raised { LocalizedCountrySelect::localized_countries_array() } 83 | # puts LocalizedCountrySelect::localized_countries_array.inspect 84 | I18n.locale = 'en' 85 | assert_equal 266, LocalizedCountrySelect::localized_countries_array.size 86 | assert_equal 'Afghanistan', LocalizedCountrySelect::localized_countries_array.first[0] 87 | I18n.locale = 'cz' 88 | assert_equal 250, LocalizedCountrySelect::localized_countries_array.size 89 | assert_equal 'Afghánistán', LocalizedCountrySelect::localized_countries_array.first[0] 90 | end 91 | 92 | def test_priority_countries_returns_correctly_and_in_correct_order 93 | assert_nothing_raised { LocalizedCountrySelect::priority_countries_array([:TW, :CN]) } 94 | I18n.locale = 'en' 95 | assert_equal [ ['Taiwan', 'TW'], ['China', 'CN'] ], LocalizedCountrySelect::priority_countries_array([:TW, :CN]) 96 | end 97 | 98 | def test_priority_countries_allows_passing_either_symbol_or_string 99 | I18n.locale = 'en' 100 | assert_equal [ ['United States', 'US'], ['Canada', 'CA'] ], LocalizedCountrySelect::priority_countries_array(['US', 'CA']) 101 | end 102 | 103 | def test_priority_countries_allows_passing_upcase_or_lowercase 104 | I18n.locale = 'en' 105 | assert_equal [ ['United States', 'US'], ['Canada', 'CA'] ], LocalizedCountrySelect::priority_countries_array(['us', 'ca']) 106 | assert_equal [ ['United States', 'US'], ['Canada', 'CA'] ], LocalizedCountrySelect::priority_countries_array([:us, :ca]) 107 | end 108 | 109 | def test_should_list_countries_with_accented_names_in_correct_order 110 | I18n.locale = 'cz' 111 | assert_match Regexp.new(Regexp.escape(%Q{\n})), localized_country_select(:user, :country) 112 | end 113 | 114 | #private 115 | 116 | def setup 117 | ['cz', 'en'].each do |locale| 118 | # I18n.load_translations( File.join(File.dirname(__FILE__), '..', 'locale', "#{locale}.rb") ) # <-- Old style! :) 119 | I18n.load_path += Dir[ File.join(File.dirname(__FILE__), '..', 'locale', "#{locale}.rb") ] 120 | end 121 | # I18n.locale = I18n.default_locale 122 | I18n.locale = 'en' 123 | end 124 | 125 | end 126 | -------------------------------------------------------------------------------- /lib/localized_country_select.rb: -------------------------------------------------------------------------------- 1 | # = LocalizedCountrySelect 2 | # 3 | # View helper for displaying select list with countries: 4 | # 5 | # localized_country_select(:user, :country) 6 | # 7 | # Works just like the default Rails' +country_select+ plugin, but stores countries as 8 | # country *codes*, not *names*, in the database. 9 | # 10 | # You can easily translate country codes in your application like this: 11 | # <%= I18n.t @user.country, :scope => 'countries' %> 12 | # 13 | # Uses the Rails internationalization framework (I18n) for translating the names of countries. 14 | # 15 | # Use Rake task rake import:country_select 'de' for importing country names 16 | # from Unicode.org's CLDR repository (http://www.unicode.org/cldr/data/charts/summary/root.html) 17 | # 18 | # Code adapted from Rails' default +country_select+ plugin (previously in core) 19 | # See http://github.com/rails/country_select/tree/master/lib/country_select.rb 20 | # 21 | 22 | module LocalizedCountrySelect 23 | class << self 24 | # Returns array with codes and localized country names (according to I18n.locale) 25 | # for tags 26 | def localized_countries_array(options={}) 27 | exclude = Array(options[:exclude]).map {|code| code.to_s.upcase } 28 | 29 | if(options[:description] == :abbreviated) 30 | I18n.translate(:countries).map { |key, value| [key.to_s.upcase] if !exclude.include?(key.to_s.upcase) } 31 | else 32 | I18n.translate(:countries).map { |key, value| [value, key.to_s.upcase] if !exclude.include?(key.to_s.upcase) } 33 | end.compact.sort_by { |country| country.first.parameterize } 34 | end 35 | # Return array with codes and localized country names for array of country codes passed as argument 36 | # == Example 37 | # priority_countries_array([:TW, :CN]) 38 | # # => [ ['Taiwan', 'TW'], ['China', 'CN'] ] 39 | def priority_countries_array(country_codes=[], options={}) 40 | if(options[:description] == :abbreviated) 41 | country_codes.map { |code| [code.to_s.upcase] } 42 | else 43 | countries = I18n.translate(:countries) 44 | country_codes.map { |code| [countries[code.to_s.upcase.to_sym], code.to_s.upcase] } 45 | end 46 | end 47 | end 48 | end 49 | 50 | module ActionView 51 | module Helpers 52 | 53 | module FormOptionsHelper 54 | 55 | # Return select and option tags for the given object and method, using +localized_country_options_for_select+ 56 | # to generate the list of option tags. Uses country code, not name as option +value+. 57 | # Country codes listed as an array of symbols in +priority_countries+ argument will be listed first 58 | # TODO : Implement pseudo-named args with a hash, not the "somebody said PHP?" multiple args sillines 59 | def localized_country_select(object, method, priority_countries = nil, options = {}, html_options = {}) 60 | tag = CountrySelect.new(object, method, self, options) 61 | 62 | tag.to_localized_country_select_tag(priority_countries, options, html_options) 63 | end 64 | alias_method :country_select, :localized_country_select 65 | 66 | # Return "named" select and option tags according to given arguments. 67 | # Use +selected_value+ for setting initial value 68 | # It behaves likes older object-binded brother +localized_country_select+ otherwise 69 | # TODO : Implement pseudo-named args with a hash, not the "somebody said PHP?" multiple args sillines 70 | def localized_country_select_tag(name, selected_value = nil, priority_countries = nil, html_options = {}) 71 | select_tag name.to_sym, localized_country_options_for_select(selected_value, priority_countries).html_safe, html_options.stringify_keys 72 | end 73 | alias_method :country_select_tag, :localized_country_select_tag 74 | 75 | # Returns a string of option tags for countries according to locale. Supply the country code in upper-case ('US', 'DE') 76 | # as +selected+ to have it marked as the selected option tag. 77 | # Country codes listed as an array of symbols in +priority_countries+ argument will be listed first 78 | def localized_country_options_for_select(selected = nil, priority_countries = nil, options={}) 79 | country_options = "".html_safe 80 | if priority_countries 81 | country_options += options_for_select(LocalizedCountrySelect::priority_countries_array(priority_countries, options), selected) 82 | country_options += "\n".html_safe 83 | return country_options + options_for_select(LocalizedCountrySelect::localized_countries_array(options) - LocalizedCountrySelect::priority_countries_array(priority_countries, options), selected) 84 | else 85 | return country_options + options_for_select(LocalizedCountrySelect::localized_countries_array(options), selected) 86 | end 87 | end 88 | alias_method :country_options_for_select, :localized_country_options_for_select 89 | 90 | end 91 | 92 | module ToCountrySelectTag 93 | def to_localized_country_select_tag(priority_countries, options, html_options) 94 | html_options = html_options.stringify_keys 95 | add_default_name_and_id(html_options) 96 | content_tag("select", 97 | add_options( 98 | localized_country_options_for_select(value, priority_countries, options).html_safe, 99 | options, value 100 | ), html_options 101 | ) 102 | end 103 | end 104 | 105 | class CountrySelect < Tags::Base 106 | include ToCountrySelectTag 107 | end 108 | 109 | class FormBuilder 110 | def localized_country_select(method, priority_countries = nil, options = {}, html_options = {}) 111 | @template.localized_country_select(@object_name, method, priority_countries, options.merge(object: @object), html_options) 112 | end 113 | alias_method :country_select, :localized_country_select 114 | end 115 | 116 | end 117 | end 118 | 119 | if defined?(Rails) 120 | require "localized_country_select/railtie" 121 | end 122 | -------------------------------------------------------------------------------- /locale/cz.rb: -------------------------------------------------------------------------------- 1 | { :cz => { 2 | 3 | :countries => { 4 | :AD => "Andorra", 5 | :AE => "Spojené arabské emiráty", 6 | :AF => "Afghánistán", 7 | :AG => "Antigua a Barbuda", 8 | :AI => "Anguila", 9 | :AL => "Albánie", 10 | :AM => "Arménie", 11 | :AN => "Nizozemské Antily", 12 | :AO => "Angola", 13 | :AQ => "Antarktida", 14 | :AR => "Argentina", 15 | :AS => "Americká Samoa", 16 | :AT => "Rakousko", 17 | :AU => "Austrálie", 18 | :AW => "Aruba", 19 | :AX => "Alandy", 20 | :AZ => "Ázerbájdžán", 21 | :BA => "Bosna a Hercegovina", 22 | :BB => "Barbados", 23 | :BD => "Bangladéš", 24 | :BE => "Belgie", 25 | :BF => "Burkina Faso", 26 | :BG => "Bulharsko", 27 | :BH => "Bahrajn", 28 | :BI => "Burundi", 29 | :BJ => "Benin", 30 | :BL => "Svatý Bartolomějd", 31 | :BM => "Bermudy", 32 | :BN => "Brunej Darussalam", 33 | :BO => "Bolívie", 34 | :BR => "Brazílie", 35 | :BS => "Bahamy", 36 | :BT => "Bhútán", 37 | :BV => "Ostrov Bouvet", 38 | :BW => "Botswana", 39 | :BY => "Bělorusko", 40 | :BZ => "Belize", 41 | :CA => "Kanada", 42 | :CC => "Kokosové ostrovy", 43 | :CD => "Demokratická republika Kongo", 44 | :CF => "Středoafrická republika", 45 | :CG => "Kongo", 46 | :CH => "Švýcarsko", 47 | :CI => "Pobřeží slonoviny", 48 | :CK => "Cookovy ostrovy", 49 | :CL => "Chile", 50 | :CM => "Kamerun", 51 | :CN => "Čína", 52 | :CO => "Kolumbie", 53 | :CR => "Kostarika", 54 | :CS => "Srbsko a Černá HoraR014", 55 | :CU => "Kuba", 56 | :CV => "Kapverdy", 57 | :CX => "Vánoční ostrovy", 58 | :CY => "Kypr", 59 | :CZ => "Česká republika", 60 | :DE => "Německo", 61 | :DJ => "Džibuti", 62 | :DK => "Dánsko", 63 | :DM => "Dominika", 64 | :DO => "Dominikánská republika", 65 | :DZ => "Alžírsko", 66 | :EC => "Ekvádor", 67 | :EE => "Estonsko", 68 | :EG => "Egypt", 69 | :EH => "Západní Sahara", 70 | :ER => "Eritrea", 71 | :ES => "Španělsko", 72 | :ET => "Etiopie", 73 | :FI => "Finsko", 74 | :FJ => "Fidži", 75 | :FK => "Falklandské ostrovy", 76 | :FM => "Mikronézie", 77 | :FO => "Faerské ostrovy", 78 | :FR => "Francie", 79 | :GA => "Gabon", 80 | :GB => "Velká Británie", 81 | :GD => "Grenada", 82 | :GE => "Gruzie", 83 | :GF => "Francouzská Guyana", 84 | :GG => "Guernsey", 85 | :GH => "Ghana", 86 | :GI => "Gibraltar", 87 | :GL => "Grónsko", 88 | :GM => "Gambie", 89 | :GN => "Guinea", 90 | :GP => "Guadeloupe", 91 | :GQ => "Rovníková Guinea", 92 | :GR => "Řecko", 93 | :GS => "Jižní Georgie a Jižní Sandwichovy ostrovy", 94 | :GT => "Guatemala", 95 | :GU => "Guam", 96 | :GW => "Guinea-Bissau", 97 | :GY => "Guyana", 98 | :HK => "Hongkong", 99 | :HM => "Ostrovy Heard a McDonald", 100 | :HN => "Honduras", 101 | :HR => "Chorvatsko", 102 | :HT => "Haiti", 103 | :HU => "Maďarsko", 104 | :ID => "Indonésie", 105 | :IE => "Irsko", 106 | :IL => "Izrael", 107 | :IM => "Ostrov Man", 108 | :IN => "Indie", 109 | :IO => "Britské území v Indickém oceánu", 110 | :IQ => "Irák", 111 | :IR => "Írán", 112 | :IS => "Island", 113 | :IT => "Itálie", 114 | :JE => "Jersey", 115 | :JM => "Jamajka", 116 | :JO => "Jordánsko", 117 | :JP => "Japonsko", 118 | :KE => "Keňa", 119 | :KG => "Kyrgyzstán", 120 | :KH => "Kambodža", 121 | :KI => "Kiribati", 122 | :KM => "Komory", 123 | :KN => "Svatý Kitts a Nevis", 124 | :KP => "Severní Korea", 125 | :KR => "Jižní Korea", 126 | :KW => "Kuvajt", 127 | :KY => "Kajmanské ostrovy", 128 | :KZ => "Kazachstán", 129 | :LA => "Lidově demokratická republika Laos", 130 | :LB => "Libanon", 131 | :LC => "Svatá Lucie", 132 | :LI => "Lichtenštejnsko", 133 | :LK => "Srí Lanka", 134 | :LR => "Libérie", 135 | :LS => "Lesotho", 136 | :LT => "Litva", 137 | :LU => "Lucembursko", 138 | :LV => "Lotyšsko", 139 | :LY => "Libye", 140 | :MA => "Maroko", 141 | :MC => "Monako", 142 | :MD => "Moldavsko, republika", 143 | :ME => "Černá Hora", 144 | :MF => "Svatý Martin; [draft=contributed]", 145 | :MG => "Madagaskar", 146 | :MH => "Marshallovy ostrovy", 147 | :MK => "Macedonia", 148 | :ML => "Mali", 149 | :MM => "Myanmar", 150 | :MN => "Mongolsko", 151 | :MO => "Macao", 152 | :MP => "Severní Mariany", 153 | :MQ => "Martinik", 154 | :MR => "Mauritánie", 155 | :MS => "Montserrat", 156 | :MT => "Malta", 157 | :MU => "Mauricius", 158 | :MV => "Maladivy", 159 | :MW => "Malawi", 160 | :MX => "Mexiko", 161 | :MY => "Malajsie", 162 | :MZ => "Mosambik", 163 | :NA => "Namibie", 164 | :NC => "Nová Kaledonie", 165 | :NE => "Niger", 166 | :NF => "Norfolk", 167 | :NG => "Nigérie", 168 | :NI => "Nikaragua", 169 | :NL => "Nizozemsko", 170 | :NO => "Norsko", 171 | :NP => "Nepál", 172 | :NR => "Nauru", 173 | :NU => "Niue", 174 | :NZ => "Nový Zéland", 175 | :OM => "Omán", 176 | :PA => "Panama", 177 | :PE => "Peru", 178 | :PF => "Francouzská Polynésie", 179 | :PG => "Papua-Nová Guinea", 180 | :PH => "Filipíny", 181 | :PK => "Pákistán", 182 | :PL => "Polsko", 183 | :PM => "Svatý Pierre a Miquelon", 184 | :PN => "Pitcairn", 185 | :PR => "Portoriko", 186 | :PS => "Palestinian Territory", 187 | :PT => "Portugalsko", 188 | :PW => "Palau", 189 | :PY => "Paraguay", 190 | :QA => "Katar", 191 | :QO => "Vnější Oceánie", 192 | :QU => "Evropská unie", 193 | :RE => "Réunion", 194 | :RO => "Rumunsko", 195 | :RS => "Srbsko", 196 | :RU => "Rusko", 197 | :RW => "Rwanda", 198 | :SA => "Saúdská Arábie", 199 | :SB => "Šalamounovy ostrovy", 200 | :SC => "Seychely", 201 | :SD => "Súdán", 202 | :SE => "Švédsko", 203 | :SG => "Singapur", 204 | :SH => "Svatá Helena", 205 | :SI => "Slovinsko", 206 | :SJ => "Svalbard a Jan Mayen", 207 | :SK => "Slovensko", 208 | :SL => "Sierra Leone", 209 | :SM => "San Marino", 210 | :SN => "Senegal", 211 | :SO => "Somálsko", 212 | :SR => "Surinam", 213 | :ST => "Svatý Tomáš", 214 | :SV => "El Salvador", 215 | :SY => "Sýrie", 216 | :SZ => "Svazijsko", 217 | :TC => "Ostrovy Caicos a Turks", 218 | :TD => "Čad", 219 | :TF => "Francouzská jižní teritoria", 220 | :TG => "Togo", 221 | :TH => "Thajsko", 222 | :TJ => "Tádžikistán", 223 | :TK => "Tokelau", 224 | :TL => "Východní Timor", 225 | :TM => "Turkmenistán", 226 | :TN => "Tunisko", 227 | :TO => "Tonga", 228 | :TR => "Turecko", 229 | :TT => "Trinidad a Tobago", 230 | :TV => "Tuvalu", 231 | :TW => "Tchaj-wan", 232 | :TZ => "Tanzanie", 233 | :UA => "Ukrajina", 234 | :UG => "Uganda", 235 | :UM => "Menší odlehlé ostrovy USA", 236 | :US => "Spojené státy", 237 | :UY => "Uruguay", 238 | :UZ => "Uzbekistán", 239 | :VA => "Svatý stolec", 240 | :VC => "Svatý Vincent a Grenadiny", 241 | :VE => "Venezuela", 242 | :VG => "Britské Panenské ostrovy", 243 | :VI => "Americké Panenské ostrovy", 244 | :VN => "Vietnam", 245 | :VU => "Vanuatu", 246 | :WF => "Wallis a Futuna", 247 | :WS => "Samoa", 248 | :YE => "Jemen", 249 | :YT => "Mayotte", 250 | :ZA => "Jihoafrická republika", 251 | :ZM => "Zambie", 252 | :ZW => "Zimbabwe", 253 | :ZZ => "Neznámá nebo neplatná oblast", 254 | } 255 | 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /locale/en.rb: -------------------------------------------------------------------------------- 1 | { :en => { 2 | 3 | :countries => { 4 | :AD => "Andorra", 5 | :AE => "United Arab Emirates", 6 | :AF => "Afghanistan", 7 | :AG => "Antigua and Barbuda", 8 | :AI => "Anguilla", 9 | :AL => "Albania", 10 | :AM => "Armenia", 11 | :AN => "Netherlands Antilles", 12 | :AO => "Angola", 13 | :AQ => "Antarctica", 14 | :AR => "Argentina", 15 | :AS => "American Samoa", 16 | :AT => "Austria", 17 | :AU => "Australia", 18 | :AW => "Aruba", 19 | :AX => "Aland Islands", 20 | :AZ => "Azerbaijan", 21 | :BA => "Bosnia and Herzegovina", 22 | :BB => "Barbados", 23 | :BD => "Bangladesh", 24 | :BE => "Belgium", 25 | :BF => "Burkina Faso", 26 | :BG => "Bulgaria", 27 | :BH => "Bahrain", 28 | :BI => "Burundi", 29 | :BJ => "Benin", 30 | :BL => "Saint Barthélemy", 31 | :BM => "Bermuda", 32 | :BN => "Brunei", 33 | :BO => "Bolivia", 34 | :BQ => "British Antarctic Territory", 35 | :BR => "Brazil", 36 | :BS => "Bahamas", 37 | :BT => "Bhutan", 38 | :BV => "Bouvet Island", 39 | :BW => "Botswana", 40 | :BY => "Belarus", 41 | :BZ => "Belize", 42 | :CA => "Canada", 43 | :CC => "Cocos Islands", 44 | :CD => "Congo - Kinshasa", 45 | :CF => "Central African Republic", 46 | :CG => "Congo - Brazzaville", 47 | :CH => "Switzerland", 48 | :CI => "Ivory Coast", 49 | :CK => "Cook Islands", 50 | :CL => "Chile", 51 | :CM => "Cameroon", 52 | :CN => "China", 53 | :CO => "Colombia", 54 | :CR => "Costa Rica", 55 | :CS => "Serbia and Montenegro", 56 | :CT => "Canton and Enderbury Islands", 57 | :CU => "Cuba", 58 | :CV => "Cape Verde", 59 | :CX => "Christmas Island", 60 | :CY => "Cyprus", 61 | :CZ => "Czech Republic", 62 | :DD => "East Germany", 63 | :DE => "Germany", 64 | :DJ => "Djibouti", 65 | :DK => "Denmark", 66 | :DM => "Dominica", 67 | :DO => "Dominican Republic", 68 | :DZ => "Algeria", 69 | :EC => "Ecuador", 70 | :EE => "Estonia", 71 | :EG => "Egypt", 72 | :EH => "Western Sahara", 73 | :ER => "Eritrea", 74 | :ES => "Spain", 75 | :ET => "Ethiopia", 76 | :FI => "Finland", 77 | :FJ => "Fiji", 78 | :FK => "Falkland Islands", 79 | :FM => "Micronesia", 80 | :FO => "Faroe Islands", 81 | :FQ => "French Southern and Antarctic Territories", 82 | :FR => "France", 83 | :FX => "Metropolitan France", 84 | :GA => "Gabon", 85 | :GB => "United Kingdom", 86 | :GD => "Grenada", 87 | :GE => "Georgia", 88 | :GF => "French Guiana", 89 | :GG => "Guernsey", 90 | :GH => "Ghana", 91 | :GI => "Gibraltar", 92 | :GL => "Greenland", 93 | :GM => "Gambia", 94 | :GN => "Guinea", 95 | :GP => "Guadeloupe", 96 | :GQ => "Equatorial Guinea", 97 | :GR => "Greece", 98 | :GS => "South Georgia and the South Sandwich Islands", 99 | :GT => "Guatemala", 100 | :GU => "Guam", 101 | :GW => "Guinea-Bissau", 102 | :GY => "Guyana", 103 | :HK => "Hong Kong", 104 | :HM => "Heard Island and McDonald Islands", 105 | :HN => "Honduras", 106 | :HR => "Croatia", 107 | :HT => "Haiti", 108 | :HU => "Hungary", 109 | :ID => "Indonesia", 110 | :IE => "Ireland", 111 | :IL => "Israel", 112 | :IM => "Isle of Man", 113 | :IN => "India", 114 | :IO => "British Indian Ocean Territory", 115 | :IQ => "Iraq", 116 | :IR => "Iran", 117 | :IS => "Iceland", 118 | :IT => "Italy", 119 | :JE => "Jersey", 120 | :JM => "Jamaica", 121 | :JO => "Jordan", 122 | :JP => "Japan", 123 | :JT => "Johnston Island", 124 | :KE => "Kenya", 125 | :KG => "Kyrgyzstan", 126 | :KH => "Cambodia", 127 | :KI => "Kiribati", 128 | :KM => "Comoros", 129 | :KN => "Saint Kitts and Nevis", 130 | :KP => "North Korea", 131 | :KR => "South Korea", 132 | :KW => "Kuwait", 133 | :KY => "Cayman Islands", 134 | :KZ => "Kazakhstan", 135 | :LA => "Laos", 136 | :LB => "Lebanon", 137 | :LC => "Saint Lucia", 138 | :LI => "Liechtenstein", 139 | :LK => "Sri Lanka", 140 | :LR => "Liberia", 141 | :LS => "Lesotho", 142 | :LT => "Lithuania", 143 | :LU => "Luxembourg", 144 | :LV => "Latvia", 145 | :LY => "Libya", 146 | :MA => "Morocco", 147 | :MC => "Monaco", 148 | :MD => "Moldova", 149 | :ME => "Montenegro", 150 | :MF => "Saint Martin", 151 | :MG => "Madagascar", 152 | :MH => "Marshall Islands", 153 | :MI => "Midway Islands", 154 | :MK => "Macedonia", 155 | :ML => "Mali", 156 | :MM => "Myanmar", 157 | :MN => "Mongolia", 158 | :MO => "Macau", 159 | :MP => "Northern Mariana Islands", 160 | :MQ => "Martinique", 161 | :MR => "Mauritania", 162 | :MS => "Montserrat", 163 | :MT => "Malta", 164 | :MU => "Mauritius", 165 | :MV => "Maldives", 166 | :MW => "Malawi", 167 | :MX => "Mexico", 168 | :MY => "Malaysia", 169 | :MZ => "Mozambique", 170 | :NA => "Namibia", 171 | :NC => "New Caledonia", 172 | :NE => "Niger", 173 | :NF => "Norfolk Island", 174 | :NG => "Nigeria", 175 | :NI => "Nicaragua", 176 | :NL => "Netherlands", 177 | :NO => "Norway", 178 | :NP => "Nepal", 179 | :NQ => "Dronning Maud Land", 180 | :NR => "Nauru", 181 | :NT => "Neutral Zone", 182 | :NU => "Niue", 183 | :NZ => "New Zealand", 184 | :OM => "Oman", 185 | :PA => "Panama", 186 | :PC => "Pacific Islands Trust Territory", 187 | :PE => "Peru", 188 | :PF => "French Polynesia", 189 | :PG => "Papua New Guinea", 190 | :PH => "Philippines", 191 | :PK => "Pakistan", 192 | :PL => "Poland", 193 | :PM => "Saint Pierre and Miquelon", 194 | :PN => "Pitcairn", 195 | :PR => "Puerto Rico", 196 | :PS => "Palestinian Territory", 197 | :PT => "Portugal", 198 | :PU => "U.S. Miscellaneous Pacific Islands", 199 | :PW => "Palau", 200 | :PY => "Paraguay", 201 | :PZ => "Panama Canal Zone", 202 | :QA => "Qatar", 203 | :QO => "Outlying Oceania", 204 | :QU => "European Union", 205 | :RE => "Reunion", 206 | :RO => "Romania", 207 | :RS => "Serbia", 208 | :RU => "Russia", 209 | :RW => "Rwanda", 210 | :SA => "Saudi Arabia", 211 | :SB => "Solomon Islands", 212 | :SC => "Seychelles", 213 | :SD => "Sudan", 214 | :SE => "Sweden", 215 | :SG => "Singapore", 216 | :SH => "Saint Helena", 217 | :SI => "Slovenia", 218 | :SJ => "Svalbard and Jan Mayen", 219 | :SK => "Slovakia", 220 | :SL => "Sierra Leone", 221 | :SM => "San Marino", 222 | :SN => "Senegal", 223 | :SO => "Somalia", 224 | :SR => "Suriname", 225 | :ST => "Sao Tome and Principe", 226 | :SU => "Union of Soviet Socialist Republics", 227 | :SV => "El Salvador", 228 | :SY => "Syria", 229 | :SZ => "Swaziland", 230 | :TC => "Turks and Caicos Islands", 231 | :TD => "Chad", 232 | :TF => "French Southern Territories", 233 | :TG => "Togo", 234 | :TH => "Thailand", 235 | :TJ => "Tajikistan", 236 | :TK => "Tokelau", 237 | :TL => "East Timor", 238 | :TM => "Turkmenistan", 239 | :TN => "Tunisia", 240 | :TO => "Tonga", 241 | :TR => "Turkey", 242 | :TT => "Trinidad and Tobago", 243 | :TV => "Tuvalu", 244 | :TW => "Taiwan", 245 | :TZ => "Tanzania", 246 | :UA => "Ukraine", 247 | :UG => "Uganda", 248 | :UM => "United States Minor Outlying Islands", 249 | :US => "United States", 250 | :UY => "Uruguay", 251 | :UZ => "Uzbekistan", 252 | :VA => "Vatican", 253 | :VC => "Saint Vincent and the Grenadines", 254 | :VD => "North Vietnam", 255 | :VE => "Venezuela", 256 | :VG => "British Virgin Islands", 257 | :VI => "U.S. Virgin Islands", 258 | :VN => "Vietnam", 259 | :VU => "Vanuatu", 260 | :WF => "Wallis and Futuna", 261 | :WK => "Wake Island", 262 | :WS => "Samoa", 263 | :YD => "People's Democratic Republic of Yemen", 264 | :YE => "Yemen", 265 | :YT => "Mayotte", 266 | :ZA => "South Africa", 267 | :ZM => "Zambia", 268 | :ZW => "Zimbabwe", 269 | :ZZ => "Unknown or Invalid Region", 270 | } 271 | 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /lib/tasks/localized_country_select_tasks.rake: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'open-uri' 3 | require 'active_support/inflector' 4 | require 'csv' 5 | 6 | # Rake task for importing country names from Unicode.org's CLDR repository 7 | # (https://unicode-org.github.io/cldr-staging/charts/37/summary/root.html). 8 | # 9 | # It parses a HTML file from Unicode.org for given locale and saves the 10 | # Rails' I18n hash in the plugin +locale+ directory 11 | # 12 | # Don't forget to restart the application when you add new locale to load it into Rails! 13 | # 14 | # == Parameters 15 | # LOCALE (required): Sets the locale to use. Output file name will include this. 16 | # FORMAT (optional): Output format, either 'rb' or 'yml'. Defaults to 'rb' if not specified. 17 | # WEB_LOCALE (optional): Forces a locale code to use when querying the Unicode.org CLDR archive. 18 | # PARSER (optional): Forces parser to use. Available are nokogiri, hpricot and libxml. 19 | # 20 | # == Examples 21 | # rake import:country_select LOCALE=de 22 | # rake import:country_select LOCALE=pt-BR WEB_LOCALE=pt FORMAT=yml 23 | # 24 | # The code is deliberately procedural and simple, so it's easily 25 | # understandable by beginners as an introduction to Rake tasks power. 26 | # See https://github.com/svenfuchs/ruby-cldr for much more robust solution 27 | 28 | namespace :import do 29 | 30 | desc "Import country codes and names for various languages from the Unicode.org CLDR archive." 31 | task :country_select do 32 | # TODO : Implement locale import chooser from CLDR root via Highline 33 | 34 | # Setup variables 35 | locale = ENV['LOCALE'] 36 | unless locale 37 | puts "\n[!] Usage: rails import:country_select LOCALE=de\n\n" 38 | exit 0 39 | end 40 | 41 | # convert locale code to Unicode.org CLDR acceptable code 42 | web_locale = if ENV['WEB_LOCALE'] then ENV['WEB_LOCALE'] 43 | elsif %w(zht zhtw).include?(locale.downcase.gsub(/[-_]/,'')) then 'zh_Hant' 44 | elsif %w(zhs zhcn).include?(locale.downcase.gsub(/[-_]/,'')) then 'zh_Hans' 45 | else locale.underscore.split('_')[0] end 46 | 47 | # ----- Get the CLDR HTML -------------------------------------------------- 48 | begin 49 | puts "... getting the HTML file for locale '#{web_locale}'" 50 | url = "https://unicode-org.github.io/cldr-staging/charts/37/summary/#{web_locale}.html" 51 | html = open(url).read 52 | rescue => e 53 | puts "[!] Invalid locale name '#{web_locale}'! Not found in CLDR (#{e})" 54 | exit 0 55 | end 56 | 57 | 58 | set_parser(ENV['PARSER']) if ENV['PARSER'] 59 | puts "... parsing the HTML file using #{parser.name.split("::").last}" 60 | countries = parser.parse(html).inject([]) { |arr, (_code, attrs)| arr << attrs } 61 | countries.sort_by! { |c| c[:code] } 62 | puts '... fetching correct list of country codes and filtering translations' 63 | correct_list = CSV.parse(open('https://raw.githubusercontent.com/datasets/un-locode/master/data/country-codes.csv').string) 64 | country_codes = correct_list.map { |c| c[0] } 65 | countries.delete_if { |c| !country_codes.member?(c[:code].to_s) } 66 | puts "\n\n... imported #{countries.count} countries:" 67 | 68 | puts countries.map { |c| "#{c[:code]}: #{c[:name]}" }.join(", ") 69 | 70 | 71 | # ----- Prepare the output format ------------------------------------------ 72 | 73 | format = if ENV['FORMAT'].nil?||%(rb ruby).include?(ENV['FORMAT'].downcase) then :rb 74 | elsif %(yml yaml).include?(ENV['FORMAT'].downcase) then :yml end 75 | 76 | unless format 77 | puts "\n[!] FORMAT must be either 'rb' or 'yml'\n\n" 78 | exit 0 79 | end 80 | 81 | if format==:yml 82 | output =< { 94 | 95 | :countries => { 96 | HEAD 97 | countries.each do |country| 98 | output << "\t\t\t:#{country[:code]} => \"#{country[:name]}\",\n" 99 | end 100 | output <<<= 6 && g[4].inner_html =~ /^[A-Z]{2}$/ 146 | code = g[4].inner_text 147 | code = code[-code.size, 2].to_sym 148 | name = row.search("td[@class='v']:not([@title])").inner_text 149 | 150 | hash[code] = {:code => code, :name => name.to_s} 151 | end 152 | hash 153 | end 154 | end 155 | end 156 | 157 | class HpricotParser < NokogiriParser 158 | def document 159 | @document ||= Hpricot(html) 160 | end 161 | end 162 | 163 | class LibXMLParser < Parser 164 | def document 165 | @document ||= LibXML::XML::HTMLParser.string(html, options: LibXML::XML::HTMLParser::Options::RECOVER).parse 166 | end 167 | 168 | def parse 169 | document.find("//tr").inject({}) do |hash, row| 170 | n = row.find("td[@class='n']") 171 | g = row.find("td") 172 | if n.map(&:content).join =~ /Locale Display Names/ && g.count >= 6 && g[4].inner_xml =~ /^[A-Z]{2}/ 173 | code = g[4].content 174 | code = code[-code.size, 2].to_sym 175 | name = row.find("td[@class='v' and not(@title)]").map(&:content).join 176 | 177 | hash[code] ||= {:code => code, :name => name.to_s} 178 | end 179 | hash 180 | end 181 | end 182 | end 183 | 184 | REQUIREMENTS_MAP = [ 185 | ['nokogiri', :Nokogiri], 186 | ['hpricot', :Hpricot], 187 | ['libxml', :LibXML] 188 | ] 189 | 190 | def self.detect_parser 191 | REQUIREMENTS_MAP.each do |library, klass| 192 | return const_get(:"#{klass}Parser") if const_defined?(klass) 193 | end 194 | 195 | REQUIREMENTS_MAP.each do |library, klass| 196 | begin 197 | require library 198 | return const_get(:"#{klass}Parser") 199 | rescue LoadError 200 | end 201 | end 202 | 203 | raise StandardError, "One of nokogiri, hpricot or libxml-ruby gem is required! Add \"gem 'nokogiri'\" to your Gemfile to resolve this issue." 204 | end 205 | end 206 | 207 | def parser 208 | @parser ||= LocalizedCountrySelectTasks.detect_parser 209 | end 210 | 211 | def set_parser(arg) 212 | @parser = begin 213 | parser = nil 214 | requirements = LocalizedCountrySelectTasks::REQUIREMENTS_MAP 215 | found = requirements.detect { |library, _| library == arg } 216 | raise ArgumentError, "Can't find parser for #{arg}! Supported parsers are: #{requirements.map(&:first).join(", ")}." unless found 217 | library, klass = found 218 | begin 219 | require library 220 | parser = LocalizedCountrySelectTasks.const_get(:"#{klass}Parser") 221 | rescue LoadError 222 | gem_name = library == 'libxml' ? 'libxml-ruby' : library 223 | raise ArgumentError, "Can't find #{library} library! Add \"gem '#{gem_name}'\" to Gemfile." 224 | end 225 | parser 226 | end 227 | end 228 | end 229 | --------------------------------------------------------------------------------