schmittjoh / JMSI18nRoutingBundle

Allows you to internationalize your routing
http://jmsyst.com/bundles/JMSI18nRoutingBundle
358 stars 159 forks source link

Ability to transform locale prefix #159

Open tomhv opened 9 years ago

tomhv commented 9 years ago

Would it be possible to update the DefaultPatternGenerationStrategy to have some kind of hook to allow some kind of transform on the _locale before it is added as a prefix?

We use country + language for our locale and would prefer to have it prefixed like this:

example.com/us/en/welcome

than this:

example.com/en_US/welcome

Another transform I can see is changing gb to uk to be more consistent with the .co.uk/.uk siffixes.

This is where I have added the call to the transform method in my code: https://github.com/schmittjoh/JMSI18nRoutingBundle/blob/master/Router/DefaultPatternGenerationStrategy.php#L69

// prefix with locale if requested
if (self::STRATEGY_PREFIX === $this->strategy
    || (self::STRATEGY_PREFIX_EXCEPT_DEFAULT === $this->strategy && $this->defaultLocale !== $locale)) {
    $i18nPattern = '/'.$this->transform($locale).$i18nPattern;
   if (null !== $route->getOption('i18n_prefix')) {
        $i18nPattern = $route->getOption('i18n_prefix').$i18nPattern;
    }
}

I know I can provide my own PatternGenerationStrategy, and I have done, but I'd hate to miss out on any bug fixes to the rest of the class.

picks44 commented 8 years ago

I have the same issue. @tomhv , does your code make this feature available ?

tomhv commented 8 years ago

Hey @picks44,

I used the code above and then the following method to transform my locale. Not sure if that's what you were asking, but there you go.

Cheers,

Tom

<?php

// src/AppBundle/Router/PatternGenerationStrategy.php

namespace AppBundle\Router;

use JMS\I18nRoutingBundle\Router\PatternGenerationStrategyInterface;

use Symfony\Component\Routing\RouteCollection,
    Symfony\Component\Translation\TranslatorInterface,
    Symfony\Component\Routing\Route;

class PatternGenerationStrategy implements PatternGenerationStrategyInterface
{
    // ...

    /**
     * transform _locale into URL prefix
     *
     * e.g. en_US => /us/en
     *
     * @param string $locale
     *
     * @return string
     */
    private function transform($locale)
    {
        switch ($locale) {
            case 'en_GB':

                return 'uk/en';

            default:

                return sprintf(
                    '%s/%s',
                    strtolower(substr($locale,3,2)),
                    strtolower(substr($locale,0,2))
                );
        }
    }
}
picks44 commented 8 years ago

Thanks a lot @tomhv , I'll try that. So I just need to tweak the vendor code with the first code, and then create this file (2nd code) in my own bundle ? I use the JMSI18nRoutingBundle on it's basic configuration.

tomhv commented 8 years ago

Don't edit the vendor code.

  1. Copy DefaultPatternGenerationStrategy from the JMSI18nRoutingBundle to your app bundle (AppBundle\Router\PatternGenerationStrategy).
  2. Update this line
    $i18nPattern = '/'.$locale.$i18nPattern;
    to
    $i18nPattern = '/'.$this->transform($locale).$i18nPattern;
  3. Add your AppBundle\Router\PatternGenerationStrategy::transform() method
  4. Add this to your params:
    jms_i18n_routing.pattern_generation_strategy.class: AppBundle\Router\PatternGenerationStrategy

That should do it.

picks44 commented 8 years ago

OK great ! I found it strange to update the vendor code ;)

picks44 commented 8 years ago

@tomhv I guess you meant jms_i18n_routing.pattern_generation_strategy.class: AppBundle\Router\DefaultPatternGenerationStrategy right ?

In the parameters of my config.yml ?

tomhv commented 8 years ago

I have this in my params.yml file, but it could go in your config.yml file too.

For the value, you should use whatever class you created with your custom code. I used AppBundle\Router\PatternGenerationStrategy

picks44 commented 8 years ago

@tomhv this is working nicely.

One warning message/error is raised though, when I "extract" the routes with the command app/console translation:extract fr_FR --config=app --output-format=xliff

I get this Can only extract the translation id from a scalar string, but got "PHPParser_Node_Expr_Variable". Please refactor your code to make it extractable, or add the doc comment /** @Ignore */ to this code element (in ../src/Des/AppBundle\Router\DefaultPatternGenerationStrategy.php on line 47)

Not sure it has something to do with this hack, but the targeted file is the one which we use for our matter.

tomhv commented 8 years ago

Hey @picks44, I haven't tried extracting the translations yet, so I don't know if it works.