2

I have a view helper being called in my layout that works fine in the default module, but I get an exception when I am in another module.

I have already changed my app.ini to use the default layout across all modules by setting:

resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"

And searching here and google provided me with another app.ini setting to add the view helper path for all modules:

resources.view.helperPath.Zend_View_Helper = APPLICATION_PATH "/views/helpers"

However instead of fixing the problem, that additional setting causes the Zend Exception to become a WSOD.

Without that second app.ini setting, I see the layout and get this exception:

Plugin by name 'AutoScript' was not found in the registry; used paths: Admin_View_Helper_: /Applications/XAMPP/xamppfiles/htdocs/dad/application/modules/admin/views/helpers/ Zend_View_Helper_: Zend/View/Helper/:./views/helpers/

With the helperPath.Zend_View_Helper ini setting I get a WSOD with the following:

Fatal error: Uncaught exception 'Zend_Loader_PluginLoader_Exception' with message 'Plugin by name 'AutoScript' was not found in the registry; used paths: Zend_View_Helper_: Zend/View/Helper/:./views/helpers/' 

It appears the plugin loader is looking in public/views/helpers/ for the AutoScript.php file even though it should be using the APPLICATION_PATH value as a prefix.

My layout invocation looks like this

<?php $this->AutoScript(); ?>

My AutoScript.php file's class is defined in application/views/helpers/

class Zend_View_Helper_AutoScript extends Zend_View_Helper_Abstract {
  public function AutoScript() {...}
}

My current fix is to copy the AutoScript.php file from application/views/helpers into modules/admin/views/helpers which fixes the issue, but duplicates a file. What am I missing? Do I have to add this view helper path programmatically by creating an _initView function in my bootstrap?

1 Answer 1

1

Typically, you would name your custom view helper with your own prefix, not the Zend_ prefix. Beyond that, there are several choices for where to put and name your view helpers.

If this view-helper is really a single-application helper, then I find it natural for it to reside somewhere in the application folder. Within that possibility space, I would ask if the view-helper will be used in a single module or across multiple modules.

If the view-helper is intended for use in a single module, then I depend upon the build-in resource-autoloader mappings and place my view-helper class Mymodule_View_Helper_Myhelper in the file application/modules/mymodule/views/helpers/Myhelper.php.

If the view-helper is intended for use across multiple modules , I might pull it up a little higher than the modules folder, say Application_View_Helper_Myhelper (assuming an appnamespace of Application) stored in application/views/helpers/Myhelper.php. In this case, we need to tell the view that there are helpers with prefix Application_View_Helper_ in that directory. This can be done at bootstrap:

protected function _initViewHelperPaths()
{
    $this->bootstrap('view');
    $view = $this->getResource('view');
    $view->addHelperPath(APPLICATION_PATH . '/views/helpers', 'Application_View_Helper_');
}

Sometimes, you need a view-helper in one module that exists in another module and you cannot - in practical terms - move the original one around. In that case, one workaround is to define an empty shell of a view-helper in your consuming module extending your unmovable view-helper. In file application/mymodule/views/helpers/MyHelper.php:

class Mymodule_View_Helper_Myhelper extends Othermodule_View_Helper_Myhelper
{
}

This way, the code for the helper implementation is not duplicated. The module-specific resource-autoloader mappings will allow all those classes to be found when they invoked as view-helpers from a view-script.

Finally, if this view helper is to be used in multiple projects, then there is an argument for placing it outside of application scope, out in in the library folder. So perhaps a class MyLibrary_View_Helper_Myhelper stored in the file library/MyLibrary/View/Helper/Myhelper.php. As before, you would need to inform the view - probably at bootstrap or in a front-controller plugin - of the prefix/path mapping:

$view->addHelperPath(APPLICATON_PATH . '/../library/MyLibrary/View/Helper', 'MyLibrary_View_Helper_');

Note that in all cases above, the invocation of the view-helper functionality itself - say, inside a view-script - is:

<?php echo $this->myhelper($params) ?>

Note, in particular, the casing difference between the classname and the invocation.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I ran through these scenarios while researching the Zend docs for view helpers across modules. In my case, it was a cross module, application specific view helper I needed to work. I don't know why, but my problem went away without having to add the initViewHelperPaths function to my bootstrap. The difference in case between my classname and helper invocation was due to a suggestion that some (linux) servers don't like the case difference between the class name and helper call.
Yeah, in my experience, most Linux filesystems appear to be case-specific. Even in the absence of that, ZF itself has its own case conventions for the name of the view-helper class and the method name you use in the invocation. Anyway, glad it worked out for you. Cheers!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.