xfra35 / f3-multilang

Create multilingual apps with this localization plugin for the PHP Fat-Free Framework
GNU General Public License v3.0
48 stars 13 forks source link

Generate equivalent URL in other languages when tokens are present #18

Closed djadomi closed 6 years ago

djadomi commented 6 years ago

Let's say we want the language menu to take you to the same page in the other languages, no just the root of the language.

Example:

You're on /en/games/first-person and this route is defined as follows:

GET @gamessection: /games/@section = Controller\Games->section

The corresponding rule for Spanish looks like this:

[MULTILANG.rules.es]
gamessection = /juegos/@section

The language menu looks like this:

<a title="GamesSite - English" href="{{@ml->alias(@ALIAS, null, 'en')}}">English</a>
<a title="GamesSite - Español" href="{{@ml->alias(@ALIAS, null, 'es')}}">Español</a>

The URL for Spanish will be rendered as /es/juegos/first-person when what we want is /es/juegos/primera-persona. How do we localise the @section parameter as well as the fixed part of the URL?

xfra35 commented 6 years ago

That's because you're calling the alias() method with the 2nd parameter not set, which is the same as passing the current route parameters.

You need somehow to pass the localized parameters to the function.

One way of doing it is to create a template filter which localizes the parameter before calling the alias() method.

E.g:

// index.php or bootstrap file or controller hook method
$tpl = Template::instance();
$tpl->filter('url', function($name, $params=NULL, $lang=NULL) use($f3, $ml, $db) {
  $params += $f3->PARAMS;
  // your custom params localization here:
  switch ($name) {
    case 'gamessection':
      // localize the term contained in $params['section'] from $ml->current to $lang
      // e.g:
      $sql = 'SELECT target.slug FROM sections source LEFT JOIN sections target
              ON source.id=target.id WHERE source.slug=?
              AND source.lang=? AND target.lang=?';
      if ($res=$db->exec($sql, [1=>$params['section'], $ml->current, $lang])
        $params['section'] = $res[0]['slug'];
      break;
    // etc.
  }
  // end of custom localization
  return $f3->BASE . $ml->alias($name, $params, $lang);
});
<!-- template file -->
<a title="GamesSite - English" href="{{ @ALIAS, null, 'en' | url }}">English</a>
djadomi commented 6 years ago

Thanks for your detailed answer. I'd left the 2nd parameter as null because I had no way to fill it in correctly as yet. I'll look into making a custom filter as you suggest.

Cheers