Chris Hartjes writes a very nice article about how to make (re)usable zend_forms; After searching around online for some examples of building simple forms, I was dismayed to discover there were two different ways of building the form. I could (a) do it the long way and create specific instances of the form elements using Zend_Form_Element_X or (b) do it the short way and add them to the form by use of Zend_Form::addElement() and pass it the type of form element I want via an array. For reasons I cannot explain initially, I decided to do things the long way. Later on, I found out that doing it this way saved me from rewriting.
Via: Creating Usable Forms With Zend Framework.
How to make POEdit detect source strings in Zend Framework
You will notice that once you have started translating an application using poedit it’s quite a smooth process, what hampers the experience a little bit is the mutitude of ways you can write code in Zend Framework, this is great in every way for developers, but requires a bit of thinking when you need to also translate all the UI strings.
So how do we make poedit detect the strings while making our code pretty?
(And guys PLEASE comment on this article with your own hints, tips & quirks!)
For example;
This is a simple login form using Zend_Form;
Zend_Form is completely Zend_Translate i18n compatable, and will read in all strings from your translation sources without the use of specific $this->translate() calls, which makes the code ALOT prettier, see below;
class Form_Login extends Zend_Form {
public function init() {
$this->setAttrib('id', 'LoginForm');
$this->addElement('text', 'username', array(
'label' => $this->getView()->translate('Username'),
'description' => $this->getView()->translate('Please enter valid username'),
));
$this->addElement('password', 'password', array(
'label' => $this->getView()->translate('Password'),
'description' => $this->getView()->translate('Please enter valid password'),
));
$this->addElement('submit', 'submit', array(
'label' => $this->getView()->translate('Login'),
));
}
}
Is the same thing as; but a LOT shorter and cleaner!
class Form_Login extends Zend_Form {
public function init() {
$this->setAttrib('id', 'LoginForm');
$this->addElement('text', 'username', array(
'label' => _('Username'),
'description' => _('Please enter valid username'),
));
$this->addElement('password', 'password', array(
'label' => _('Password'),
'description' => _('Please enter valid password'),
));
$this->addElement('submit', 'submit', array(
'label' => _('Login'),
));
}
}
Both are caught by the poedit keywords scanner that looks for translate() as well as the translate helper shotcode _().
Some notes (And I’ll keep this section updated while I find more tips & hints and quirks!)
But! It always seem to be a But in there;
These two are NOT the same!
translate("Welcome %s, your last login was %s",$this->user['name'],$this->user['active']); ?>
user['name'],$this->user['active']); ?>
The second one explodes with; “Warning: _() expects exactly 1 parameter, 3 given”
That tells us that;
or even (if you have short tag mode on;
= _('Logout'); ?>
should be ok to use. except that it’s not producing the translated output in an view.phtml or layout.phtml. so we are forced to use;
translate('Logout'); ?>
Bootstrap Zend_Translate
A recurring problem for site developers is implementing a solid way to create and maintain multilingual sites, this article series is my feeble attempt to guide you through how to quickly implement the Zend_Translate in an Zend Framework 1.9.x site.
The procedures and best practices for this is unfortunately like training a dog, everyone has a different way of doing it and an opinion, so the methods and code I show here are taken out of applications that are running in production so if you have a better way of doing it please feel free to comment!.
I usually use poedit a gettext editor which is available for most platforms to create my translation files, and after some initial configuration of the catalog paths so it can see your source files please see Part 1 of this article series.
The bootstrap below looks for the language specific gettext .mo files in /application/languages/ for example /application/languages/sv_SE.mo
Bootstrap.php
protected function _initTranslate() {
// We use the Swedish locale as an example
$locale = new Zend_Locale('sv_SE');
Zend_Registry::set('Zend_Locale', $locale);
// Create Session block and save the locale
$session = new Zend_Session_Namespace('session');
$langLocale = isset($session->lang) ? $session->lang : $locale;
// Set up and load the translations (all of them!)
$translate = new Zend_Translate('gettext', APPLICATION_PATH . DIRECTORY_SEPARATOR .'languages', $langLocale,
array('disableNotices' => true));
//$translate->setLocale($langLocale); // Use this if you only want to load the translation matching current locale, experiment.
// Save it for later
$registry = Zend_Registry::getInstance();
$registry->set('Zend_Translate', $translate);
}
Now when you use statements like
in your layout.phtml or view.phtml files it will be picked up by poedit and you will be presented with a string “Contact Admin” to translate, in my case i’ll just enter “Kontakta Administratören”.
translate('Contact Admin'); ?>
There is some debate on what to put in the translate strings as identifiers, I personaly prefer the actual term to translate in a base language, in this case English instead of some convoluted “IDS0001” type strings.
Poedit will keep track of changes, i.e if I would change the “Contact Admin” to “Contact us” it will tell you on synchronization that “Contact Admin” disappeared and a new translation is required for “Contact us”. It’s quite easy to send those strings to your translators.
Thats it for today.