Zend Framework View Helper not available in module when using layout - php

I'm starting to work with zend framework 1.12 and I ran into a little problem which I don't seem to be able to fix.
Up untill now i've done everything in the application, but now I want to build a module that handles all stuff that is related to settings.
Therefor i've created a new module and added a controller into it. This module automatically takes the layout from the application, which is what I want.
In this layout I use a view helper which works when I load a controller/action that is in the application folder. But when I try to load the layout around my controller inside my module the view helper is not available.
I hope I'm making sense and I would appreciate your help on this one!
Cheers!

If I understand you correctly you need to setup your view helper path in the bootstrap or application.ini, I do it in bootstrap:
protected function _initView()
{
//Initialize view
$view = new Zend_View();
//add custom view helper path
$view->addHelperPath('/../library/Namespace/View/Helper');
//do more stuff if needed
//add it to the view renderer
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer');
$viewRenderer->setView($view);
//Return it, so that it can be stored by the bootstrap
return $view;
}
also make sure your module includes it's own bootstrap file, this makes it possible to load resources to the module:
//at /application/modules/module/bootstrap.php
class Module_Bootstrap extends Zend_Application_Module_Bootstrap
{
//just an empty class is enough
}
hope this helps

Related

ZF2 conflicts layout with same name

I'm trying the framework ZF2 and I try to do very independant modules like bundles in SF2.
I've got ZfcTwig to have Twig to render my views. This worked until I've created a second module.
-Application (default module)
-Admin
-view
index.twig
-layout
base.twig
-Blog
-view
index.twig
-layout
base.twig
The problem is that my Blog layout extend the Admin base layout then !
I've done my structure layout based on http://blog.evan.pro/module-specific-layouts-in-zend-framework-2
So in both Module.php I've this:
public function init($moduleManager)
{
$sharedEvents = $moduleManager->getEventManager()->getSharedManager();
$sharedEvents->attach(__NAMESPACE__, 'dispatch', function($e) {
$controller = $e->getTarget();
$controller->layout('layout/base.twig');
}, 100);
}
Plus I don't understand why I've to define twice the layout, one time in the init function of Module.php, the second on extend function of twig views.
For sure its work if I've different names.
And I see for this module: https://github.com/EvanDotPro/EdpModuleLayouts
But I think it should be possible without this to have really independant module since its the philosophy of the framework.
By default, ZfcTwig works in "zf way", using the two-step view pattern.
If you want to use the original twig system (for extends), you must specify it in your config file.
It is well commented :
/**
* If set to true disables ZF's notion of parent/child layouts in favor of
* Twig's inheritance model.
*/
'disable_zf_model' => true,
This way, you will control yous layouts with extends instructions.

Embed Yii module page in Facebook app

I've created Yii quiz module which I also want to use in Facebook app (Facebook side).
It can be done trough iframe, but generated page have got also menus and many other unnecessary (in this case) stuff. Is it possible in Yii to show only generated module code without rest of the website?
Try and use a different layout for that module. First you can add a layout folder and layout files to that module, say : /protected/modules/quiz/views/layouts/quizlayout.php. So this new quizlayout.php should be your layout for all the views in this module.
To do that you can set the layout property of the quizmodule in the QuizModule class's init(), like so (in QuizModule.php):
class QuizModule extends CWebModule {
public function init() {
// this method is called when the module is being created
// you may place code here to customize the module or the application
// import the module-level models and components
$this->setImport(array(
'quiz.models.*',
'quiz.components.*',
));
$this->layout='quizlayout';
}
//...
}
Now by default, gii generated modules' controllers are subclasses of the Controller class in component/Controller.php file. And that Controller class defines a layout, so if you have that same structure, then the above method will not work, and you'll have to override the layout within your modules' controllers. However instead of going inside each controller and adding a line, you can instead do this in the beforeControllerAction($controller, $action) function in QuizModule.php :
public function beforeControllerAction($controller, $action) {
if(parent::beforeControllerAction($controller, $action)) {
// this method is called before any module controller action is performed
// you may place customized code here
$controller->layout='quizlayout';
return true;
}
else
return false;
}
Edit:
Of course your quizlayout.php should not have code for menus, and any extra stuff, but at the very least the echo $content line should be there, as also mentioned in eskimo's answer.
In you protected/views there is a file called "main.php"
This is your main layout file, that gets rendered around any view called by $this->render
To remove the menu etc.. remove everything within the body except for the line:
<?php echo $content; ?>
Obviously leave in all the stuff in the head (.css files etc...)

How to call a method in Zend_Controller_Action in all controllers Application Wide

I am new to Zend Framework. 1st things 1st, I want to change that .phtml extention to .php in the views.
After researching, I found that this code works, in the init method of different controllers:
$this->getHelper('viewRenderer')->setViewSuffix('php');
Problem is that I have to repeat that code in every controller, which is something bad and defeats the purpose of using a framework.
I could have subclassed the Zend_Controller_Action into some base controller with all the shared code which all other controllers can inherit from, but as far as I know, it's not the best practice to do.
How can I achieve the shared code without subclassing the Zend_Controller_Action class and without using any plugins or Action helpers
Thanks in advance.
Just figured it out..No need for any base controllers.
In the bootstap, I wrote this code:
protected function _initViewSuffix() {
$this->bootstrap('View');
$view = $this->getResource('View');
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
$viewRenderer->setViewSuffix('php');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
}
And then in Application.ini, I added this line:
resources.view = []
Now it works.

What is the cleanest way to retrieve a list of application resources across modules?

First, some context:
I am currently working on a modular Zend Framework application using Zend_Application. I wrote a custom module bootstrap that inserts custom resources into the Module Resource Autoloader, for example a 'Widget' resource.
Now, assuming the following structure:
/application
/application/modules/foo/widget/Bar.php
/application/modules/baz/widget/Qux.php
How would I be able to retrieve a list of every available widget in my application, preferably without traversing my entire directory structure?
Unfortunately I don't think there's a perfect solution to this. The best way I think is to have a standard way of 'registering' widgets in the respective module bootstraps, similar to how module-specific view helpers work.
Create a class for managing widgets which you instantiate in your main application bootstrap:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initWidgets()
{
return new Yourapp_Widgets();
}
}
and then in each module:
class Foo_Boostrap extends Zend_Application_Module_Bootstrap
{
protected function _initWidgets()
{
$widgetManager = $this->getApplication()->getResource('widgets');
$widgetManager->registerWidget('Foo_Bar');
}
}
you could then have a method on the widget manager class to return all registered widgets.

Zend Framework Widget Tutorial question

I try to follow this tutorial, but I can't get it to work:
http://weierophinney.net/matthew/archives/246-Using-Action-Helpers-To-Implement-Re-Usable-Widgets.html
I did everything as described, but I don't know how to make it available in my controllers. My filesystem looks like this:
- application
- controllers
- IndexController.php
- modules
- user
- configs
user.ini
- controllers
- forms
Login.php
- helpers
HandleLogin.php
- views
- scripts
login.phmtl
profile.phtml
Bootstrap.php
- views
How do I use the HandleLogin Helper in my IndexController? I really have no idea and I'm looking an trying for more then a day and I almost want to throw my PC out of the window ;). So any help would be appreciated!
Looks like the widget plugin is not called anywhere.
Few things to check:
Do you have a Bootstrap.php file for the module?
Does this bootstrap file has _initWidgets() method?
Does this method call:
$widget = new Module_Widget_Name; // is it callable?
Zend_Controller_Action_HelperBroker::addHelper($widget);
Have you registered widget resource?
public function _initResourceLoader()
{
$loader = $this->getResourceLoader();
$loader->addResourceType('helper', 'helpers', 'Helper');
$loader->addResourceType('widget', 'widgets', 'Widget');
return $loader;
}
Does application.ini contains resources.modules[] = line?
You dont. The point of the tutorial is to create a reusable widget that runs independent from any specific controllers. When the application receives a request, it will run through it's dispatch cycle and trigger the action helper on preDispatch automatically:
Now, let's look at the action helper itself. As a reminder, action helpers can define hooks for init() (invoked by the helper broker each time it is passed to a new controller), preDispatch() (invoked prior to executing the controller's preDispatch() hook and executing the action itself), and postDispatch() (executed after the action and the controller's postDispatch() routine).
The helper will fetch the current controller (whichever that may be for that request) to get the View instance and configure it with the form

Categories