Creating smarty plugins

Creating smarty plugins

Category: Smarty

Feb 28, 2019

Author: Jaime Gonzalez Trujillo

Creating smarty plugins

So long ago, when I started working with php, I started using Smarty and since then I have learned how to create plugins for all my projetcs, today I will show you how to create a simple plugin.
we are going to create a very simple plugin to create image thumbs at the end of this article.
To understand how this plugin works you need to have a good knowledge of PHP and GD or Imagemagick.
I can only write some comments hoping that you can understand the process, I am not here to teach you PHP or other programing language, I just want to show you how to create Smarty plugins.

To create a simple plugin we need to create a php file and save it in smarty plugin directory or create a directory for our personal plugins.

plugin files must be named as follows:
type.name.php
Where type is one of these plugin types:

function
modifier
block
compiler
prefilter
postfilter
outputfilter
resource
insert



$params is our array that will have all extra parameters that we will send to our plugin.
so in our tpl to call a plugin {plugin_name param1="" param2="" param3=""}

<?php
function smarty_function_plugin_name(array $params, Smarty_Internal_Template $template)
{
/* here we process all the php functions and return the result back to our tpl */
}
?>

Playground


function smarty_function_plugin_name(array $params, Smarty_Internal_Template $template)
{
/* here we process all the php functions and return the result back to our tpl */
}
?>

Ok now that you have the idea lets make a simple function plugin

Plugin name: lorem ->complete name: smarty_function_lorem
Plugin file name: function.lorem.php


In this example I will create a long string of text.
and create a single param "limit" to define the lenght we want from the string.
so to call this plugin from our tpl file: {lorem limit="300"}

to use this plugin just create a file function.lorem.php in your plugins directory copy paste the code and save it.
and testit in your tpl file calling the plugin like this.
{lorem limit="300"}


<?php
function smarty_function_lorem(array $params, Smarty_Internal_Template $template)

{
$text = <<<EOT
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a neque non nisl mollis porta. Vestibulum porta semper dolor, in pulvinar ipsum venenatis vehicula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce non condimentum nunc. Morbi sit amet dui ac nibh pulvinar cursus in sit amet augue. Donec tristique, lacus sollicitudin tristique bibendum, ante tellus pharetra nisl, eu vulputate ligula leo ut turpis. Nam eget sapien sed lorem gravida dictum ut ut lorem. Morbi tellus risus, porta egestas nulla vitae, egestas pharetra velit. Mauris dolor ante, sollicitudin et venenatis at, dignissim at mi. Duis et efficitur mauris. Praesent scelerisque vitae tellus sit amet aliquet. Pellentesque in tortor porta, tempus magna sit amet, auctor nisi. Donec dictum augue nisl, id feugiat turpis faucibus vel. Suspendisse potenti. In eu mattis velit, at varius quam.

Curabitur lobortis convallis magna, id iaculis velit accumsan vel. Aliquam congue porttitor mattis. Curabitur consequat nisl dui, ut accumsan mi elementum ut. Nam vitae sollicitudin lacus. Nulla rutrum odio nec metus pretium, eget convallis purus efficitur. Vestibulum et cursus nibh. Mauris tincidunt nunc fermentum felis ornare sodales. Curabitur tempus porta eros, non efficitur tortor consectetur ut. Maecenas ultricies, nunc at convallis fermentum, magna tortor posuere ex, efficitur auctor massa tellus at quam. Aliquam pretium ut quam nec iaculis. Fusce at leo hendrerit, venenatis nulla a, feugiat diam. Aenean volutpat accumsan elit. Etiam tellus nisl, scelerisque in hendrerit sit amet, semper vel lacus. Donec ultrices libero nec velit imperdiet, vel elementum sem pretium. Vestibulum sollicitudin augue lorem, at ultricies dui interdum sed. Suspendisse sollicitudin nisi in odio malesuada vehicula.

Sed venenatis quis justo vulputate lobortis. Aliquam mattis lacus eget ex ornare, sed tincidunt ligula iaculis. Nulla nisl neque, tincidunt ac scelerisque et, ultrices semper tellus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Aliquam sit amet velit ut odio vulputate ultrices. Nullam semper molestie ligula, quis pretium erat elementum et. Donec sed imperdiet tortor. Phasellus accumsan quis enim in venenatis. Cras enim diam, hendrerit ut nisl et, consequat luctus nulla. Vestibulum volutpat, magna elementum facilisis rhoncus, erat turpis sollicitudin nisi, quis placerat lectus magna eu leo. Etiam blandit nibh non lacus tristique luctus. Etiam interdum metus eu interdum commodo. Curabitur non varius nunc. Morbi a dui id lacus dictum vestibulum. Pellentesque vel sollicitudin ligula. Sed sed iaculis ligula, et elementum leo.

Cras tempus ipsum eget metus tempus, non faucibus nisl pretium. Maecenas ac leo diam. Pellentesque justo turpis, tristique ut viverra sit amet, sollicitudin vitae elit. Quisque dictum vel ante quis eleifend. Nam sit amet purus et risus rhoncus imperdiet. Curabitur dapibus porttitor est, sit amet varius lacus ornare nec. Quisque interdum id erat in maximus.

Etiam at blandit sem, a rhoncus magna. Etiam aliquam quam at massa facilisis volutpat. Phasellus non vulputate velit. Integer bibendum ornare dapibus. Mauris cursus dignissim massa at facilisis. Pellentesque eget feugiat dui. Ut eros nulla, pretium vel ullamcorper a, porta eget justo. Aenean congue ac leo vitae maximus. Curabitur lacinia, odio ac convallis condimentum, enim nulla tempus ante, non fringilla dui augue et turpis. Mauris in magna ac ligula eleifend egestas vitae at nibh.

Curabitur non quam malesuada, interdum tortor feugiat, finibus nunc. Integer interdum, sem ac posuere pulvinar, nisi orci accumsan ante, non vulputate eros turpis vel nisl. Aenean condimentum ultricies lorem quis condimentum. Aliquam erat volutpat. Cras massa eros, blandit nec tristique sit amet, auctor eget urna. Vivamus non felis eros. Duis risus lacus, eleifend id tincidunt non, vehicula a odio. Donec condimentum dignissim tempus. Interdum et malesuada fames ac ante ipsum primis in faucibus.

In laoreet maximus urna, efficitur maximus nulla ornare et. Donec nec dolor ultrices, ullamcorper justo at, interdum neque. Praesent gravida lectus nec quam ullamcorper commodo. Nam in tellus nec lacus pellentesque ultrices. In in mattis mi, non dignissim ipsum. In quis ligula a massa egestas ultrices. Morbi at libero hendrerit, blandit velit ut, lobortis ex. Vivamus non consequat orci, quis vestibulum turpis.

Cras aliquet vestibulum turpis ut lobortis. Cras consequat odio a nulla consectetur ornare. Duis sed ex non risus tincidunt fringilla. Suspendisse nec nisl eu risus luctus gravida id sed velit. Cras nec lorem iaculis, rhoncus diam vitae, egestas est. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec sagittis lectus. Quisque commodo erat massa, vitae venenatis felis sollicitudin in. Duis convallis, nunc a sodales imperdiet, enim nisl semper risus, et mattis velit urna quis ex. Etiam ullamcorper massa at tellus maximus aliquam. Nulla facilisi.

Sed varius bibendum mi. Phasellus vitae mattis justo. Proin ut enim nibh. Etiam eleifend blandit rutrum. Nunc sodales, massa vel mattis molestie, mi nunc congue nibh, a dictum turpis purus sed ante. Donec pretium lacinia metus, at varius sem pretium a. Mauris eu urna nec massa sodales rhoncus a sit amet augue. Nulla quis neque leo. Integer sit amet mauris tempus tellus hendrerit sagittis.

Phasellus magna purus, aliquet at ipsum ut, sollicitudin mollis arcu. Donec mollis aliquet auctor. Maecenas venenatis pulvinar accumsan. Suspendisse vel erat at diam molestie pellentesque. Mauris dapibus luctus massa, eu rutrum orci pellentesque quis. Suspendisse eget ligula maximus, vehicula erat dictum, egestas tellus. In eu risus eget mi rhoncus auctor. Nam mollis, nisi quis egestas accumsan, magna dui vehicula est, et porttitor lacus diam sit amet erat. Phasellus eu nunc vitae ligula faucibus aliquet. Fusce tempor sapien odio. Donec euismod, enim eu lacinia mollis, erat enim gravida risus, eu tincidunt eros felis sed justo. Cras et turpis nec nibh consectetur porta eget ac mi. Integer vel consequat tellus.

In a urna vitae ipsum ultricies dignissim. Nulla orci mi, tincidunt a tempor sit amet, efficitur at risus. Nullam ultricies mollis lacus at vulputate. Nulla sed suscipit ipsum, nec tempus nulla. Fusce a odio enim. Fusce quam ligula, molestie eu pellentesque eget, placerat ac ligula. Proin eleifend a turpis eu consequat.

Ut tristique id leo quis suscipit. Nunc quis nunc a velit scelerisque feugiat in quis risus. Pellentesque sit amet faucibus massa. Sed mollis arcu metus, vitae volutpat tellus porta iaculis. Nulla facilisi. In ut imperdiet odio. Suspendisse iaculis condimentum ante.

Sed condimentum, nibh eget scelerisque vulputate, quam est pellentesque nisl, volutpat dictum odio urna a felis. Phasellus pharetra libero leo, sed vulputate nisi gravida a. Aenean arcu ipsum, fermentum a malesuada sed, ultricies ut ante. In congue ultrices felis, ac aliquam tortor iaculis nec. Pellentesque at facilisis mi. Nunc eget arcu non enim fermentum sodales nec eget lacus. Vivamus pellentesque semper orci.

In tincidunt sem a nisl eleifend, non faucibus tellus aliquam. Nunc et massa at nisl pellentesque dignissim. Duis vel sagittis eros. Phasellus id leo volutpat tortor accumsan condimentum et semper ex. Mauris vitae tempus velit. Integer ac felis mollis erat aliquet sodales id eget sapien. Vivamus sem eros, vehicula at facilisis a, tempus sit amet metus. Cras et orci purus. Maecenas purus sem, suscipit et augue sit amet, placerat imperdiet justo. Cras consequat tempor ante. Sed venenatis porttitor nulla, sit amet aliquam erat molestie tempor.

Vivamus pulvinar tristique dui, luctus ultricies elit cursus ut. Praesent scelerisque, odio id faucibus accumsan, ligula eros pulvinar ipsum, nec cursus turpis mi eget ligula. Morbi lobortis ipsum a tortor volutpat varius. Morbi tincidunt nec nisl nec suscipit. Aenean et felis euismod felis pellentesque rutrum vitae sed ante. Morbi eget venenatis felis. Fusce volutpat erat vel nunc ultrices eleifend. Praesent ipsum risus, varius a neque maximus, condimentum rhoncus lacus. Mauris non tellus vestibulum, tempus ante a, malesuada augue. Vivamus dignissim est ut diam pulvinar faucibus sit amet nec metus. Sed imperdiet posuere est, vel vestibulum magna vestibulum at. Proin dignissim est ut diam tristique tristique. Aenean vel purus facilisis, mollis urna quis, fermentum lacus.
EOT;


$maxchar = $params['limit']; /* here we get the limit from our $params array */
$end='...'; /* this will be at the end in our string */


if (strlen($text) > $maxchar || $text == '') {
$words = preg_split('/\s/', $text);
$output = '';
$i = 0;
while (1) {
$length = strlen($output)+strlen($words[$i]);
if ($length > $maxchar) {
break;
}
else {
$output .= " " . $words[$i];
++$i;
}
}
$output .= $end;
}
else {
$output = $text;
}


$result = nl2br($output); /* formated text before sending back to our tpl */
return $result;
}
?>

Playground


function smarty_function_lorem(array $params, Smarty_Internal_Template $template)

{
$text = << Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a neque non nisl mollis porta. Vestibulum porta semper dolor, in pulvinar ipsum venenatis vehicula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce non condimentum nunc. Morbi sit amet dui ac nibh pulvinar cursus in sit amet augue. Donec tristique, lacus sollicitudin tristique bibendum, ante tellus pharetra nisl, eu vulputate ligula leo ut turpis. Nam eget sapien sed lorem gravida dictum ut ut lorem. Morbi tellus risus, porta egestas nulla vitae, egestas pharetra velit. Mauris dolor ante, sollicitudin et venenatis at, dignissim at mi. Duis et efficitur mauris. Praesent scelerisque vitae tellus sit amet aliquet. Pellentesque in tortor porta, tempus magna sit amet, auctor nisi. Donec dictum augue nisl, id feugiat turpis faucibus vel. Suspendisse potenti. In eu mattis velit, at varius quam.

Curabitur lobortis convallis magna, id iaculis velit accumsan vel. Aliquam congue porttitor mattis. Curabitur consequat nisl dui, ut accumsan mi elementum ut. Nam vitae sollicitudin lacus. Nulla rutrum odio nec metus pretium, eget convallis purus efficitur. Vestibulum et cursus nibh. Mauris tincidunt nunc fermentum felis ornare sodales. Curabitur tempus porta eros, non efficitur tortor consectetur ut. Maecenas ultricies, nunc at convallis fermentum, magna tortor posuere ex, efficitur auctor massa tellus at quam. Aliquam pretium ut quam nec iaculis. Fusce at leo hendrerit, venenatis nulla a, feugiat diam. Aenean volutpat accumsan elit. Etiam tellus nisl, scelerisque in hendrerit sit amet, semper vel lacus. Donec ultrices libero nec velit imperdiet, vel elementum sem pretium. Vestibulum sollicitudin augue lorem, at ultricies dui interdum sed. Suspendisse sollicitudin nisi in odio malesuada vehicula.

Sed venenatis quis justo vulputate lobortis. Aliquam mattis lacus eget ex ornare, sed tincidunt ligula iaculis. Nulla nisl neque, tincidunt ac scelerisque et, ultrices semper tellus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Aliquam sit amet velit ut odio vulputate ultrices. Nullam semper molestie ligula, quis pretium erat elementum et. Donec sed imperdiet tortor. Phasellus accumsan quis enim in venenatis. Cras enim diam, hendrerit ut nisl et, consequat luctus nulla. Vestibulum volutpat, magna elementum facilisis rhoncus, erat turpis sollicitudin nisi, quis placerat lectus magna eu leo. Etiam blandit nibh non lacus tristique luctus. Etiam interdum metus eu interdum commodo. Curabitur non varius nunc. Morbi a dui id lacus dictum vestibulum. Pellentesque vel sollicitudin ligula. Sed sed iaculis ligula, et elementum leo.

Cras tempus ipsum eget metus tempus, non faucibus nisl pretium. Maecenas ac leo diam. Pellentesque justo turpis, tristique ut viverra sit amet, sollicitudin vitae elit. Quisque dictum vel ante quis eleifend. Nam sit amet purus et risus rhoncus imperdiet. Curabitur dapibus porttitor est, sit amet varius lacus ornare nec. Quisque interdum id erat in maximus.

Etiam at blandit sem, a rhoncus magna. Etiam aliquam quam at massa facilisis volutpat. Phasellus non vulputate velit. Integer bibendum ornare dapibus. Mauris cursus dignissim massa at facilisis. Pellentesque eget feugiat dui. Ut eros nulla, pretium vel ullamcorper a, porta eget justo. Aenean congue ac leo vitae maximus. Curabitur lacinia, odio ac convallis condimentum, enim nulla tempus ante, non fringilla dui augue et turpis. Mauris in magna ac ligula eleifend egestas vitae at nibh.

Curabitur non quam malesuada, interdum tortor feugiat, finibus nunc. Integer interdum, sem ac posuere pulvinar, nisi orci accumsan ante, non vulputate eros turpis vel nisl. Aenean condimentum ultricies lorem quis condimentum. Aliquam erat volutpat. Cras massa eros, blandit nec tristique sit amet, auctor eget urna. Vivamus non felis eros. Duis risus lacus, eleifend id tincidunt non, vehicula a odio. Donec condimentum dignissim tempus. Interdum et malesuada fames ac ante ipsum primis in faucibus.

In laoreet maximus urna, efficitur maximus nulla ornare et. Donec nec dolor ultrices, ullamcorper justo at, interdum neque. Praesent gravida lectus nec quam ullamcorper commodo. Nam in tellus nec lacus pellentesque ultrices. In in mattis mi, non dignissim ipsum. In quis ligula a massa egestas ultrices. Morbi at libero hendrerit, blandit velit ut, lobortis ex. Vivamus non consequat orci, quis vestibulum turpis.

Cras aliquet vestibulum turpis ut lobortis. Cras consequat odio a nulla consectetur ornare. Duis sed ex non risus tincidunt fringilla. Suspendisse nec nisl eu risus luctus gravida id sed velit. Cras nec lorem iaculis, rhoncus diam vitae, egestas est. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec sagittis lectus. Quisque commodo erat massa, vitae venenatis felis sollicitudin in. Duis convallis, nunc a sodales imperdiet, enim nisl semper risus, et mattis velit urna quis ex. Etiam ullamcorper massa at tellus maximus aliquam. Nulla facilisi.

Sed varius bibendum mi. Phasellus vitae mattis justo. Proin ut enim nibh. Etiam eleifend blandit rutrum. Nunc sodales, massa vel mattis molestie, mi nunc congue nibh, a dictum turpis purus sed ante. Donec pretium lacinia metus, at varius sem pretium a. Mauris eu urna nec massa sodales rhoncus a sit amet augue. Nulla quis neque leo. Integer sit amet mauris tempus tellus hendrerit sagittis.

Phasellus magna purus, aliquet at ipsum ut, sollicitudin mollis arcu. Donec mollis aliquet auctor. Maecenas venenatis pulvinar accumsan. Suspendisse vel erat at diam molestie pellentesque. Mauris dapibus luctus massa, eu rutrum orci pellentesque quis. Suspendisse eget ligula maximus, vehicula erat dictum, egestas tellus. In eu risus eget mi rhoncus auctor. Nam mollis, nisi quis egestas accumsan, magna dui vehicula est, et porttitor lacus diam sit amet erat. Phasellus eu nunc vitae ligula faucibus aliquet. Fusce tempor sapien odio. Donec euismod, enim eu lacinia mollis, erat enim gravida risus, eu tincidunt eros felis sed justo. Cras et turpis nec nibh consectetur porta eget ac mi. Integer vel consequat tellus.

In a urna vitae ipsum ultricies dignissim. Nulla orci mi, tincidunt a tempor sit amet, efficitur at risus. Nullam ultricies mollis lacus at vulputate. Nulla sed suscipit ipsum, nec tempus nulla. Fusce a odio enim. Fusce quam ligula, molestie eu pellentesque eget, placerat ac ligula. Proin eleifend a turpis eu consequat.

Ut tristique id leo quis suscipit. Nunc quis nunc a velit scelerisque feugiat in quis risus. Pellentesque sit amet faucibus massa. Sed mollis arcu metus, vitae volutpat tellus porta iaculis. Nulla facilisi. In ut imperdiet odio. Suspendisse iaculis condimentum ante.

Sed condimentum, nibh eget scelerisque vulputate, quam est pellentesque nisl, volutpat dictum odio urna a felis. Phasellus pharetra libero leo, sed vulputate nisi gravida a. Aenean arcu ipsum, fermentum a malesuada sed, ultricies ut ante. In congue ultrices felis, ac aliquam tortor iaculis nec. Pellentesque at facilisis mi. Nunc eget arcu non enim fermentum sodales nec eget lacus. Vivamus pellentesque semper orci.

In tincidunt sem a nisl eleifend, non faucibus tellus aliquam. Nunc et massa at nisl pellentesque dignissim. Duis vel sagittis eros. Phasellus id leo volutpat tortor accumsan condimentum et semper ex. Mauris vitae tempus velit. Integer ac felis mollis erat aliquet sodales id eget sapien. Vivamus sem eros, vehicula at facilisis a, tempus sit amet metus. Cras et orci purus. Maecenas purus sem, suscipit et augue sit amet, placerat imperdiet justo. Cras consequat tempor ante. Sed venenatis porttitor nulla, sit amet aliquam erat molestie tempor.

Vivamus pulvinar tristique dui, luctus ultricies elit cursus ut. Praesent scelerisque, odio id faucibus accumsan, ligula eros pulvinar ipsum, nec cursus turpis mi eget ligula. Morbi lobortis ipsum a tortor volutpat varius. Morbi tincidunt nec nisl nec suscipit. Aenean et felis euismod felis pellentesque rutrum vitae sed ante. Morbi eget venenatis felis. Fusce volutpat erat vel nunc ultrices eleifend. Praesent ipsum risus, varius a neque maximus, condimentum rhoncus lacus. Mauris non tellus vestibulum, tempus ante a, malesuada augue. Vivamus dignissim est ut diam pulvinar faucibus sit amet nec metus. Sed imperdiet posuere est, vel vestibulum magna vestibulum at. Proin dignissim est ut diam tristique tristique. Aenean vel purus facilisis, mollis urna quis, fermentum lacus.
EOT;

$maxchar = $params['limit'];
$end='...';


if (strlen($text) > $maxchar || $text == '') {
$words = preg_split('/\s/', $text);
$output = '';
$i = 0;
while (1) {
$length = strlen($output)+strlen($words[$i]);
if ($length > $maxchar) {
break;
}
else {
$output .= " " . $words[$i];
++$i;
}
}
$output .= $end;
}
else {
$output = $text;
}


$result = nl2br($output);
return $result;

?>

Ok now lets go ahead and star making a real plugin that we can really use for thi plugin we can chose to use GD or Imagemagick, I will use Imagemagick why because is faster.
but you can choose the one you like.
lets first name our function thumbmagick.
and set some params lets think what we want our function to do with our image.
lets start with the following params:

source = this is for the url "path" where our image is located.
w = the width in px that we want our image to be resized.
h = the height in px that we cant our image to be resized.
q = image quality that we want.

so in our tpl the function call will be like this {thumbmagick source="path_to_image/image.jpg" w=300 h=300 q=90}

<?php
function smarty_function_thumbmagick($params, $template)
{

if (empty($params['source'])) {
trigger_error("thumbmagick: missing 'source' parameter", E_USER_NOTICE); /* we neeed some kind of error handling so this parameter can not be empty right */
return;
} else {
$source = $params['source']; /* if everything went ok, the here we have our path to the image */
}


$images_folder = "thumbs/"; /* folder where we will save our new resized images */

/* lets create a folder to save our thumbs you can skip this section if you already created a folder to save the thumbs */
if (!(is_dir($images_folder))) {
mkdir($images_folder, 0777, true) or die("Unable to make directory: " . $images_folder);
}


$convert = '/usr/bin/convert'; /* Where is Imagemagick: this could be something like /usr/bin/convert or /opt/local/share/bin/convert */

/* Lets get the image file extension here we are going to need it later to name our new file */
$fileParts = explode('.', $source);
$count = count($fileParts) - 1;
$ext = $fileParts[$count];

$filename = md5_file($source); /* change the file name to MD5 */
$SavePath = $images_folder . $filename . '_w' . $w . '_h'.$h. '.' . $ext; /* here will have the full path with the new file name we use the width and height to name our file */

/* time to resize our image and save it. */
exec($convert." ".$source." -resize ".$w."x".$h."^ -gravity center -crop ".$w."x".$h."+0+0 +repage -quality ".$params['q']." ".$SavePath);


return $SavePath; /* here we return the new image so the result will look something like this "thumbs/imagewithnewname.jpg" */

}
?>

Playground


function smarty_function_thumbmagick($params, $template)
{

if (empty($params['source'])) {
trigger_error("thumbmagick: missing 'source' parameter", E_USER_NOTICE); /* we neeed some kind of error handling so this parameter can not be empty right */
return;
} else {
$source = $params['source']; /* if everything went ok, the here we have our path to the image */
}


$images_folder = "thumbs/"; /* folder where we will save our new resized images */

/* lets create a folder to save our thumbs you can skip this section if you already created a folder to save the thumbs */
if (!(is_dir($images_folder))) {
mkdir($images_folder, 0777, true) or die("Unable to make directory: " . $images_folder);
}


$convert = '/usr/bin/convert'; /* Where is Imagemagick: this could be something like /usr/bin/convert or /opt/local/share/bin/convert */

/* Lets get the image file extension here we are going to need it later to name our new file */
$fileParts = explode('.', $source);
$count = count($fileParts) - 1;
$ext = $fileParts[$count];

$filename = md5_file($source); /* change the file name to MD5 */
$SavePath = $images_folder . $filename . '_w' . $w . '_h'.$h. '.' . $ext; /* here will have the full path with the new file name we use the width and height to name our file */

/* time to resize our image and save it. */
exec($convert." ".$source." -resize ".$w."x".$h."^ -gravity center -crop ".$w."x".$h."+0+0 +repage -quality ".$params['q']." ".$SavePath);


return $SavePath; /* here we return the new image so the result will look something like this "thumbs/imagewithnewname.jpg" */

}
?>
{thumbmagick source="path_to_image/image.jpg" w=300 h=300 q=90}

Ok so we have just created a smarty plugin to create thumbs, if you test the plugin you will see how simple its to create thumbs this way, but there is something wrong with this plugin, one of the things if you analize the plugin its that every time you call the plugin it will create the thumbs, so if the thumb its already created why not just return the created thumb instead of recreating the thumb you are right we need the plugin to check if the thumb is already create just return the thumb.

so here we will go one step forward. Say hi to Smarty cache, thats what we are going to do create a cache folder to store our thumbs.
so lets add and make some changes to our plugin.

<?php
function smarty_function_thumbmagick($params, $template)
{
if (empty($params['source'])) {
trigger_error("thumbmagick: missing 'source' parameter", E_USER_NOTICE);
/* we neeed some kind of error handling so this parameter can not be empty right */
return;
} else {
$source = $params['source'];
/* if everything went ok, then here we have our path to the image */
}
if (!isset($params['w'])) { /* check if we recive w if not then just declare null */
$w = null;
} else {
$w = $params['w'];
}
if (!isset($params['h'])) { /* check if we recive h if not then just declare null */
$h = null;
} else {
$h = $params['h'];
}
if (!isset($params['q'])) { /* check if we recive q if not then just assign 90 as default quality */
$q = 90;
} else {
$q = $params['q'];
}


$images_folder = "thumbs/";
/* folder where we will save our new resized images */
/* lets create a folder to save our thumbs you can skip this section if you already created a folder to save the thumbs */
if (!(is_dir($images_folder))) {
mkdir($images_folder, 0777, true) or die("Unable to make directory: " . $images_folder);
}
$convert = '/usr/bin/convert';
/* Where is Imagemagick: this could be something like /usr/bin/convert or /opt/local/share/bin/convert */
/* Lets get the image file extension here we are going to need it later to name our new file */
$fileParts = explode('.', $source);
$count = count($fileParts) - 1;
$ext = $fileParts[$count];
$filename = md5_file($source);
/* change the file name to MD5 */
/*
-This is the first change, now we are creating some options to name our file depending on what params we recive,
-we will use this as a reference to check if the thumb already exists
but also create some other option to resize our image, like if we only recive w then h will be auto or viceversa.
*/
if (!empty($w) and !empty($h)) {
$SavePath = $images_folder . $filename . '_w' . $w . '_h' . $h . '.' . $ext;
/* if we recive w and h this will handle the name */
} elseif (!empty($w)) {
$SavePath = $images_folder . $filename . '_w' . $w . '.' . $ext;
/* if we recive only w this will handle the name */
} elseif (!empty($h)) {
$SavePath = $images_folder . $filename . '_h' . $h . '.' . $ext;
/* if we recive only h this will handle the name */
} else {
return false;
}
$CreateThumb = true;
/* lets define this var as true first */
/* lets check if the thumb was created before so we can just return the thumb */
if (file_exists($SavePath) == true) {
$CreateThumb = false;
$origFileTime = date("YmdHis", filemtime($source));
$newFileTime = date("YmdHis", filemtime($SavePath));
if ($newFileTime < $origFileTime) {
$CreateThumb = true;
}
}
if ($CreateThumb == true) { /* if the thumb doesn't exist lets just created ok */
if (!empty($w) and !empty($h)) {
exec($convert . " " . $source . " -resize " . $w . "x" . $h . "^ -gravity center -crop " . $w . "x" . $h . "+0+0 +repage -quality " . $q . " " . $SavePath);
} elseif (!empty($w)) {
exec($convert . " " . $source . " -thumbnail " . $w . " -quality " . $q . " " . $SavePath);
} elseif (!empty($h)) {
exec($convert . " " . $source . " -thumbnail x" . $h . " -quality " . $q . " " . $SavePath);
}
}
/*
here is another important part to make changes, so we are returning the new file, so I just want to show the image lets make a var to return the image.
*/
$result = '<img src="' . $SavePath . '"/>';
return $result;
/* here we return the new image so the result will look something like this "<img src="thumbs/imagewithnewname.jpg"> */
}
?>

Playground


function smarty_function_thumbmagick($params, $template)
{
if (empty($params['source'])) {
trigger_error("thumbmagick: missing 'source' parameter", E_USER_NOTICE);
/* we neeed some kind of error handling so this parameter can not be empty right */
return;
} else {
$source = $params['source'];
/* if everything went ok, then here we have our path to the image */
}
if (!isset($params['w'])) { /* check if we recive w if not then just declare null */
$w = null;
} else {
$w = $params['w'];
}
if (!isset($params['h'])) { /* check if we recive h if not then just declare null */
$h = null;
} else {
$h = $params['h'];
}
if (!isset($params['q'])) { /* check if we recive q if not then just assign 90 as default quality */
$q = 90;
} else {
$q = $params['q'];
}
$images_folder = "thumbs/";
/* folder where we will save our new resized images */
/* lets create a folder to save our thumbs you can skip this section if you already created a folder to save the thumbs */
if (!(is_dir($images_folder))) {
mkdir($images_folder, 0777, true) or die("Unable to make directory: " . $images_folder);
}
$convert = '/usr/bin/convert';
/* Where is Imagemagick: this could be something like /usr/bin/convert or /opt/local/share/bin/convert */
/* Lets get the image file extension here we are going to need it later to name our new file */
$fileParts = explode('.', $source);
$count = count($fileParts) - 1;
$ext = $fileParts[$count];
$filename = md5_file($source);
/* change the file name to MD5 */
/*
-This is the first change, now we are creating some options to name our file depending on what params we recive,
-we will use this as a reference to check if the thumb already exists
but also create some other option to resize our image, like if we only recive w then h will be auto or viceversa.
*/
if (!empty($w) and !empty($h)) {
$SavePath = $images_folder . $filename . '_w' . $w . '_h' . $h . '.' . $ext;
/* if we recive w and h this will handle the name */
} elseif (!empty($w)) {
$SavePath = $images_folder . $filename . '_w' . $w . '.' . $ext;
/* if we recive only w this will handle the name */
} elseif (!empty($h)) {
$SavePath = $images_folder . $filename . '_h' . $h . '.' . $ext;
/* if we recive only h this will handle the name */
} else {
return false;
}
$CreateThumb = true;
/* lets define this var as true first */
/* lets check if the thumb was created before so we can just return the thumb */
if (file_exists($SavePath) == true) {
$CreateThumb = false;
$origFileTime = date("YmdHis", filemtime($source));
$newFileTime = date("YmdHis", filemtime($SavePath));
if ($newFileTime < $origFileTime) {
$CreateThumb = true;
}
}
if ($CreateThumb == true) { /* if the thumb doesn't exist lets just created ok */
if (!empty($w) and !empty($h)) {
exec($convert . " " . $source . " -resize " . $w . "x" . $h . "^ -gravity center -crop " . $w . "x" . $h . "+0+0 +repage -quality " . $q . " " . $SavePath);
} elseif (!empty($w)) {
exec($convert . " " . $source . " -thumbnail " . $w . " -quality " . $q . " " . $SavePath);
} elseif (!empty($h)) {
exec($convert . " " . $source . " -thumbnail x" . $h . " -quality " . $q . " " . $SavePath);
}
}
/*
here is another important part to make changes, so we are returning the new file, so I just want to show the image lets make a var to return the image.
*/
$result = '';
return $result;
/* here we return the new image so the result will look something like this " */
}
?>

THIS SECTION IS NO FINISH YET: STATUS:WORKING IN THIS AREA

So we have a working thumb plugin, now let's extend more our plugin to make it more dynamic I want to add a few more options.
ImageMagick has lots of options we can use, but I also want my plugin to be light and efective, so I just want some option that I need, but you can extend this plugin still more if you know ImageMagick.

I will add the following optios to the plugin to make is more dynamic:

1.-cache folder -> to define where we want to save our thumbs.
2.- crop -> I we want to crop our thumb
3.- html -> maybe we want to send the image alt or title or class or something related to html
4.- Link -> if we want the image to have a link
5.- Cache time -> How long we want our thumb to be recreated again.
6.- remote images -> I want this to plugin to be able to handle remote images also.
7.- reflection -> I want my thums to have reflection as an option why because css reflection its kind slow.
8.- Return -> I want to control how thumbs are sent back to our tpl maybe somethimes I just need the image and path, or maybe I want to add some extra html to like a wrapper to our image.
9.- pngquant -> I also want to compress the thumbs if they are png to save space and to make my website faster.
10.- defaults -> I will probably define some default values so if I dont send ex. cache folder or crop etc. must be some default values.
and a few more options check the php code to see them all.


and this is what we are going to do now ok so let's go to work.
Like I said if you have any questions, or an idea to add something else to this plugin Ideas are welcome ok.


this is how or call function will look now with the following options.

{thumbmagick source="path_to_image/image.jpg" w=300 h=300 q=90 crop=true link="http://someurl.com" html=' class="some_clas" ' cache="somefolder/" cachetime="6" reflection=true compress=true }


This are our new params:

if (!isset($params['crop']))$params['crop'] = null; /* to handle or crop */
if (!isset($params['htmloptions']))$params['htmloptions'] = null; /* html options */
if (!isset($params['link']))$params['link'] = null; /* if url link */
if (!isset($params['cache']))$params['cache'] = null; /* or cache folder */
if (!isset($params['watermark']))$params['watermark'] = null; /* check if we want a watermark */
if (!isset($params['rtn']))$params['rtn'] = null; /* our return style */
if (!isset($params['compress']))$params['compress'] = null; /* if we want to compress our png files */
if (!isset($params['reflect']))$params['reflect'] = null; /* if we want the reflection effect in our thumbs */
if (empty($params['cache_time']))$params['cache_time'] = 14444; /* cache lifetime */
if (isset($params['reflect'])){ /* if reflection lets create default rgba transparent color values */
if (empty($params['reflect_top']))$params['reflect_top'] ="232,232,232,0.1";
if (empty($params['reflect_bottom']))$params['reflect_bottom'] = "0,0,0,1";
}


/*
The Internet has many images that you may wish to download and copy. But they may be protected by copyright laws. If so, downloading one to your computer is illegal and you could face penalties, both federal and civil, even if you don't print the image. Although many websites have copyright information at the bottom of their pages, it's not required for the images to be protected. It's up to you to find out if they are.
*/
$purl = parse_url($params['source']);
if (isset($purl['scheme']) && ($purl['scheme'] == 'http' || $purl['scheme'] == 'https')):
/* We need a folder to download and store our remote images before we can create the thumb */
if (empty($params['remote'])) {
$params['remote'] = 'remote/';
}
$remote_images = $params['remote'];
if (!(is_dir($remote_images))) {
mkdir($remote_images, 0777, true) or die("Unable to make directory: " . $params['remote']);
}
$finfo = pathinfo($source);
list($filename) = explode('?', $finfo['basename']);
$local_filepath = $remote_images . $filename;
$download = true;
if (file_exists($local_filepath)):
if (filemtime($local_filepath) < strtotime('+' . $cache_lifetime . ' minutes')):
$download = false;
endif;
endif;
if ($download == true):
$img = file_get_contents($source);
file_put_contents($local_filepath, $img);
endif;
$source = $local_filepath;
endif;
if (file_exists($source) == false) {
$source = $_SERVER['DOCUMENT_ROOT'] . $source;
if (file_exists($source) == false) {
return 'image not found';
}
}



How to use this plugin?
create a file in your plugins folder: function.thumbmagick.php
copy and paste the contents in php code.
That's all

Use it like this:
{thumbmagick source="image.png" compress=true w=600} /* image will be resize to 600px width and compressed
{thumbmagick source="image.jpg" h=500 w=600} /* image will be resized to 600px width and 500px height
{thumbmagick source="image.png"} /* image will be resized to 480px width
{thumbmagick source="image.jpg" w=300 html=" title='image title' class='someclass' "} /* image will have a class and a title with 300px width
{thumbmagick source="media/hotest.jpg" w=400 h=400 linkurl="http://www.somedoain.com" window=true } /* image has a link with 400px width and height
you cann see all the options in the plugin info.

Playground


/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {thumbmagick} function plugin
* Type: function
* Name: thumbmagick
* Date: Mar 02, 2019
* Purpose: Create image thumbs
* Examples: {thumbmagick source="/images/demo1.jpg" w=400}
* Output:
* Params:
*
* - source - (required) - file (and path) of image
* - h - (optional) - image height (default actual height)
* - w - (optional) - image width (default actual width)
* - c - (optional) - crop ex. crop=true
* - q - (optional) - image quality ex. q=90 (0 to 100)
* - s - (optional) - scale ex. s=true
* - m - (optional) - Max only ex. m=true
* - html - (optional) - html to include in the image tag html=" itemprop='image' class='' alt='' title='' "
* - link - (optional) - link=true, you need to specify the linkurl (true or false)
* - linkurl - (optional) - Add a link to the image (default to image source)
* - linkclass - (optional) - linkclass="someclass" Add a a class to the image link . if you need to add more styles use linkhtml
* - linkhtml - (optional) - linkhtml=" class='' title='' " adds html to the link

* - window - (optional) - ex. window=true, if linkurl Opens the link in a new window target="_blank" (default target="_self")
* - friendly_url - (optional) - friendly_url=true (true or false) Add a friendly link to the image (default false)
* - friendly_url_link - (optional) - Add a friendly link to the image (friendly url: ex domain.com/myimage)
* - rtn - (optional) - rtn=true returns only the image path without
* - reflect - (optional) - reflect=true adds reflection effect to the image need 3 more values. (default false) must have w and h
* - reflect_topc - rgba value ex. reflect_topc="232,232,232,0.1"
* - reflect_bottomc - rgba value ex. reflect_topc="0,0,0,1"
* - reflect_height - reflect_height=30 (values in px)
* - cache_time - Cache lifetime before the thumb will be recreated ex. cache_time=1 (1=1day , default to 1 day)
* - cache - (optional) specify a cache folder for the thumbs (default cache/)
* - remote - (optional) specify a download folder for remote images (default remote/)
* - compress - (optional) compress=true if image ext png you can enable compression (default false)
*
* @link https://www.wkwebbuilder.com/index.php?action=ViewBlogArticle&id=8 {thumbmagick}
* @author Jaime Gonzalez
* @version 1.0
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @throws SmartyException
* @return string
*/
function smarty_function_thumbmagick($params, $template)
{
if (empty($params['source'])) {
trigger_error("thumbmagick: missing 'source' parameter", E_USER_NOTICE);
return;
} else {
$source = $params['source'];
}
if (!isset($params['w']))
$params['w'] = null;
if (!isset($params['h']))
$params['h'] = null;
if (!isset($params['q']))
$params['q'] = 90;
/* quality will default to 90 if we don't specify it */
if (!isset($params['c']))
$params['c'] = false;
/* crop the image */
if (!isset($params['s']))
$params['s'] = false;
/* scale the image */
if (!isset($params['m']))
$params['m'] = null;
if (!isset($params['html']))
$params['html'] = null;
if (!isset($params['linkurl']))
$params['linkurl'] = null;
if (!isset($params['friendly_url']))
$params['friendly_url'] = null;
if (!isset($params['friendly_url_link']))
$params['friendly_url_link'] = null;
if (!isset($params['rtn']))
$params['rtn'] = null;
if (!isset($params['link']))
$params['link'] = true;
/* if we don't specify a link by default will be the image link */
if (!isset($params['linkclass']))
$params['linkclass'] = false;
if (!isset($params['linkhtml']))
$params['linkhtml'] = false;
if (!isset($params['window']))
$params['window'] = false;
if (!isset($params['reflect']))
$params['reflect'] = null;
if (!isset($params['cache_time']))
$params['cache_time'] = 1;
/* default to 1 day */
if (!isset($params['cache']))
$params['cache'] = 'cache/';
if (!isset($params['remote']))
$params['remote'] = 'remote/';
/* lets create some default values just in case */
if (empty($params['w']) and empty($params['h'])) {
/* if we don't specify w and h then the thumb will be resize to 480px width change this value as youu need */
$params['w'] = 480;
}
$w = $params['w'];
$h = $params['h'];
$q = $params['q'];
$cache_lifetime = $params['cache_time'];
$cacheFolder = $params['cache'];
$convert = '/usr/bin/convert'; # this could be something like /usr/bin/convert or /opt/local/share/bin/convert
if (isset($params['reflect'])) {
if (empty($params['reflect_topc']))
$params['reflect_topc'] = "232,232,232,0.1";
/* rgba values start from top */
if (empty($params['reflect_bottomc']))
$params['reflect_bottomc'] = "0,0,0,1";
/* rgba values start from bottom */
if (empty($params['reflect_height']))
$params['reflect_height'] = 100;
/* default to 100 px */
}
$check_dir_cache = $params['cache'];
if (!(is_dir($check_dir_cache))) {
mkdir($check_dir_cache, 0777, true) or die("Unable to make directory: " . $params['cache']);
}
$purl = parse_url($params['source']);
/* let's parse the image path to see if it has http or https meaning is a remote image */
if (isset($purl['scheme']) && ($purl['scheme'] == 'http' || $purl['scheme'] == 'https')):
$finfo = pathinfo($source);
list($filename) = explode('?', $finfo['basename']);
$local_filepath = $params['remote'] . $filename;
$download_image = true;
if (file_exists($local_filepath)):
if (filemtime($local_filepath) < strtotime('+' . $cache_lifetime . ' days')): /* you can change this value to minutes, hours, weeks, months, */
$download_image = false;
endif;
endif;
if ($download_image == true):
$img = file_get_contents($source);
file_put_contents($local_filepath, $img);
endif;
$source = $local_filepath;
endif;
if (file_exists($source) == false) {
$source = $_SERVER['DOCUMENT_ROOT'] . $source;
if (file_exists($source) == false) {
return 'image not found';
}
}
$fileParts = explode('.', $source);
$count = count($fileParts) - 1;
$ext = $fileParts[$count];
if (isset($params['reflect']) && $params['reflect'] == true) {
$ext = "png";
}
$imgPath = str_replace('.' . $ext, '', $source);
$filename = md5_file($source);
if (!empty($w) and !empty($h)) {
$SavePath = $cacheFolder . $filename . '_w' . $w . '_h' . $h . (isset($params['reflect']) && $params['reflect'] == true ? "_rf" : "") . (isset($params['c']) && $params['c'] == true ? "_cp" : "") . (isset($params['s']) && $params['s'] == true ? "_sc" : "") . '.' . $ext;
} elseif (!empty($w)) {
$SavePath = $cacheFolder . $filename . '_w' . $w . (isset($params['reflect']) && $params['reflect'] == true ? "_rf" : "") . '.' . $ext;
} elseif (!empty($h)) {
$SavePath = $cacheFolder . $filename . '_h' . $h . (isset($params['reflect']) && $params['reflect'] == true ? "_rf" : "") . '.' . $ext;
} else {
return false;
}
$create = true;
if (file_exists($SavePath) == true) {
$create = false;
$origFileTime = date("YmdHis", filemtime($source));
$newFileTime = date("YmdHis", filemtime($SavePath));
if ($newFileTime < $origFileTime) {
$create = true;
}
}
if ($create == true) {
if (isset($params['reflect']) && $params['reflect'] == true) {
$tmedia = "tmpimage_" . rand() . ".jpg";
$TempImage = $params['cache'] . "/" . $tmedia;
if (!empty($w) and !empty($h)) {
exec($convert . " " . $source . " -resize " . $w . "x" . $h . "^ -gravity center -crop " . $w . "x" . $h . "+0+0 +repage -quality " . $params['q'] . " " . $TempImage);
} elseif (!empty($w)) {
exec($convert . " " . $source . " -resize " . $w . "x +0+0 +repage ^ -gravity center -quality " . $params['q'] . " " . $TempImage);
} elseif (!empty($h)) {
exec($convert . " " . $source . " -resize x" . $h . "+0+0 +repage ^ -gravity center -quality " . $params['q'] . " " . $TempImage);
}
list($tw, $th, $type, $attr) = getimagesize($TempImage);
$reflect_topc = $params['reflect_topc'];
$reflect_bottomc = $params['reflect_bottomc'];
$reflect_height = $params['reflect_height'];
if (empty($params['reflect_height'])) {
$params['reflect_height'] = $th / 3.5;
}
$ImgHeight = $params['reflect_height'] + $th;
exec($convert . " " . $TempImage . " -alpha on \( +clone -flip -size " . $tw . "x" . $reflect_height . " 'gradient:rgba(" . $reflect_topc . ")-rgba(" . $reflect_bottomc . ")' -alpha off -compose CopyOpacity -composite \) -channel rgba -append -gravity North -crop " . $tw . "x" . $ImgHeight . "+0-5\!\ -background none -compose Over -flatten " . $SavePath);
unlink($TempImage);
} else {
if (!empty($w) and !empty($h)) {
list($width, $height) = getimagesize($source);
$resize = $w;
if ($width > $height) {
$resize = $w;
if (isset($params['c']) && $params['c'] == true) {
$resize = "x" . $h;
}
} else {
$resize = "x" . $h;
if (isset($params['c']) && $params['c'] == true) {
$resize = $w;
}
}
if (isset($params['s']) && $params['s'] == true) {
exec($convert . " " . $source . " -resize " . $resize . " -quality " . $params['q'] . " " . $SavePath);
} else {
exec($convert . " " . $source . " -resize " . $w . "x" . $h . "^ -gravity center -crop " . $w . "x" . $h . "+0+0 +repage -quality " . $params['q'] . " " . $SavePath);
}
} elseif (!empty($w)) {
exec($convert . " " . $source . " -thumbnail " . $w . "" . (isset($params['m']) && $params['m'] == true ? "\>" : "") . " -quality " . $params['q'] . " " . $SavePath);
} elseif (!empty($h)) {
exec($convert . " " . $source . " -thumbnail x" . $h . "" . (isset($params['m']) && $params['m'] == true ? "\>" : "") . " -quality " . $params['q'] . " " . $SavePath);
}
}

/* To use pngquant you must install it first in your server https://pngquant.org/ */
if ($ext == "png" and $params['compress'] == true) {
/* If image extension is png and compress = true lets compress the image */
$pngquant = '/usr/bin/pngquant';
$max_quality = 80;
$min_quality = 65;
$CompressThumb = shell_exec($pngquant." --quality=".$min_quality."-".$max_quality." --skip-if-larger --force --ext .png ".$SavePath);
}
}
# return cache file path
$_DST['string'] = ' rel="' . $source . '" width="' . $w . '" height="' . $h . '"';
if (empty($params['html']))
$_RETURN['img'] = '';
else
$_RETURN['img'] = '';
list($nwidth, $nheight, $type, $attr) = getimagesize($SavePath);
if ($params['link'] == true) {
if (isset($params['friendly_url_link']) && !empty($params['friendly_url_link'])) {
if ($params['friendly_url'] == true) {
$link = $params['friendly_url_link'];
}
} elseif (isset($params['linkurl']) && !empty($params['linkurl'])) {
$link = $params['linkurl'];
} else {
$link = $source;
}
if (isset($params['linkclass']) && !empty($params['linkclass'])) {
$lnclass = "class='" . $params['linkclass'] . "'";
} else {
$lnclass = "";
}
if (isset($params['linkhtml']) && !empty($params['linkhtml'])) {
$linkhtml = $params['linkhtml'];
} else {
$linkhtml = "";
}
if ($params['window'] == true)
$result = '
' . $_RETURN['img'] . '';
elseif ($params['rtn'] == true)
$result = $SavePath;
elseif ($params['rtnstyle'] == true)
$result = 'style="width:100%;height:' . $nheight . 'px"';
else
$result = '' . $_RETURN['img'] . '';
} else {
$result = $_RETURN['img'];
}
return $result;
}
?>
{thumbmagick source="path_to_image/image.jpg" w=300 h=300 q=90 c=true link="http://someurl.com" html=' class="some_clas" ' cache="somefolder/" cachetime="6" reflection=true compress=true}