I have the following directory structure for my application:
application
modules
default
controllers
models
views
Bootstrap.php
test
controllers
models
views
Bootstrap.php
Below is the code of module specific bootstrap files:
//default/bootstrap.php
class Default_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initMessageDefault(){
echo "called default module's bootstrap file";
}
}
//test/bootstrap.php
class Test_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initMessageTest(){
echo "called test module's bootstrap file";
}
}
Now if I call the default controller I.e. www.domain.com/index I can see following output:
called default module's bootstrap file
called test module's bootstrap file
My question is why the bootstrap file of both the modules is getting called? Shouldn't just the boostrap file of the default module be called when I call the default module?
Is this a bug or am I doing something wrong?
Thanks for your help in advance.
This is intended. Bootstraps are for application initialization, all bootstraps are run on every request.
If you're looking to do something only for the current module what you probably want is a controller plugin. These are also run on every request but you can check the current module in there and then run some custom code.
Related
Can you create more than one controller to override the same Magento core controller?For example, Can I create two modules, in each module, create an AccountController.php to override the Magento's core AccountController in Mage/Customer?
Will it create any conflicts if two modules are depending on the save core module and overriding the same controller, of course each controller will overriding different actions in the core controller.
Yes you can create more than one module that both extend the same core controller.
First you will want to include the core controller then overload only the specific functions you want.
require_once 'Mage/Customer/controllers/AccountController.php';
class Namespace_Module1_AccountController extends Mage_Customer_AccountController
{
public function indexAction(){
//this will overload the index action for the core customer AccountController
}
}
Repeat this with each module you make and only overload the actions you wish to change. For example if you wanted the second module to overload the save action you would do.
require_once 'Mage/Customer/controllers/AccountController.php';
class Namespace_Module2_AccountController extends Mage_Customer_AccountController
{
public function saveAction(){
//this will overload the save action for the core customer AccountController
//this will also leave your index action overload from the other module in place
}
}
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...)
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
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.
The standard extension for template files in Zend Framework is .phtml... I need to change them to .js in one specific module... can anyone help... I'd ideally like to change this a Controller level...
Many thanks...
In your controller:
public function init() {
$this->getHelper('viewRenderer')->setViewSuffix('js');
}
If you need to apply this to all controllers within a module, you should place this in an abstract controller class used for that module and have each controller in that module inherit from that abstract class.
You could theoretically put this in the module's bootstrap, but it would set the view suffix to 'js' for every request, even ones that end up not being routed to that specific module. This is because every module's bootstrap is executed for each request, regardless of which module is selected by the dispatcher.
The controller's init() function, though, will only execute when the module is selected for dispatch.