Here is my solution :
Middleware
<?php
namespace App\Middleware;
use Interop\Http\ServerMiddleware\DelegateInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Locale;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class LocalizationMiddleware implements MiddlewareInterface
{
public const LOCALIZATION_ATTRIBUTE = 'locale';
public function process(ServerRequestInterface $request, DelegateInterface $delegate) : ResponseInterface
{
$cookies = $request->getCookieParams();
$query = $request->getQueryParams();
$server = $request->getServerParams();
if (isset($query['lang']) && preg_match('/^(?P<locale>[a-z]{2,3}([-_][a-zA-Z]{2}|))$/', $query['lang'])) {
Locale::setDefault(Locale::canonicalize($query['lang']));
if (isset($cookies['lang'])) {
setcookie('lang', FALSE, NULL, NULL, NULL, (!empty($server['HTTPS'])), FALSE);
}
setcookie('lang', Locale::getDefault(), NULL, NULL, NULL, (!empty($server['HTTPS'])), FALSE);
} else if (isset($cookies['lang'])) {
Locale::setDefault(Locale::canonicalize($cookies['lang']));
} else if (isset($server['HTTP_ACCEPT_LANGUAGE']) ) {
$locale = Locale::acceptFromHttp($server['HTTP_ACCEPT_LANGUAGE']);
Locale::setDefault(Locale::canonicalize($locale));
} else {
Locale::setDefault('en_US');
}
return $delegate->process($request->withAttribute(self::LOCALIZATION_ATTRIBUTE, Locale::getDefault()));
}
}
Extension
<?php
namespace App\Extension;
use League\Plates\Engine;
use League\Plates\Extension\ExtensionInterface;
use Zend\I18n\Translator\Translator;
class TranslateExtension implements ExtensionInterface
{
private $translator;
public function __construct(Translator $translator) {
$this->translator = $translator;
}
public function register(Engine $engine)
{
$engine->registerFunction('translate', [$this, 'generateTranslate']);
}
public function generateTranslate(string $var) : string
{
return $this->translator->translate($var, 'my-application');
}
}
Extension factory
<?php
namespace App\Extension\Factory;
use App\Extension\TranslateExtension;
use App\Middleware\LocalizationMiddleware;
use Psr\Container\ContainerInterface;
use Zend\I18n\Translator\Translator;
class TranslateFactory
{
public function __invoke(ContainerInterface $container)
{
$translator = new Translator();
$translator->addTranslationFilePattern('gettext', '../locale', '%s/my-application.mo', 'my-application');
return new TranslateExtension($translator);
}
}
Configuration
Edit config/templates.global.php
:
<?php
use Zend\Expressive\Plates\PlatesRendererFactory;
use Zend\Expressive\Template\TemplateRendererInterface;
return [
'dependencies' => [
'factories' => [
TemplateRendererInterface::class => PlatesRendererFactory::class,
App\Extension\TranslateExtension::class => App\Extension\Factory\TranslateFactory::class,
],
],
'templates' => [
'extension' => 'phtml',
],
'plates' => [
'extensions' => [
App\Extension\TranslateExtension::class,
],
]
];
Add the middleware in config/pipelines.php
:
$app->pipe(App\Middleware\LocalizationMiddleware::class);
You can now use $this->translate()
in your Plates templates 