Welcome to Abdul Malik Ikhsan's Blog

Zend Framework 2 : Translate ZF2 form label and value using translatorTextDomain

Posted in Tutorial PHP, Zend Framework 2 by samsonasik on September 22, 2014

zf2-zendframework2When you work with ZF2 Form, you can translate the form element label and element value by specify translatorTextDomain. It can be applied globally on Module class so all form will be applied with its translation.
For example, We have structure of our translation like this :
zf2-form-label-translation

We can create a translation file then

<?php

return array(
    'Address' => 'Alamat', // for label "Address"
    'Create'  => 'Buat',   // for Submit value "Create" 
);

Now, let’s configure the translator in the module.config.php

return array(
    // .. other array config here

    'translator' => array(
        'locale' => 'id',
        'translation_file_patterns' => array(
            array(
                'type' => 'phpArray',
                'base_dir' => 'vendor/zendframework/zendframework/resources/languages',
                'pattern' => '%s/Zend_Captcha.php',
                'text_domain' => 'formvalidation',
            ),
            array(
                'type' => 'phpArray',
                'base_dir' => 'vendor/zendframework/zendframework/resources/languages',
                'pattern' => '%s/Zend_Validate.php',
                'text_domain' => 'formvalidation',
            ),
            
            // for label and value that we define ourself ...
            array(
                'type'     => 'phpArray',
                'base_dir' => __DIR__ . '/../translation',
                'pattern' => '%s/site.php',
                'text_domain' => 'myformlabelandvalue',
            ), 
        ),
    ),
    
    // ...
);

Ok, so, we then can create a form for that demo :

namespace TranslationSample\Form;

use Zend\Form\Form;
use Zend\InputFilter\InputFilterProviderInterface;

class SampleForm extends Form implements InputFilterProviderInterface
{
    public function __construct()
    {
        parent::__construct('sampleform');
    }
    
    public function init()
    {
        $this->add(array(
            'name' => 'address',
            'type' => 'Textarea',
            'options' => array(
                'label' => 'Address',
            ),
        ));
        
        $this->add(array(
            'type' => 'Submit',
            'name' => 'create',
            'attributes' => array(
                'value'    => 'Create',
                'class'    => 'btn btn-success',
            ),
        ));
    }
    
    public function getInputFilterSpecification()
    {
        return array(
            array(
                'name' => 'address',
                'required' => true,
                'validators' => array(

                    array(
                        'name'    => 'StringLength',
                        'options' => array(
                            'min'      => 6,
                            'max'      => 200,
                        ),
                    ),
                    
                ),
            ),
        );
    }
}

The above setup need to be fired at Module::onBootstrap :

namespace TranslationSample;

use Zend\Mvc\MvcEvent;
use Zend\Validator\AbstractValidator;

class Module
{
    public function onBootstrap(MvcEvent $event)
    {
        $application    = $event->getApplication();
        $serviceManager = $application->getServiceManager();
        $translator     = $serviceManager->get('translator');
        // for validation
        AbstractValidator::setDefaultTranslator($translator, 'formvalidation'); 
        // for form element label and value
        $serviceManager->get('ViewHelperManager')
                       ->get('formcollection')
                       ->setTranslatorTextDomain('myformlabelandvalue');
    }

    // ...
}

So, when $this->formCollection($form); is called :

$form = $this->form;
$form->prepare();

echo $this->form()->openTag($form);
echo $this->formCollection($form);
echo $this->form()->closeTag();

then the label and value will use the translatortextdomain registered like this :

formcollection-zf2-translate

If you use formLabel or formRow individually, you can apply the translatorTextDomain into it.

I uploaded the full code at my github account : https://github.com/samsonasik/TranslationSample .

NOTE : based on feedback by Manuel Stosic, we can do this for specific resource in view like :

$this->formLabel()->setTranslatorTextDomain('myformlabelandvalue');
$this->formInput()->setTranslatorTextDomain('myformlabelandvalue');
$this->formButton()->setTranslatorTextDomain('myformlabelandvalue');

References :
1. https://gist.github.com/stefanotorresi/13da4d2c8e486927a2f8
2. https://github.com/zendframework/zf2/issues/5826

Advertisements

5 Responses

Subscribe to comments with RSS.

  1. Manuel Stosic (@manuakasam) said, on September 22, 2014 at 12:25 am

    Setting the TTD like this is not advisable. Other modules could do the same and then the later one goes in. While it may be less handy, setting the TTD inside the view like
    $this->formLabel()->setTranslatorTextDomain()
    $this->formInput()->setTranslatorTextDomain()
    $this->formButton()->setTranslatorTextDomain()
    should be fail-safe.

    • samsonasik said, on September 22, 2014 at 12:38 am

      Thank you, yes, that would be good for setting up specific module or resource. It just a quick and dirty how we can apply into all modules that uses translation.

  2. Alejandro Celaya said, on September 22, 2014 at 12:55 am

    Very handy.

  3. mikemix said, on January 12, 2015 at 12:56 am

    Why not just register formCollection plugin which would override the default one? Sounds like a better idea than spamming the onBoostrap method.

    • samsonasik said, on January 12, 2015 at 2:13 am

      Yes, we can do that ;). There are many way to do one thing. And this is for quick and dirty ;).


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: