Integration of I18n function in Plates templates

Hello everyone,

I followed this cookbook ( and it works just fine to define the locale !

But I’m struggling to use the I18n functions inside my Plates templates. Now my locale is defined correctly, I have absolutely no idea how to translate the strings that are in my templates.

I tried to find documentation about that integration but couldn’t find any…
Can someone help me with that ?

Thanks a lot ! :slight_smile:

Anyone has a suggestion on how do this ?

Thanks :slight_smile:

Here is my solution :



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'])) {

      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'])) {
    } else if (isset($server['HTTP_ACCEPT_LANGUAGE']) ) {
      $locale = Locale::acceptFromHttp($server['HTTP_ACCEPT_LANGUAGE']);
    } else {

    return $delegate->process($request->withAttribute(self::LOCALIZATION_ATTRIBUTE, Locale::getDefault()));



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


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');

    return new TranslateExtension($translator);


Edit config/ :


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' => [

Add the middleware in config/pipelines.php :


You can now use $this->translate() in your Plates templates :tada: