How to make POEdit detect source strings in Zend Framework

This entry is part 3 of 4 in the series Working with Zend_Translate and Poedit

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;

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'); ?>

Series Navigation<< Bootstrap Zend_TranslateBootstrapping Zend_Translate with a LangSelector Plugin >>

10 Replies to “How to make POEdit detect source strings in Zend Framework”

  1. I have tried your example by replacing

    ‘label’ => $this->getView()->translate(‘Username’),

    by

    ‘label’ => _(‘Username’),

    in my code but it generates an error:
    Fatal error: Call to undefined function _()

    Where does your _() function comes from ?

    Thanks.

    1. Hi Ithier,
      What Zend Framework version are you running and are you initializing Zend_Translate in your bootstrap?
      _() is a helper function available with instantiating the Zend_Translate.

  2. Hi Danny,

    Thank you to answer my question.

    I am using the 1.10.1 version.
    I do initialize Zend_Translate but not in my bootstrap but in a routeShutdown function of a controller plugin. I do that because I choose the language from a parameter on the URL (they are like /project/en/controller/…).
    I think that it is correctly installed and configured because if I use the setLabel function then my label is correctly translated.
    But I would like to use your initialization method as I find more readable except that if I have to add this->getView()->translate(‘Username’), to each of my labels then it is no more easier to read !!

  3. Hi Danny,
    i have similar problem “Call to undefined function _()”. I am using ZF 1.10.4. Could you please tell us where is this helper or paste its content here, cause i think i don’t have it in my library :/

  4. ok, i paste this code into bootstrap.php and it works, but i don’t like this soultion, it’s should be some helper or something :/

    function _($string) {
    return Zend_Registry::get(‘Zend_Translate’)->_($string);
    }

  5. _() is available through;
    library/Zend/Translate/Adapter.php: public function _($messageId, $locale = null)

    So why this one dissapears is a bit of a mystery to me.
    How does your _initTranslate (or similar) look in your bootstrap?

  6. Nice tutorial.

    But I’m wondering why are you setting translated labels and descriptions manually in your form. Zend_Form allows you to set a default translator by Zend_Form::setDefaultTranslator($translate); (also zend validate) and all translate magic will happen automaticaly (errors, labels, etc – without descriptions – but see below).

    I thinkt, that nice solution could be extending zend_from class into your own, where you can override default addElement method and set description and label based on field name. And then you have for example: label:login and desc:login.
    unfortunately – automatic search for missing translation’s wont work as well in poedit then.

  7. _() is defined nowhere in the Zend Framework, but is an alias to the PHP function gettext() and is only defined if PHP is compiled with gettext support. If you don’t initialize the PHP gettext support with a translation file, this function does nothing but returns submitted string.

    So, basically, using _() works only if gettext is installed and does nothing at all, so Zend_Form will handle the translations with its built in i18n support.

    I personally love this unobtrusive way to let poedit recognise the strings. If you can’t rely on gettext being installed (which would be pointless since you’re using Zend_Translate) you can put this somewhere in your Bootstrap file (outside of any classes):

    if (!function_exists(‘gettext’)){
    function _($string) {return $string;}
    }

  8. Hi everbody,

    I use .po and .mo files to translate my web pages, but I created the source manually. Then I tried to generate new catalogue by Poedit. But I still got a problem. I set all preferences tabs according to Configuring Poedit for Zend Framework Projects, but there is still a error message appearing -> Poedit didn’t find any files in scanned directories.

    Any hint?

Leave a Reply

Your email address will not be published. Required fields are marked *