zf3-twig-trans
, (*1)
Magic glue to create the expected experience when developing with ZfcTwig, the MvcTranslator (e.g., from within your controllers), and your twig templates using a custom {% trans %} that this module provides. Usage is very simple! With this package included, "trans" becomes available in your templates., (*2)
New! This module supports text domains!, (*3)
Inspired by ZfcTwig and its extensions project at https://github.com/twigphp/Twig-extensions, (*4)
Requirements
Item |
Version |
PHP |
7+ |
Zend Framework |
3.* |
Gettext PHP Module |
* |
Installation
composer require "saeven/zf3-twig-trans"
Configuration
Loading the module: application.config.php
In your module's application.config.php, make sure you've got these modules loaded:, (*5)
'ZfcTwig',
'CirclicalTwigTrans'
By loading CirclicalTwigTrans, you will be setting an alias from 'translator' to 'MvcTranslator'. If you have an existing translator alias in your system, please remove it., (*6)
Managing Locale: Your Application's Module.php
It's assumed that you are managing locale in your app's bootstrap. For example, in your Application module's onBootstrap:, (*7)
public function onBootstrap(MvcEvent $e)
{
$translator = $e->getApplication()->getServiceManager()->get('translator');
$translator
->setLocale( 'fr_CA' )
->setFallbackLocale( 'en_US' );
}
Proper Language File Setup
gettext imposes a certain file structure; language folders for a module would look like so:, (*8)
module/
Application/
language/
en_US/
LC_MESSAGES/
default.mo
default.po
errors.mo
errors.po
fr_CA/
LC_MESSAGES/
default.mo
default.po
errors.mo
errors.po
The .mo files are truly the ones that matter. The .po files, are the source files that are used to compile the .mo files with msgfmt., (*9)
The nomenclature, default.mo, indicates that that file contains text strings for the 'default' text domain. In other words, the name of the files is vital to proper functionality., (*10)
You need to tweak your translator configuration to support this file structure, it's very simple. Per module:, (*11)
'translator' => [
'translation_file_patterns' => [
[
'locale' => 'en_US',
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s/LC_MESSAGES/default.mo',
'text_domain' => 'default',
],
[
'locale' => 'en_US',
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s/LC_MESSAGES/errors.mo',
'text_domain' => 'errors',
],
],
],
Very important: there's a critical difference between Zend's translator implementations, and gettext's implementation. The Zend translator
will allow you to use multiple .mo files for a same domain, but gettext does not support this behavior. To ensure that both the Twig translations, and
your in-app translations (e.g., $translator->translate('foo')
) work properly, your domain names must be unique. A good practice is to name your domain,
after your module., (*12)
Usage
Included tests support all flavors of trans, adding direct support for domain overrides from within the template. These syntax structures all work:, (*13)
Translate 'Sorry' from text-domain 'errors'
{% trans from "errors" %}Sorry{% endtrans %}
Translate 'Home' from the 'default' domain
{% trans %}Home{% endtrans %}
Translate "A 404 error occurred" from the 'default' domain
{% trans "A 404 error occurred" %}
Translate with pluralization from the 'default' domain
{% set birds = 422 %}
{% trans %}
There is one bird
{% plural birds %}
There are {{ birds }} birds
{% endtrans %}
Translate with pluralization from the 'errors' domain
{% set birds = 422 %}
{% trans from "errors" %}
There is one bird
{% plural birds %}
There are {{ birds }} birds
{% endtrans %}
Translate with notes
{% trans %}
Hello User!
This is used in the greeting area.
{% endtrans %}
Controllers
Usage in controllers doesn't change., (*14)
/** @var Laminas\I18n\Translator\Translator $tr */
$tr = $sm->get('translator');
$tr->translate( 'Home' );
$tr->translate( 'Sorry', 'errors' );
$num = 422;
sprintf( $tr->translatePlural( "There is one bird", "There are %d birds", 422 ), $num );
sprintf( $tr->translatePlural( "There is one bird", "There are %d birds", 422, 'errors' ), $num );
You can test it with the ZF3 Skeleton, by translating "Home" to "fr_CA" which becomes "Acceuil" (good test)., (*15)
Enjoy!
Let me know if you find any issues. I use this module as well in production, so definitely want to hunt bugs down!, (*16)