What is the preferred method of localization in Zend 2? - localization

I am looking for a tutorial on the preferred method of handling localization in Zend 2, but so far I haven't been able to find any. The best I could find is this page, which doesn't explain the practical process of implementing localization (specifically, application messages) in detail, or this question, which was asked before the release of Zend 2 and is now outdated.
If given a choice presented on that page, say I pick GNU Gettext as a translation format. Is there any tutorial on localizing a ZF2 application in that case?
Or, say I store the text of the pages on my site in a database table, for example
CREATE TABLE `page` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`body` blob,
`locale` int(11) NOT NULL,
`creator` int(11) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `pagecreatorfk_idx` (`creator`),
CONSTRAINT `pagecreatorfk` FOREIGN KEY (`creator`)
REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
How would I go with providing localized messages then?

Alright, for starters you'll need a translation program such as http://www.poedit.net/
Here is how I have my setup:
In your Module folder create another folder called "language".
Open your module.config.php and add the following:
'translator' => array(
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
'text_domain' => 'account'
)
)
)
What makes things easy for me is to create a language.php file and add lines like this:
echo _('text_to_translate_here');
When you configure your PoEdit you'll scan this file which will add the translation id's to PoEdit. Now you can add the real text that you want to be displayed and upon save it will output 2 files like account.mo and account.po. The only file you need to upload to your language folder is the account.mo
Since I use translations all over my application I've added the factory to my global.php file:
return array(
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
)
)
);
In my view.phtml file I'll now be able translate:
<?php echo $this->translate('text_to_translate_here', 'account'); ?>
Now if you don't want to use textdomains as I have shown in my example of the module.config.php then all translations will by default use the "default" textdomain. So you could do this instead:
<?php echo $this->translate('text_to_translate_here'); ?>
This will also work for FormLabels: (This will output Priroity as the label name)
<?php echo $this->formLabel($this->form->get('prio')); ?>
If you want to translate Form objects using a textdomain other than "default" then you could add this to your view.phtml
$this->formSubmit()->setTranslatorTextDomain('account');
Now your Submit FormLabels will use that textdomain instead of the default textdomain. The same goes for any other type of Form Object. Just replace formSubmit with the element type.
Let me know if this helps out or if I'm missing anything.

Related

How do I change the view path at runtime

In my ZF2 app I want to change the Template directory at runtime.
The default path is set in module.config.php:
'template_path_stack' => array(
__DIR__ . '/../view',
),
I would like to change that to the equivalent of
'template_path_stack' => array(
__DIR__ . '/../view-alternate',
),
at runtime, so I can dynamically change the theme of the page based on the user preference which is stored in the DB.
Template name resolving is a heavy process. It is better to provide the template name manually.
I recommend you to use 'template_map' instead of 'template_path_stack'. You can create some kind of naming convention to differentiate between the two themes, it can be a prefix that you can manage dynamically.
There is a tool to transform the stack into a template map: https://github.com/zendframework/zf2/blob/master/bin/templatemap_generator.php
The solution I ended up with is to use https://github.com/ZendExperts/ZeTheme.
Combined with the option too save the theme in the session I was able to change the theme because it's not at runtime. A page reload was necessary.
It's a workaround. Not the answer.

Typo3 Fluid detect Links in Text

This Code is showing a Textarea Input from the Backend in my Frontend:
<f:format.nl2br>{data.textfield}</f:format.nl2br>
Its possible there are Links in it as simple text for example:
http://www.example.com
Is it possible somehow to detect those links and wrap a linktag around it with Typo3 6 and Fluid?
Its rather easy in Javascript but if possible I prefer a Typo3/Fluid solution here.
why dont you use the RTE for your Textfield in the Backend and render it in Fluid with
<f:format.html>{data.textfield}</f:format.html>
If you do it like this, you have your line breaks rendered and all the Links, too. You enable the RTE features in your TCA-Configuration:
'textarea' => array(
'exclude' => 0,
'label' => 'your_label_from_locallang.xlf',
'config' => array(
'type' => 'text',
'cols' => 40,
'rows' => 15
),
'defaultExtras' => 'richtext[]'
),
Is the fluid used in context of an extension? If so make the check on php side and bind a boolean value to the view. You can then use something like this:
<f:if condition="isLink">
<f:then>
<f:link.external uri="{data.textfield}" target="_blank">{data.textfield}</f:link.external>
</f:then>
<f:else>
<f:format.nl2br>{data.textfield}</f:format.nl2br>
</f:else>
</f:if>
Unfortunately condition is very limited in what it can check on fluid side only so this won't help if you can't use php.
Another possibility would be to create a ViewHelper for that.

How do I use shared view script paths for partials in Zend Framework 2?

I'm using Zend Framework 2 (v2.1.4) and I have a partials template that I want to use in several Modules. According to the documentation I can access partials in other Modules, but
That said, it’s likely a better practice to put re-usable partials in shared view script paths.
This sounds like a good idea, but I can't find any documentation on this "share view script path". Where do I find it, and when I've set it, how do I tell the partial() helper to use them?
In your module.config.php
'view_manager' => array(
'template_path_stack' => array(
'mymodule' => __DIR__ . '/../view',
),
'template_map' => array(
'snippets/mypartial' => __DIR__ . '/../view/snippets/mypartial.phtml',
),
),
And use like that
<?php echo $this->partial("snippets/mypartial"); ?>

Translate Form Error Messages

I've been using ZF2 since alpha so I'm not entirely new. However not to disturb my current project I setup a new SkeletonApp and it's working. I've added my Translations I needed for both English and German and they are working as expected. However, the Form Error Messages are not being translated to German, or any other language.
I've read the manual but it only covers how to setup Translations based on Factories and it has no details regarding how to set up inside of the module.config.php. Just like in ZF1, ZF2 also have a resources/languages folder which contains all the Form Validation Error Messages already translated. I'd like to use those! And this is where my problem is. I have no idea how to add the configuration to make this work with all my forms.
In my module.config.php file based on the SkeletonApp it already had support for translations, so I took that configuration and added another array, assuming this would have worked.
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo'
),
array(
'type' => 'phparray',
'base_dir' => __DIR__ . '/../resources/languages',
'pattern' => '%s.php'
)
)
),
However to no avail has this worked. In my Controller I have an eventManager which is where I set my locale like this:
$self->getServiceLocator()->get('translator')->setLocale('en_US'); // change to de_DE for German
Doing this as I mentioned above does translate my text from English to German and so on.
What am I missing to make my Form Errors Translate? Thank you for any guidance you can share on this situation.
Both sources use the same text domain, with the gettext source having the higher priority. This means that it will load your locale from the gettext source and then stop, since the locale + text domain combination is already loaded.
Solution: Use different text domains for each source.

How to use subforms in Zend Framework2

Is there a way how I can use zend subforms in Zend Framework2. When I did a search in the internet I have landed upon many examples showing how to use zend subforms but using Zend Framework1.
In case if somebody has a link/example where one can go through a basic example, would be great.
Any information is appreciated.
Because Zend\Form is tree structure, you could add another form into your form with a form name. Such like this:
$form = new \Zend\Form\Form();
$form->add(array(
'name' => 'username',
'type' => 'Zend\Form\Element\Text',
));
$subForm = new \Zend\Form\Form();
$subForm->setName('subform');
$subForm->add(array(
'name' => 'email',
'type' => 'Zend\Form\Element\Text',
));
$form->add($subForm);
$form->prepare();
$helper = new Zend\Form\View\Helper\FormText();
echo $helper($form->get('username')); //<input type="text" name="username" value="">
echo $helper($form->get('subform')->get('email')); //<input type="text" name="subform[email]" value="">
Notice that the "subform" input name will be add form name as prefix automatic.
I've been using it for a few hours, and in my understanding, zf1 subforms funcionalities are solved in zf2 by using nested fieldsets.
\Zend\Form\Fieldset is also the parent class of \Zend\Form\Form.
The previous answer seems correct to me, but if you prefer to keep forms and subforms in separate classes, read this:
http://zf2.readthedocs.org/en/latest/modules/zend.form.collections.html
Ignore the entity and hydration stuff if you are not interested for now, and look at CreateProduct class, it's a form that uses the FieldSet ProductFieldset as a subform. At rendering time, subform fields will be named like
<input ...name="product[el1]" ... >
(where product is the name of the subform).
And $form->getData() will return
array('product'=>array(...))
Note: you need to call $form->prepare(); before rendering, or the nesting won't be processed.

Resources