Tuesday, May 3, 2011

How do I Extend Zend View to Implement a Concrete Function?

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!

From stackoverflow
  • 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!");
    
    MegaHAL : 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.
  • If configured properly Poedit can automatically extract strings from functions other than _().

    MegaHAL : Yes, you're quite right - but I still want to expose a concrete helper function to all views. Is it even possible?
  • 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().

    MegaHAL : Thanks, I believe that's exactly what I want.
  • 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?

    MegaHAL : 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.
    gaoshan88 : 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.

0 comments:

Post a Comment