How would you recommend providing all countries collection to a phoenix form select?

I need to support translations or at least show the countries in French.

All Hex packages I found so far don’t support i8n and will just show the names in English.

I’m hesitating between creating a table for countries in the database, or just use a long list without database. It seems to me that this is how the packages I found work though.

Is there maybe a package that you would recommend to me. I just need the countries names and maybe their ISO prefix.

2 Likes

You should use CLDR for that: https://github.com/schultzer/cldr_territories

As an example, we’ve used this to show a list of countries (with unicode flag):

defmodule MyAppWeb.RegistrationView do
  use MyAppWeb, :view

  alias Cldr.Territory

  def country_select(form, opts \\ []) do
    select(form, :address_country, country_options(), opts)
  end

  def country_options() do
    Territory.country_codes()
    |> Enum.map(&country_option/1)
    |> Enum.sort(&(&1[:key] <= &2[:key]))
  end

  def country_option(country) do
    [key: Territory.from_territory_code!(country),
     value: country,
     data_label: Territory.to_unicode_flag!(country)]
  end
end

You could use the translate_territory/3 method or if you only support french then just set the locale for that.

11 Likes

Thanks, that’s perfect. ^^

Finaly I had to create a Cldr backend module following the docs.

Then I replaced in your code, Cldr.Territory.from_territory_code!(country) with:

Territory.from_territory_code!(country, MyApp.Cldr)

Otherwise I was getting an error message saying that Cldr.Territory.from_territory_code!/1 does not exist.

1 Like

Good call! That’s been the major change in v2, the above code was used with v1. Unfortunately I can’t edit the post to update the example.

1 Like

Does anyone know where the translations come from? How they are generated and where they are stored? Unfortunately it doesn’t say in the docs
cc @kip ?

The localisation data comes from the CLDR project. The source is on github.

For ex_cldr and friends, the localisation data is baked into the code in a backend module. Using the example above, Territory.from_territory_code!(country, MyApp.Cldr), MyApp.Cldr is a backend module.

The serialised data can be explored, if you’re curious, by looking at the output from Cldr.Config.get_locale("en", %Cldr.Config{locales: :all}). Please note this is not a function to be used at runtime, its for compile time usage or exploration purposes only.

5 Likes

So I’m new to CLDR and I’ve seen on the website that the database contains telephone codes:
CLDR Features - CLDR - Unicode Common Locale Data Repository (under country information, last bullet point).

However there’s no way to retrieve a country calling code with ex_cldr and its friends?

I guess this should be in cldr_territories but it’s not included.

CLDR has deprecated telephone code data so it hasn’t been included in any ex_cldr or related library to my knowledge.

Depending on your requirements you might find ex_phone_number meets your needs. If you’re after a wrapper for Google’s libphonenumber which is the canonical library for parsing, formatting, and validating international phone numbers you might find elibphonenumber closer to your requirement although it is a NIF so has a more complex build process.

Lastly, if none of these meets your needs, let me know what the use case is - its an interesting topic (like postal codes) but just not currently top of my list of things to do.

2 Likes

Thank you @kip I created a new thread because I went off-topic from this original question.

Better SEO for others who look for that information:)

1 Like

I’ve added a territory select helper to ex_cldr_html, there’s an explanation in this forum thread: https://elixirforum.com/t/select-field-with-all-country-codes

6 Likes