Shutiri Posted January 4, 2015 Share Posted January 4, 2015 Hello all, I was looking for this one for a while, and wanted to contribute with the solution that worked for me. This is a result of VEKIA's advices on different topics, so credits to him. In controllers/front/ProductController.php, find: $this->setTemplate(_PS_THEME_DIR_.'product.tpl'); For SINGLE products, replace with: if (Tools::getValue('id_product')==3){ // For product number 3 $this->setTemplate(_PS_THEME_DIR_.'productAlt1.tpl'); } else { $this->setTemplate(_PS_THEME_DIR_.'product.tpl'); } To apply a template to a range of products within a given category or categories: if ($this->category->id>=5 && $this->category->id<=7 || $this->category->id==11){ $this->setTemplate(_PS_THEME_DIR_.'productStore.tpl'); // template file for caregories between 5 and 7, OR category 11 } else { $this->setTemplate(_PS_THEME_DIR_.'product.tpl'); // DEFAULT template } I hope this helps. Cheers!! 4 Link to comment Share on other sites More sharing options...
theillo Posted February 25, 2015 Share Posted February 25, 2015 (edited) Thanks, great idea! I was just about to ask if there were any suggestions how to accomplish this! In fact I feel like it might be helpful to make a module, that does this as an override, but then also calls a custom hook, so that you can do your own logic in that hook, assign custom variables to your custom template file, etc. I might work on that! Edited February 25, 2015 by theillo (see edit history) Link to comment Share on other sites More sharing options...
theillo Posted February 25, 2015 Share Posted February 25, 2015 (edited) BAM found a perfect solution! I created a module that does that (so when I reinstall my store at a later point again, I can just reinstall the module). But you can also just hack your way through the process. I guess another advantage of making it a module is that you can require this module to be installed by all those modules that will now depend on this hook. Here's what you need to do: 1.) Create a new Hook When doing a module installation, you should be able to just call $this->registerHook('nameOfNewHook'); since the Hook class has a case for creating new, non existing hooks. Otherwise, the code to create a new hook is this: $hook = 'nameOfNewHook'; $new_hook = new Hook(); $new_hook->name = pSQL($hook); $new_hook->title = pSQL($hook); $new_hook->add(); So just run that code during installation of your module, or just run it once and then you're set. No I actually gave my new hook the name 'actionLoadProductTemplate'. 2.) Create a new Product Controller class Create a file called ProductController.php with the following contents: <?php class ProductController extends ProductControllerCore { public function initContent() { parent::initContent(); $template_file = Hook::exec('actionLoadProductTemplate', array('product' => $this->product, 'category'=> $this->category)); //you can pass along other properties of the product class by putting them in this array if($template_file && file_exists($template_file)) { $tpl_path = $template_file; } else { $tpl_path = _PS_THEME_DIR_.'product.tpl'; } $this->setTemplate($tpl_path); } } 3.) Override the ProductConroller class Once you created the class file, you'll need to make sure Prestashop uses it, by overriding it: If you are installing a module, put it in the folder 'PS_ROOT/modules/NAMEOFYOURMODULE/override/controller/front/ProductController.php' If you delete the file 'PS_ROOT/cache/class_index.php' JUST before the installation, it should even work properly from the start. Of course alternatively you can just place your file in the override directory of the prestashop folder ( 'PS_ROOT/override/controller/front/ProductController.php') If it doesn't work, make sure the class_index.php file has this written in it: 'ProductController' => array ( 'path' => 'override/controllers/front/ProductController.php', 'type' => 'class', 'override' => false, ), or if you want to maintain the source code of your override file in the folder of your module, go like this: 'ProductController' => array ( 'path' => 'modules/NAMEOFYOURMODULE/override/controllers/front/ProductController.php', 'type' => 'class', 'override' => true, ), Again, you just need to hack around in the cache file, if it didn't work from the beginning (which it never has for me though, so I've always had to do it ) 4.) Start using your new hook in all your modules! :-D So now you can use this great new hook to change the template file of a product. Your hook function will need to RETURN the path to the new template you want to use, and your template file needs to exist. Otherwise it'll just show the default template file. public function hookActionLoadProductTemplate($params) { $this->product = $params['product']; $this->category = $params['category']; //the product and category arrays are passed along by the product controller. $this->customer = $this->context->customer; //do some custom logic $myrule = TRUE; //for example what type of product you have, and if you customer has purchased it, or what category it is in... //assign any custom variables to your custom template $this->context->smarty->assign('custom stuff', 'custom things go here'); //return the path of your new template. if($myrule) { $this->context->smarty->assign('custom_variable', 'custom value!'); return _PS_MODULE_DIR_.'YOURMODULENAME/views/templates/product_custom_no1.tpl'; } else { $this->context->smarty->assign('another_variable', 'different value!'); return _PS_THEME_DIR_.'product_custom_no2.tpl'; } } Edited February 25, 2015 by theillo (see edit history) 2 1 Link to comment Share on other sites More sharing options...
lshrvm Posted February 23, 2016 Share Posted February 23, 2016 (edited) Error Edited February 24, 2016 by lshrvm (see edit history) Link to comment Share on other sites More sharing options...
LauraPresta Posted June 6, 2018 Share Posted June 6, 2018 (edited) Lol thank you so much Theillo, this is great. This post should be pinned to correct section or something like this. Nice exemple of new hook and override Edited June 6, 2018 by LauraPresta (see edit history) 1 Link to comment Share on other sites More sharing options...
LauraPresta Posted June 6, 2018 Share Posted June 6, 2018 did you found a better/cleaner solution for this ? "If you delete the file 'PS_ROOT/cache/class_index.php' JUST before the installation, it should even work properly from the start." Link to comment Share on other sites More sharing options...
theillo Posted June 8, 2018 Share Posted June 8, 2018 On 6/6/2018 at 9:12 AM, LauraPresta said: did you found a better/cleaner solution for this ? "If you delete the file 'PS_ROOT/cache/class_index.php' JUST before the installation, it should even work properly from the start." Seems to me that deleting it right before install is the cleanest, otherwise I used to do this: $this->original_string = "'ProductController' => array ( 'path' => '', 'type' => 'class', 'override' => false, ),"; $this->replacement_string = "'ProductController' => array ( 'path' => 'modules/customproducttpl/override/controllers/front/ProductController.php', 'type' => 'class', 'override' => true, ),"; $this->rewriteClassCache($this->original_string, $this->replacement_string); public function rewriteClassCache($original,$replacement){ $file = dirname(dirname(dirname(__FILE__))).'/cache/class_index.php'; $filecontent=file_get_contents($file); $pos=strpos($filecontent, $original); if($pos === false) { //p('couldnt find original.'); $pos=strpos($filecontent, $replacement); //d('found replacement at '.$pos); return; } $filecontent=substr($filecontent, 0, $pos)."\r\n".$replacement."\r\n".substr($filecontent, $pos+strlen($original)); //d($filecontent); if( !file_put_contents($file, $filecontent) ) { d('rewriting the class index file failed!'); return; } else{ //p('did the replacement'); return; } } Link to comment Share on other sites More sharing options...
LauraPresta Posted June 9, 2018 Share Posted June 9, 2018 Thank you theillo for this answer I'll test your solution. About deleting the file, do you think it could be done during the install part of the module ? i mean, do we have the rights to do this - is it a legit use ? Link to comment Share on other sites More sharing options...
Takuya Posted March 12, 2019 Share Posted March 12, 2019 Hi, Is it possible to achieve this in Prestashop 1.7.4.2 ? Kind regards, Link to comment Share on other sites More sharing options...
giulym Posted April 11, 2019 Share Posted April 11, 2019 Hello! I'd like to know if it works for 1.7.5.1 thanks Link to comment Share on other sites More sharing options...
Takuya Posted April 11, 2019 Share Posted April 11, 2019 (edited) Hi, See link below, it's actually very simple to do ... https://devdocs.prestashop.com/1.7/themes/reference/templates/templates-layouts/ Specific templates If you’re working on a big store in many languages you may need to change the layout of the page depending on the language. For example you want a different product page for american customers and japanese ones. In this case you simply have to create new template product.tpl and place it in the right folder. When searching for a template, PrestaShop will check many location to determine which file should be used. It make it very easy to have different template for a given locale or a specific entity id. With the product page, the core will check the following locations (in order) and return the first template found: Example with a product with ID = 3 and locale = en-US en-US/catalog/product-3.tpl catalog/product-3.tpl en/US/catalog/listing/product.tpl catalog/listing/product.tpl Another example with category template for the category with ID = 9 and locale = en-US. en-US/catalog/listing/category-9.tpl catalog/listing/category-9.tpl en/US/catalog/listing/category.tpl catalog/listing/category.tpl en-US/catalog/listing/product-list.tpl catalog/listing/product-list.tpl Kind regards, Edited April 11, 2019 by Takuya (see edit history) Link to comment Share on other sites More sharing options...
giulym Posted April 11, 2019 Share Posted April 11, 2019 23 minutes ago, Takuya said: Hi, See link below, it's actually very simple to do ... https://devdocs.prestashop.com/1.7/themes/reference/templates/templates-layouts/ Specific templates If you’re working on a big store in many languages you may need to change the layout of the page depending on the language. For example you want a different product page for american customers and japanese ones. In this case you simply have to create new template product.tpl and place it in the right folder. When searching for a template, PrestaShop will check many location to determine which file should be used. It make it very easy to have different template for a given locale or a specific entity id. With the product page, the core will check the following locations (in order) and return the first template found: Example with a product with ID = 3 and locale = en-US en-US/catalog/product-3.tpl catalog/product-3.tpl en/US/catalog/listing/product.tpl catalog/listing/product.tpl Another example with category template for the category with ID = 9 and locale = en-US. en-US/catalog/listing/category-9.tpl catalog/listing/category-9.tpl en/US/catalog/listing/category.tpl catalog/listing/category.tpl en-US/catalog/listing/product-list.tpl catalog/listing/product-list.tpl Kind regards, Thank you!!! Link to comment Share on other sites More sharing options...
limitcracker Posted August 9, 2020 Share Posted August 9, 2020 (edited) On 2/25/2015 at 2:02 PM, theillo said: BAM found a perfect solution! I created a module that does that (so when I reinstall my store at a later point again, I can just reinstall the module). But you can also just hack your way through the process. I guess another advantage of making it a module is that you can require this module to be installed by all those modules that will now depend on this hook. Here's what you need to do: 1.) Create a new Hook When doing a module installation, you should be able to just call $this->registerHook('nameOfNewHook'); since the Hook class has a case for creating new, non existing hooks. Otherwise, the code to create a new hook is this: $hook = 'nameOfNewHook'; $new_hook = new Hook(); $new_hook->name = pSQL($hook); $new_hook->title = pSQL($hook); $new_hook->add(); So just run that code during installation of your module, or just run it once and then you're set. No I actually gave my new hook the name 'actionLoadProductTemplate'. 2.) Create a new Product Controller class Create a file called ProductController.php with the following contents: <?php class ProductController extends ProductControllerCore { public function initContent() { parent::initContent(); $template_file = Hook::exec('actionLoadProductTemplate', array('product' => $this->product, 'category'=> $this->category)); //you can pass along other properties of the product class by putting them in this array if($template_file && file_exists($template_file)) { $tpl_path = $template_file; } else { $tpl_path = _PS_THEME_DIR_.'product.tpl'; } $this->setTemplate($tpl_path); } } 3.) Override the ProductConroller class Once you created the class file, you'll need to make sure Prestashop uses it, by overriding it: If you are installing a module, put it in the folder 'PS_ROOT/modules/NAMEOFYOURMODULE/override/controller/front/ProductController.php' If you delete the file 'PS_ROOT/cache/class_index.php' JUST before the installation, it should even work properly from the start. Of course alternatively you can just place your file in the override directory of the prestashop folder ( 'PS_ROOT/override/controller/front/ProductController.php') If it doesn't work, make sure the class_index.php file has this written in it: 'ProductController' => array ( 'path' => 'override/controllers/front/ProductController.php', 'type' => 'class', 'override' => false, ), or if you want to maintain the source code of your override file in the folder of your module, go like this: 'ProductController' => array ( 'path' => 'modules/NAMEOFYOURMODULE/override/controllers/front/ProductController.php', 'type' => 'class', 'override' => true, ), Again, you just need to hack around in the cache file, if it didn't work from the beginning (which it never has for me though, so I've always had to do it ) 4.) Start using your new hook in all your modules! 😄 So now you can use this great new hook to change the template file of a product. Your hook function will need to RETURN the path to the new template you want to use, and your template file needs to exist. Otherwise it'll just show the default template file. public function hookActionLoadProductTemplate($params) { $this->product = $params['product']; $this->category = $params['category']; //the product and category arrays are passed along by the product controller. $this->customer = $this->context->customer; //do some custom logic $myrule = TRUE; //for example what type of product you have, and if you customer has purchased it, or what category it is in... //assign any custom variables to your custom template $this->context->smarty->assign('custom stuff', 'custom things go here'); //return the path of your new template. if($myrule) { $this->context->smarty->assign('custom_variable', 'custom value!'); return _PS_MODULE_DIR_.'YOURMODULENAME/views/templates/product_custom_no1.tpl'; } else { $this->context->smarty->assign('another_variable', 'different value!'); return _PS_THEME_DIR_.'product_custom_no2.tpl'; } } Where do we place hookActionLoadProductTemplate( ) ? Inside mymodule.php or inside the ProductController.php? Thanks a lot for your help! Edited August 9, 2020 by limitcracker (see edit history) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now