27

I'm using the Symfony2 country Field Type, it works well and country names are translated. I am storing the two-digit country code in the column country of my entity.

How can I display the full, translated country name? This is how I added the field to the form:

$builder
    ->add('country', 'country', array(
        'label' => 'Paese', 'preferred_choices' => array('IT')
    ));

And then in my controller:

$user = $this->getDoctrine()->getRepository('AcmeHelloBundle:User');
$countryCode = $user->getCountry();
$countryName = null; // Get translated country name from code

Or in my twig template:

{# Output the country code and name #}
{{ user.country }}

{# translated country name from code #}
Pratik Gadoya
  • 1,420
  • 1
  • 16
  • 27

7 Answers7

21

I'm not sure if you still need... but it might help someone else. this can be done through a twig extension easily (this code is based on @tomaszsobczak's answer )

<?php
    // src/Acme/DemoBundle/Twig/CountryExtension.php
    namespace Acme\DemoBundle\Twig;


    class CountryExtension extends \Twig_Extension {
        public function getFilters()
        {
            return array(
                new \Twig_SimpleFilter('country', array($this, 'countryFilter')),
            );
        }

        public function countryFilter($countryCode,$locale = "en"){
            $c = \Symfony\Component\Locale\Locale::getDisplayCountries($locale);

            return array_key_exists($countryCode, $c)
                ? $c[$countryCode]
                : $countryCode;
        }

        public function getName()
        {
            return 'country_extension';
        }
    }

And in your services.yml files

# src/Acme/DemoBundle/Resources/config/services.yml
services:
    acme.twig.country_extension:
        class: Acme\DemoBundle\Twig\CountryExtension
        tags:
            - { name: twig.extension }

Usage example inside a twig file:

{{ 'US'|country(app.request.locale) }}
Hannoun Yassir
  • 20,583
  • 23
  • 77
  • 112
  • 3
    `\Symfony\Component\Locale\Locale` will be depricated in Symfony 3.0 – Rvanlaak Sep 23 '13 at 08:45
  • I like this solution the best, just be carefull at public Function getFilter: Check your own version of symfony2 documentation for the proper return value (google for twig custom filter you'll find it fast) – Cesc Dec 03 '13 at 10:04
  • 4
    Great simple solution. To fit with Sf 3.0, just change the `countryFilter` method this way: `return Symfony\Component\Intl\Intl::getRegionBundle()->getCountryName($countryCode, $locale); ` – Ronan Sep 11 '15 at 20:04
19

As per @Rvanlaak's comment above, \Symfony\Component\Locale\Locale is now deprecated. I think the most concise way to do this now is:

use Symfony\Component\Intl\Intl;

...

$country = Intl::getRegionBundle()->getCountryName($countryCode);
NoelLH
  • 361
  • 6
  • 15
17

Inspired by Hannoun Yassir answer, I use the Intl as in the country type field. The code of twig extension is

<?php
namespace Tbl\SagaBundle\Twig;

use Symfony\Component\Intl\Intl;

class CountryExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('countryName', array($this, 'countryName')),
        );
    }

    public function countryName($countryCode){
        return Intl::getRegionBundle()->getCountryName($countryCode);
    }

    public function getName()
    {
        return 'country_extension';
    }
}
?>

Add twig extension in services.yml

# src/Acme/DemoBundle/Resources/config/services.yml
services:
    acme.twig.acme_extension:
        class: Acme\DemoBundle\Twig\CountryExtension
        tags:
            - { name: twig.extension }

usage in the template (the country name will be display in locale by default (see Symfony/Component/Intl/ResourceBundle/RegionBundleInterface.php)

{{ user.countryCode|countryName }}

Many thanks Yassir, this version don't use locale deprecated since version 2.3 >> http://symfony.com/components/Locale

Fabrice G
  • 273
  • 2
  • 5
11

You can use the same component that Symfony is using for country Field Type

public function humanCountry() {
    $c = \Symfony\Component\Locale\Locale::getDisplayCountries('en');

    return array_key_exists($this->getCountry(), $c)
           ? $c[$this->getCountry()]
           : $this->getCountry();
}
TomaszSobczak
  • 2,900
  • 21
  • 24
11

Use SonanaIntlBundle, you could do something like this:

{{ 'FR' | country }} => France (if the current locale in request is 'fr')
{{ 'FR' | country('de') }} => Frankreich (force the locale)

{{ 'fr' | language }} => français (if the current locale in request is 'fr')
{{ 'fr' | language('en') }} => French (force the locale)

{{ 'fr' | locale }} => français (if the current locale in request is 'fr')
{{ 'fr' | locale('en') }} => French (force the locale)

Read more about this

smoreno
  • 3,129
  • 3
  • 32
  • 49
  • I'm not going to install a bundle just for this, but thanks. II think that the string name should already be in Symfony2. – gremo Mar 26 '12 at 10:55
9

Well if you are using entities one option instead of doing twig filters is to create function for getting country name inside entity.

use Symfony\Component\Intl\Intl;

public function getCountryName() {
    return Intl::getRegionBundle()->getCountryName($this->getCountry());
}

So in twig later you can do

{{ user.countryName }}
Dainius
  • 91
  • 2
  • 2
3

For convenience purposes, if someone reads this some years later:

For twig 2 or later you can use

composer require twig/intl-extra

to make the filter language_name available. It also provides some options for configuration.

See the doc.

Wolfone
  • 1,276
  • 3
  • 11
  • 31