Developer's Corner - Smarty Pre- and Post-filters - By Matt Hornsby


While upgrading some old 1.x websites recently I encountered a couple of problems that needed a quick and simple solution. Like most things related to CMS Made Simple, there are many ways to tackle a problem, but I thought this would be a fun opportunity to look into Smarty pre- and post-filters.

Category: Tutorials, Geek, General
Posted: February 14, 2019 by scotch33

Problem 1: Content pasted from Microsoft Word

When an editor pastes in content from Word without cleaning it up first, it often includes a lot of extra formatting code. For this particular client, the code included curly braces "{mso-style-name:..." in hundreds of pages. Certainly I could have done a database find & replace, but why not try something different this time?

A Smarty Prefilter plugin is executed on each template before it is compiled into PHP code. This is perfect, as anything post-render (e.g. using |replace on the content block) wouldn't remove the rendering error. Like other Smarty plugins, they live in the /assets/plugins folder. The naming scheme is prefilter.mypluginname.php. Here's the code I used:

<?php
function smarty_prefilter_fix_word($tpl_output, $template)

    return preg_replace("|{mso|",'{ mso',$tpl_output);
}
?>


I saved the file as prefilter.fix_word.php, put it in the assets/plugins folder, and voila - the problem is gone. It simply adds a space after the curly brace, which tells Smarty that it is not a Smarty tag. Of course for efficiency, it would make sense to remove all of the cruft, either through a careful SQL query or expanding the regular expression above to be more thorough, but this got a downed-site back up in moments at minimal cost to the client. 

Problem 2: Hardcoded http image urls in content blocks

This was a very old site, and included hundreds of <img> tags in the content which used the full url to the image instead of a path, resulting in them all being loaded via http instead of https. This caused mixed-content issues when the site was viewed via https, and again needed a quick fix that didn't include a database find & replace.

This time, a post-filter is needed as it isn't a rendering issue.  post-filters are executed on each template AFTER it is compiled to PHP code. This goes in the same place as the prefilter, and is just as simple. Here's the code:

<?php
function smarty_postfilter_https($tpl_output, $template)
{
    return str_replace('http://my-site.com','https://my-site.com',$tpl_output);
}
?>

The file was saved as postfilter.https.php in the plugins folder, and, again, problem solved in minutes.

Notes

-Smarty pre- and post-filters are applied to ALL templates, not just page templates, so it's important to be specific. In the pre-filter I originally had it stripping the entire <style> block, but this could interfere with modules such as CGCalendar which include <style> blocks in their templates.

-The point of this article isn't to say this is the best method for the above examples. There are better and more robust options to clean the offending code, but this is a simple, quick fix and illustrates how these plugins can be used.


Our Partners: