smr Posted January 11, 2014 Share Posted January 11, 2014 (edited) Hi, I use prestashop version 1.5.4.1. I read hundred of posts and manual, but still didn't find how to assign and exchange a variable between the overriding Product.php file and product-list.tpl file. I wish to create a custom function to truncate the $product.description_short to say 100 chars but keeping the html tags. I found some examples of solution, but don't succeed to pass the result to the template file product-list.tpl! After many tests to search for right syntax, I succeed to see with debug console, that my function is called and executed in my overriding Product.php file but dying after maximum execution time because of deadend loop in my function. So I just succeed to assign a variable in template file and display it this way {assign var=my_var value='test'} then display it with {$my_var} Now to just test passing a variable, I tried these ways, always using {$my_var} in template product-list.tpl: <?php class Product extends ProductCore { //public $my_var; //public static $my_var = 'test'; //$smarty->assign('my_var', function1($args)); //assign($my_var, value='test'); //$smarty->assign('my_var', 'test'); public function get_position($content, $position, $chars = 100) { ... return $var1; } public function function1($content, $chars = 50) { $position = 0; $data=array(); while(...){ ...$next_position = $this->get_position($content, $position, $chars ); $data[] = substr($content, $position, $next_position); } ... return $data; } public function __construct($id_product = null, $full = false, $id_lang = null, $id_shop = null, Context $context = null) { parent::__construct($id_product, $full, $id_lang); //$this->my_var= 'test' ; //$this->my_var= $smarty->get_template_vars('my_var');; //$this->context->smarty->assign('my_var', $this->my_var); //$this->assign('my_var', $this->my_var); //$this->my_var = $this->function1('testtesttesttest',10); //self::$smarty->assign('my_var',function1('testtesttesttest',10)); //self::$smarty->assign('my_var','test); } } ?> (In the code above, I comment all syntax tests, of course I uncomment one at a time to test it.) In the debug console I see that $content and $chars take right value, this means functions are called. But I don't find the right syntax to assign my_var in product.php so it is readable in product-list.tpl. Most of the tests give syntax error or "Notice: Undefined index:my_var in..." if I don't assign my_var in product-list.tpl Of course, I also need in Product.php file to read arguments coming from product-list.tpl call.. Thanks in advance for any help Meanwhile I look for custom function using plugin... but I read that custom plugin should be placed in a "plugins" directory but documentation is not clear about where to install this directory. By default it is said that smarty will look in default smarty "plugins" directory in smarty_dir, but I don't know where is this default directory. I noticed in debug console that it is rootdir\tools\smarty\plugins\ is it right? Thanks again Edited January 15, 2014 by smr (see edit history) Link to comment Share on other sites More sharing options...
smr Posted January 12, 2014 Author Share Posted January 12, 2014 (edited) I suceed with using plugin! I had to create a function.truncHtml.php file that I saved in rootdir/tools/smarty/plugins/ (there is a lot of plugins to read as examples!) the content of this file is: <?php /* * Smarty plugin * ------------------------------------------------------------- * File: function.truncHtml.php * Type: function * Name: truncHtml * Purpose: truncate string to a length keeping Html tags and outputs a response * ------------------------------------------------------------- */ function smarty_function_truncHtml($params, &$smarty, $patternsReplace = false) { $string=$params['mystring'] ; $length= $params['chars'] ; $i = 0; $count = 0; $isParagraphCut = false; $htmlOpen = false; $openTag = false; $tagsStack = array(); while ($i < strlen($string)) { $char = substr($string, $i, 1); if ($count >= $length) { $isParagraphCut = true; break; } if ($htmlOpen) { if ($char === ">") { $htmlOpen = false; } } else { if ($char === "<") { $j = $i; $char = substr($string, $j, 1); while ($j < strlen($string)) { if($char === '/'){ $i++; break; } elseif ($char === ' ') { $tagsStack[] = substr($string, $i, $j); } $j++; } $htmlOpen = true; } } if (!$htmlOpen && $char != ">") { $count++; } $i++; } if ($isParagraphCut) { $j = $i; while ($j > 0) { $char = substr($string, $j, 1); if ($char === " " || $char === ";" || $char === "." || $char === "," || $char === "<" || $char === "(" || $char === "[") { break; } else if ($char === ">") { $j++; break; } $j--; } $string = substr($string, 0, $j); foreach($tagsStack as $tag){ $tag = strtolower($tag); if($tag !== "img" && $tag !== "br"){ $string .= "</$tag>"; } } $string .= "..."; } if ($patternsReplace) { foreach ($patternsReplace as $value) { if (isset($value['pattern']) && isset($value["replace"])) { $string = preg_replace($value["pattern"], $value["replace"], $string); } } } return $string; } ?> Be careful that the name of the php plugin file must be "smarty_function_nameofyourfunction.php" and the name of your main function must have the same name syntax so the first line of function is "function smarty_function_nameofyourfunction($params..." where $params is the variable sent by your template file (product-list.tpl in my case) when it is invoking this custom function. $params may be an array of variables ; in my case I call the function like this in product-list.tpl {truncHtml mystring=$product.description_short chars=250} I found this plugin creation syntax here and I found the truncHtml function here it is said it is not perfect but enough for my case. It is not clear how many and what parameters to write in the function defintion. I tried with a single parameter and it is ok like this function smarty_function_truncHtml($params) { $string=$params['mystring'] ; $length= $params['chars'] ; $patternsReplace = false ; But it is not ok with three parameters this way function smarty_function_truncHtml($params, $patternsReplace = false, &$smarty) { it seems &$smarty must be the second parameter if there are three parameters (or two) Still no solution with overriding Edited January 12, 2014 by smr (see edit history) Link to comment Share on other sites More sharing options...
vekia Posted January 12, 2014 Share Posted January 12, 2014 you can pass variables with $this->context object $this->context->smarty->assign(array('test' => 'this is test'); Link to comment Share on other sites More sharing options...
smr Posted January 13, 2014 Author Share Posted January 13, 2014 (edited) thanks for your help. problem is I don't see where to place this statement. I tried in my Product.php overriding file but this give syntax errors I tried in a new ProductController.php overriding file, this way <?php class ProductController extends ProductControllerCore { public function initContent() { $this->context->smarty->assign(array('test' => 'this is test')); parent::initContent(); } } ?> no syntax error, but my $test variable is not visible in product-list.tpl... Edited January 14, 2014 by smr (see edit history) Link to comment Share on other sites More sharing options...
vekia Posted January 14, 2014 Share Posted January 14, 2014 ProductController - product page (produc.ttpl) CategoryController - category products list (product-list.tpl) 1 Link to comment Share on other sites More sharing options...
smr Posted January 14, 2014 Author Share Posted January 14, 2014 Sure it is more clear when we know the solution, I did so and progressed by transmitting a variable from CategoryController override file to product-list.tpl, either directly or through a function this way <?php class CategoryController extends CategoryControllerCore { public function initContent() { function Test($params){ return $params; } $this->context->smarty->assign(array('var1' => 'this is test')); $this->context->smarty->assign('var2',Test('this is another test' )); parent::initContent(); } } ?> and in product-list.tpl {$var1} or {$var2} but I didn't find yet how to pass a variable from product-list.tpl to CategoryController, to be used in a function, something like {Test, 'this is a test'} or my target usage: {Test, $product.description_short, 100} Thanks again Link to comment Share on other sites More sharing options...
smr Posted January 15, 2014 Author Share Posted January 15, 2014 I got it! Here how to code the controller: <?php class CategoryController extends CategoryControllerCore { public function initContent() { function Test($params){ return $params;} function mytruncHtml($string,$length) { $patternsReplace = false ; $i = 0; $count = 0; $isParagraphCut = false; $htmlOpen = false; $openTag = false; $tagsStack = array(); while ($i < strlen($string)) { $char = substr($string, $i, 1); if ($count >= $length) { $isParagraphCut = true; break; } if ($htmlOpen) { if ($char === ">") { $htmlOpen = false; } } else { if ($char === "<") { $j = $i; $char = substr($string, $j, 1); while ($j < strlen($string)) { if($char === '/'){ $i++; break; } elseif ($char === ' ') { $tagsStack[] = substr($string, $i, $j); } $j++; } $htmlOpen = true; } } if (!$htmlOpen && $char != ">") { $count++; } $i++; } if ($isParagraphCut) { $j = $i; while ($j > 0) { $char = substr($string, $j, 1); if ($char === " " || $char === ";" || $char === "." || $char === "," || $char === "<" || $char === "(" || $char === "[") { break; } else if ($char === ">") { $j++; break; } $j--; } $string = substr($string, 0, $j); foreach($tagsStack as $tag){ $tag = strtolower($tag); if($tag !== "img" && $tag !== "br"){ $string .= "</$tag>"; } } $string .= "..."; } if ($patternsReplace) { foreach ($patternsReplace as $value) { if (isset($value['pattern']) && isset($value["replace"])) { $string = preg_replace($value["pattern"], $value["replace"], $string); } } } return $string; } parent::initContent(); } } ?> and here is how to call the function in product-list.tpl {call_user_func_array('mytruncHtml', array($product.description_short,230))} or for a simple function with one argument {call_user_func('Test', 'my new test')} Thanks for helps 1 Link to comment Share on other sites More sharing options...
Nikpro Posted January 23, 2014 Share Posted January 23, 2014 I got it! Here how to code the controller: <?php class CategoryController extends CategoryControllerCore { public function initContent() { function Test($params){ return $params;} function mytruncHtml($string,$length) { $patternsReplace = false ; $i = 0; $count = 0; $isParagraphCut = false; $htmlOpen = false; $openTag = false; $tagsStack = array(); while ($i < strlen($string)) { $char = substr($string, $i, 1); if ($count >= $length) { $isParagraphCut = true; break; } if ($htmlOpen) { if ($char === ">") { $htmlOpen = false; } } else { if ($char === "<") { $j = $i; $char = substr($string, $j, 1); while ($j < strlen($string)) { if($char === '/'){ $i++; break; } elseif ($char === ' ') { $tagsStack[] = substr($string, $i, $j); } $j++; } $htmlOpen = true; } } if (!$htmlOpen && $char != ">") { $count++; } $i++; } if ($isParagraphCut) { $j = $i; while ($j > 0) { $char = substr($string, $j, 1); if ($char === " " || $char === ";" || $char === "." || $char === "," || $char === "<" || $char === "(" || $char === "[") { break; } else if ($char === ">") { $j++; break; } $j--; } $string = substr($string, 0, $j); foreach($tagsStack as $tag){ $tag = strtolower($tag); if($tag !== "img" && $tag !== "br"){ $string .= "</$tag>"; } } $string .= "..."; } if ($patternsReplace) { foreach ($patternsReplace as $value) { if (isset($value['pattern']) && isset($value["replace"])) { $string = preg_replace($value["pattern"], $value["replace"], $string); } } } return $string; } parent::initContent(); } } ?> and here is how to call the function in product-list.tpl {call_user_func_array('mytruncHtml', array($product.description_short,230))} or for a simple function with one argument {call_user_func('Test', 'my new test')} Thanks for helps give exemple use this technology Link to comment Share on other sites More sharing options...
smr Posted January 23, 2014 Author Share Posted January 23, 2014 What kind of exemple you wish, this is a trial, no web site yet with this solution. Here is the code in product-list.tpl, from line 40 to 50 <div class="center_block"> <a href="{$product.link|escape:'htmlall':'UTF-8'}" class="product_img_link" title="{$product.name|escape:'htmlall':'UTF-8'}"> <div class="product_desc"> <img src="{$link->getImageLink($product.link_rewrite, $product.id_image, 'home_default')|escape:'html'}" alt="{$product.legend|escape:'htmlall':'UTF-8'}" {if isset($homeSize)} width="{$homeSize.width}" height="{$homeSize.height}"{/if} /> {if isset($product.new) && $product.new == 1}<span class="new">{l s='New'}</span>{/if} <span>{if isset($product.pack_quantity) && $product.pack_quantity}{$product.pack_quantity|intval|cat:' x '}{/if}{$product.name|truncate:35:'...'|escape:'htmlall':'UTF-8'}</span> {call_user_func_array('mytruncHtml', array($product.description_short,230))} </div> </a> </div> 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