rosuandreimihai Posted May 22, 2016 Share Posted May 22, 2016 (edited) Hi all, I have a custom CMS page with a link similar to this one: http://mysite.com/flowers-country-city.html The link is generated trough a override of the Link.php class using a custom function public function getVirtualPageLink($cms, $id_country, $country, $city, $alias = null, $ssl = null, $id_lang = null, $id_shop = null, $relative_protocol = false) { if (!$id_lang) { $id_lang = Context::getContext()->language->id; } $url = $this->getBaseLink($id_shop, $ssl, $relative_protocol).$this->getLangLink($id_lang, null, $id_shop); $dispatcher = Dispatcher::getInstance(); if (!is_object($cms)) { if ($alias !== null && !$dispatcher->hasKeyword('vpage_rule', $id_lang, 'id_country', $id_shop) && !$dispatcher->hasKeyword('vpage_rule', $id_lang, 'city', $id_shop)) { return $url.$dispatcher->createUrl('vpage_rule', $id_lang, array('id' => (int)$cms, 'rewrite' => (string)$alias), $this->allow, '', $id_shop); } $cms = new CMS($cms, $id_lang); } // Set available keywords $params = array(); $params['id'] = $cms->id; $params['rewrite'] = (!$alias) ? (is_array($cms->link_rewrite) ? $cms->link_rewrite[(int)$id_lang] : $cms->link_rewrite) : $alias; $params['id_country'] = ''; $params['id_country'] = $id_country; $params['country'] = ''; $params['country'] = $country; $params['city'] = ''; $params['city'] = $city; $context = new Context(); $context->getContext()->cookie->__set('vp_country',$country); $context->getContext()->cookie->__set('vp_city',$city); $params['meta_keywords'] = ''; if (isset($cms->meta_keywords) && !empty($cms->meta_keywords)) { $params['meta_keywords'] = is_array($cms->meta_keywords) ? Tools::str2url($cms->meta_keywords[(int)$id_lang]) : Tools::str2url($cms->meta_keywords); } $params['meta_title'] = ''; if (isset($cms->meta_title) && !empty($cms->meta_title)) { $params['meta_title'] = is_array($cms->meta_title) ? Tools::str2url($cms->meta_title[(int)$id_lang]) : Tools::str2url($cms->meta_title); } return $url.$dispatcher->createUrl('vpage_rule', $id_lang, $params, $this->allow, '', $id_shop); } I tried to enclose the parameters inside some cookies but then I realized that the cookies would be available only if click event was fired, but it would not work on direct access of the link I have also a custom Dispatcher rule, similar to the one above 'vpage_rule' => array( 'controller' => 'cms', 'rule' => '{rewrite}-{country}-{city}.html', 'keywords' => array( 'id' => array('regexp' => '[0-9]+'), 'rewrite' => array('regexp' => '[_a-zA-Z0-9-\pL]*', 'param' => 'cms_rewrite'), 'id_country' => array('regexp' => '[0-9]+'), 'country' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), 'city' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), 'meta_keywords' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), 'meta_title' => array('regexp' => '[_a-zA-Z0-9-\pL]*') ), ), So, can someone tell me how to solve this issue? To have the url parameters inside a CMS page from a custom link? What would be the best and simple way of doing it? Thank you! Edited May 22, 2016 by rosuandreimihai (see edit history) Link to comment Share on other sites More sharing options...
roja45 Posted May 22, 2016 Share Posted May 22, 2016 I think you're going about this the wrong way, it would be easier to create a module with your own front controller. When you call the front controller via it's url it can return your page with all of your parameters, dynamically retrieved, in smarty rendering the page as you require. You don't need to worry about using overrides then, which are evil. Link to comment Share on other sites More sharing options...
roja45 Posted May 22, 2016 Share Posted May 22, 2016 (edited) here you go, this should get you going in the right direction. It may install, I haven't tested it but the structure is correct. $url = $this->context->link->getModuleLink('mymodule', 'MyFontController', array(), true); That will generate a url to the module front controller. mymodule.zip Edited May 22, 2016 by roja45 (see edit history) Link to comment Share on other sites More sharing options...
rosuandreimihai Posted May 22, 2016 Author Share Posted May 22, 2016 Thank you! It sounds more logical than my solution But, all the virtual pages (the links) are generated inside cms.tpl just like this: {foreach $vPages as $page} <li> {assign var="link_" value="flowers-{$page.country}-{$page.city}.html"} {assign var="id_link" value="{$link->getVirtualPageLink('107',$page.id_country,$page.country,$page.city)}"} {assign var="meta_title" value="Flowers in {$page.country} - {$page.city}"} <a style="color:normal" href="{$id_link|escape:'html':'UTF-8'}" title="{$meta_title|escape:'html':'UTF-8'}"> {$meta_title|escape:'html':'UTF-8'} </a> </li> {/foreach} How should I change the link to point to the new tpl? Thank you again! Link to comment Share on other sites More sharing options...
roja45 Posted May 22, 2016 Share Posted May 22, 2016 yeah, your $vPages is a variable that has been assigned in smarty; in the initContent function in the front controller you would assign the same variable and replace the my-page.tpl with your own content. In that initContent function you can do whatever you need to create the links, assign the,, then use them in the template. You have lots of options with a front controller, check out the standard PS ones in the controllers/front directory. ContactController build the contact page, SitemapController builds the sitemap page (essentially a list of dynamic links..) Link to comment Share on other sites More sharing options...
rosuandreimihai Posted May 23, 2016 Author Share Posted May 23, 2016 Hi Roja, I followed what you explained, I created a custom FrontController that points to the vPages.tpl, I added a new page under SEO & Preferences with the friendly url mysite.com/flowers-world but I'm getting only 404 This page is not available message Could you tell me what I am doing wrong? Thank you! Link to comment Share on other sites More sharing options...
roja45 Posted May 24, 2016 Share Posted May 24, 2016 Not easy for me to do that, does it work if you access the page via the non-friendly URL? Easiest thing to do is attach a debugger and step through what's happening. All the magic finding the correct controller to load based on the URL received happens in the Dispatcher.php Link to comment Share on other sites More sharing options...
rosuandreimihai Posted May 24, 2016 Author Share Posted May 24, 2016 Ok, I took your advice, I have created a module that has the following structure: modules/ modules/vpages modules/vpages/controllers modules/vpages/controllers/front modules/vpages/controllers/front/vPagesController.php modules/vpages/views modules/vpages/views/templates modules/vpages/views/templates/front modules/vpages/views/templates/front/vPage.tpl modules/vpages/vpages.php The vPagesController.php has the following strucure: class vpagesvPagesControllerModuleFrontController extends ModuleFrontController { public $errors = array(); public $display_column_left = false; public $ssl = true; public function __construct() { parent::__construct(); $this->page_name = 'vpages'; $this->context = Context::getContext(); } public function initContent() { parent::initContent(); $this->setTemplate('vPage.tpl'); } } And it should work by pointing to: mysite.com/index.php?fc=module&module=vpages&controller=vPagesController I also tried to lowercase everything just like this: mysite.com/index.php?fc=module&module=vpages&controller=vpagescontroller Nothing works, I still get a "This page is unavaiilable" Could you point me to the correct way? Thank you! Link to comment Share on other sites More sharing options...
roja45 Posted May 24, 2016 Share Posted May 24, 2016 Change the following.. vPagesController.php > VPages.php class vpagesvPagesControllerModuleFrontController extends ModuleFrontController { > class vpagesVPagesModuleFrontController extends ModuleFrontController { mysite.com/index.php?fc=module&module=vpages&controller=vPagesController > mysite.com/index.php?fc=module&module=vpages&controller=VPages and report back.. Link to comment Share on other sites More sharing options...
rosuandreimihai Posted May 25, 2016 Author Share Posted May 25, 2016 It works like a charm! Thank you! It's amazing, but I still don't understand why this naming convention works and my naming for the module didn't worked.. Thanks again! Link to comment Share on other sites More sharing options...
roja45 Posted May 25, 2016 Share Posted May 25, 2016 If you look inside the Dispatcher (getController function) you will see that it does a whole bunch of pattern matching, sub-stringing, appending, camel-casing of your module and controller names in order to find and load the class, if it isn't exactly as it needs it, it can't find it. May not be so much of a problem when you create a friendly url for it. Mark the thread as solved and indicate the answer. Cheers Link to comment Share on other sites More sharing options...
rosuandreimihai Posted May 25, 2016 Author Share Posted May 25, 2016 Now that you managed to learn me something new, could you tell me how to manage the links inside the page just created? There will be some hundreds of them, pulled out from database, with links similar to mysite.com/flowers-country-city.html where country and city are parameters pulled from DB Should I create another module to maintain the new page that will be called for every link? Thank you! Link to comment Share on other sites More sharing options...
roja45 Posted May 25, 2016 Share Posted May 25, 2016 I don't see why you'd need another module, just direct those links back to the same controller and do something different based on a parameter passed or something, you don't have to call the same template each time. Look at the initContent function of the OrderController.php that's a front controller and it does a bunch of different things. Link to comment Share on other sites More sharing options...
rosuandreimihai Posted May 26, 2016 Author Share Posted May 26, 2016 Thanks, but I needed a new page that should have another friendly url generated dynamically. For each different parameter (country and city) there should appear some other link that could be directly accessed from outside the shop So, I created a new controller inside the same module that will redirect to a custom page. The first page contains all the links generated. The page can be seen at: http://europeanflora.com/flowers-world Now, all the links point to a new page, just like this: http://europeanflora.com/module/vpages/dpage?module_action=list&id_country=36&country=Romania&city=Bucuresti But, how can I maintain the Dispatcher to make a url rewrite something like this: mysite.com/flowers-bucurest-romania.html? Can I make that sort of page without loosing the parameters and still be able to pull them out using {$smarty.get.country}? Or should I just live the page just like this? I think that SEO would be more relevant if I make a friendly url.. Link to comment Share on other sites More sharing options...
roja45 Posted May 26, 2016 Share Posted May 26, 2016 Logic is the wrong way around, write the links in the format you need them, then use the friendly url options in Prestashop to rewrite the friendly link back to your controller. Link to comment Share on other sites More sharing options...
EdEichman Posted May 26, 2016 Share Posted May 26, 2016 Related to Roja45's module (which I WISH I had seen before I started my code), I posted an article on how to create a front controller module from scratch. In any case, I agree with Roja45 that modules are much better than overrides. 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