Mittwoch, 20. Juli 2016

ZF2 form validator translation

Zend Framework brings own translations with it. As of ZF 2.4 there are translations for Zend_Captcha and Zend_Validator. I wanted to use the latter in most easy way possible, without any hard magic or too much additional coding.

One possibility would have been adding the translations to module.config.php right after the inclusion of mo files, which are there by default with the Zend Skeleton Application.

    'translator' => array(
        'locale' => 'en_US',
        'translation_file_patterns' => array(
            array(
                'type'     => 'gettext',
                'base_dir' => __DIR__ . '/../language',
                'pattern'  => '%s.mo',
            ),
        ),
    ),

I decided to go with small modification of my  Module.php where only few lines have to be added.

<?php

namespace Application;

/* all your other use imports */
use Zend\Validator\AbstractValidator;

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        /* all your other function logic*

        // Dynamically adding translation files, which are bundled with ZF. (Zend_Captcha + Zend_Validate)
        // Caveats:
        // - Path to files could change in future releases, so this should be checked adjusted accordingly, when upgrading.
        // - No (expensive) file checking is done and if the file doesn't exist, an error message could be thrown, when translator tries to include inexistent file.
        $translator = $e->getApplication()->getServiceManager()->get('translator');
        $localePrimary = \Locale::getPrimaryLanguage($translator->getLocale());
        $translator->addTranslationFile(
            'phpArray',
            './vendor/zendframework/zendframework/resources/languages/' . $localePrimary . '/Zend_Captcha.php',
            'default',
            $translator->getLocale()
        );
        $translator->addTranslationFile(
            'phpArray',
            './vendor/zendframework/zendframework/resources/languages/' . $localePrimary . '/Zend_Validate.php',
            'default',
            $translator->getLocale()
        );
        AbstractValidator::setDefaultTranslator($translator);
    }

    /* all your other functions */
}

This is enough and the Zend translation files will be loaded by the translator object. It's also important to set it as default translator to all validators with the last lines, so all instantiated implementations will use the correct language from the beginning. The paths are correct for ZF 2.4, for any other releases they might be different and would need to be adjusted accordingly. I use Locale::getPrimaryLanguage to extract just the two letter locale code used by Zend translation files. This way you could work properly without any special with multiple sublocales like en_US and en_GB, de_DE and de_AT simultaneously without any additional hacks.

If you are already using Zend\Cache with translator, don't be as dumb as me and flush the cache, else you'll search for a long time for the reason of the code to seemingly not work. :D


You don't have to do anything for multilingual sites when using Zend\Cache though. Translator caches every language with different key on the first use, if it doesn't find it in cache. So you would only have to flush the cache, if you change something in your translations. There is no concurrency problem with multiple languages in use.

Keine Kommentare:

Kommentar veröffentlichen