views:

679

answers:

4

I want to make it as easy as possible for our designers to localise strings in views, which means that I want to do this:

...
<p><?php echo $this->_("Hello, world!"); ?></p>
...

The underscore notation here is necessary to allow Poedit to automagically extract all strings for localisation. The implementation is trivial:

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

At the moment, I've put this directly in Zend_View_Abstract, which is bad (I don't want to do this by modifying any of the Zend library). Ideally, then, I'd extend Zend_View_Abstract to allow me to implement other concrete functions that we require, but I don't know how to set this up. An alternative might be to implement a View Helper, but the only way that I know how to do this makes the code in the view more verbose. Any pointers (no, not those kind) would be much appreciated. Thanks!

+1  A: 

I think that you're looking for a way to create custom view helpers.

Example:

class My_View_Helper extends Zend_View_Helper_Abstract
{
    public function translate($string)
    {
        //...
    }
}

...

$view->setHelperPath('/path/to/helpers', 'My_View_Helper');

...

Then in your views you can use it:

echo $this->translate("Hello, World!");
CMS
I don't want to use a helper, because there doesn't seem to be any way for me to implement a function named "_" in a helper, due to the requirements of class naming and file naming (mentioned in the documentation you linked to). As I said in my question, the underscore notation is important, both for terseness, consistency with gettext, and Poedit automagic string extraction.
MegaHAL
A: 

If configured properly Poedit can automatically extract strings from functions other than _().

Alix Axel
Yes, you're quite right - but I still want to expose a concrete helper function to all views. Is it even possible?
MegaHAL
+1  A: 

Although I think that using view helpers would be the correct "Zend-Framework"-way of doing this, you can extend Zend_View and implement all additional methods you'd like to have - this way you don't loose the features of Zend_View.

class My_View extends Zend_View
{
    public function _($string)
    {
        return Zend_Registry::get('Zend_Translate')->_($string);
    }
}

You then only have to make sure that your new view class is instantiated and registered as the default view in the controller (setting the Zend_Controller_Action::$view instance variable to an instance of your class) and in your Zend_Layout (when using layouts; passing your view as a config option with key view) when not using the ViewRenderer or in the ViewRenderer when using the ViewRenderer using Zend_Controller_Action_Helper_ViewRenderer::setView().

Stefan Gehrig
Thanks, I believe that's exactly what I want.
MegaHAL
+3  A: 

Obviously ignore my paths for your own...

  1. Extend Zend_View
  2. Put your method in this extended class
  3. Instantiate the class (in your bootstrap for instance)
  4. Assign it to the ViewRenderer
  5. Pass that viewrenderer to Zend_Controller_Action_HelperBroker's addHelper method
  6. Use it in your view

In /library/MegaHAL/Zend/ create View.php:

class MegaHAL_Zend_View extends Zend_View
{
    public function _($string)
    {
    return Zend_Registry::get('translate')->_($string);
    }
}

In your bootstrap:

require_once APPLICATION_PATH.'../library/MegaHAL/Zend/View.php';

$view = new MegaHAL_Zend_View();

$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

In your view:

<p><?php echo $this->_("Hello");?></p>

I believe that will do what you want, yes?

gaoshan88
Works a treat - thanks for your help. I'm accepting this over other answers because it's more step-by-step, and specific to my problem with ViewRenderer.
MegaHAL
No problem, glad to help. I tend to prefer more detailed explanations because the "one, two skip a few" type of instructions, like in the Zend Framework documentation, always seem to end up leaving out that one, tiny little nugget that ties it all together... drives me nuts.
gaoshan88