Prestashop 1.5.x has treated us with a wonderful possibility to implement controllers in modules. This is the main goal of ModuleFrontController and ModuleAdminController classes. Let’s take a closer look at them (pay attention to comments):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
/*the class overloads 2 methods and adds a new one*/ class ModuleFrontControllerCore extends FrontController { /** * @var Module */ public $module; public function __construct() { $this->controller_type = 'modulefront'; //instead of standard controllers’ front $this->module = Module::getInstanceByName(Tools::getValue('module')); // an instance of the module is created if (!$this->module->active) Tools::redirect('index'); //if the module is inactive, the user will be redirected to index.php $this->page_name = 'module-'.$this->module->name.'-'.Dispatcher::getInstance()->getController(); //for example: module-belvg_storelocator-search parent::__construct(); } /** * Assign module template * * @param string $template */ public function setTemplate($template) { if (Tools::file_exists_cache(_PS_THEME_DIR_.'modules/'.$this->module->name.'/'.$template)) $this->template = _PS_THEME_DIR_.'modules/'.$this->module->name.'/'.$template; //if the file with the template is located in the root directory elseif (Tools::file_exists_cache($this->getTemplatePath().$template)) $this->template = $this->getTemplatePath().$template; //otherwise file in module_dir/views/templates/front/ should be used else throw new PrestaShopException("Template '$template'' not found"); //if the file is not found, the exception will be thrown } /** * Get path to front office templates for the module * * @return string */ public function getTemplatePath() { return _PS_MODULE_DIR_.$this->module->name.'/views/templates/front/'; } } /*the class overloads 2 methods and adds a new one*/ abstract class ModuleAdminControllerCore extends AdminController { /** * @var Module */ public $module; public function __construct() { $this->controller_type = 'moduleadmin'; //instead of AdminController’s admin parent::__construct(); $tab = new Tab($this->id); // an instance with your tab is created; if the tab is not attached to the module, the exception will be thrown if (!$tab->module) throw new PrestaShopException('Admin tab '.get_class($this).' is not a module tab'); // an instance of the module is created $this->module = Module::getInstanceByName($tab->module); //it is checked if the module is installed if (!$this->module->id) throw new PrestaShopException("Module {$tab->module} not found"); } public function createTemplate($tpl_name) { //$this->override_folder = Tools::toUnderscoreCase(substr($this->controller_name, 5)).'/'; if (file_exists($this->getTemplatePath().$this->override_folder.$tpl_name) && $this->viewAccess()) return $this->context->smarty->createTemplate($this->getTemplatePath().$this->override_folder.$tpl_name, $this->context->smarty); return parent::createTemplate($tpl_name); } /** * Get path to back office templates for the module * * @return string */ public function getTemplatePath() { return _PS_MODULE_DIR_.$this->module->name.'/views/templates/admin/'; } } |
Let’s now pass from theory to practice. For Prestashop to call Frontend controller right from the module folder, it’s necessary to create the controllers/front/mycontroller.php file in the module root directory.
1 2 3 4 5 6 |
//Please notice that MyModule here is the name of your module (the best practice – it matches the name of the module directory), MyController – is the name of your controller (the best practice – it matches the name of the controller file) class MyModuleMyControllerModuleFrontController extends ModuleFrontController { } |
Templates of your module can be located either in the root directory or here:
module_dir/views/templates/front/
Modulecontroller URL differs from front-end controllers and looks like this:
http://domain.com/index.php?fc=module&module=mymodule&controller=mycontroller
Hello
Can you please send me code for creating controller in admin folder of module by extending ModuleAdminController . I tried different ways but every time I get an error “Controller not found”.
Regards
Sandeep
Hi, excuse me for send you message for this form. I have a problem on creation the module on dashboard in my prestashop site. I need call a function of mymodule.php from an archive .tpl but only when I press function onclick the button. I think that you could help me. Thanks.
Great explanation as usual, I work at PrestaShop but I still learn things on your website :)
I would just add one useful piece of info: You can get the URL to this controller with the Link class like this:
$this->context->link->getModuleLink(‘module_name’, ‘controller name’);
This works from all objects that have a context: modules, other controllers, etc.
Dudy,
To output errors instead of a blank screen you need to follow recommendations described in this article.
All the rest you are doing right, in any smarty template it is possible to use variables such as {$var}.
Hi there..
I got a simple problem here but really need a solution.
I made a module that can change colors for shop theme. it is functioning.
Then i added an iframe in the admin form (form.tpl) so that anything change you may see the results instantly without have to click ‘view my shop’.
so for the iframe, i use smarty variable {$base_dir} for it’s src.
.
it ends up with sowing nothing. Debugging the actual site, the iframe element have blank on the src value.
And the question is, in the form.tpl, what is the right method to call any smarty variable? It seems that in the form.tpl doesn’t recognize the smarty variable. I thought that should be global ?
Ademus,
Try the following method:
In a controller class:
Thanks for your help.
I would like to call a controller method.
So, do you know how to instaciate a controller with presta 1.5 ?
In presta 1.4 I used ControllerFactory::getController(‘
but it seems to work no more.
very interesting.
How may I call a controller method as I used to do with
ControllerFactory::getController(‘myController’)->myMethod();
in version 1.4 ?
Thank you
This is best