diff --git a/NEWS b/NEWS index 64ee18d0..efbdb5aa 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ Version 1.4.0 ------------- + - added template filters (Monte) - added RELEASE_NOTES file to distribution (Monte) - added register_resource() and unregister_resource() functions (Monte) - changed syntax of variables called within section loops, diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 8c69e71f..9ee3f9fb 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,18 +1,22 @@ 1.4.0 ----- -IMPORTANT NOTICE: Smarty now has a new syntax for accessing elements within -section loops. The new syntax is easier to use for complex data structures. -Consequently, this breaks the old syntax. To fix your current templates, we -have provided a script that will adjust the syntax for you. Located in -misc/fix_vars.php, run this script from the the command line, giving each -template as an argument. Be sure to use absolute pathnames, or pathnames +IMPORTANT NOTICE + +Smarty now has a new syntax for accessing elements within section loops. The +new syntax is easier to use and nicely handles data structures of any +complexity. Consequently, this breaks the old syntax. To fix your current +templates, we have provided a script that will adjust the syntax for you. +Located in misc/fix_vars.php, run this script from the the command line, giving +each template as an argument. Be sure to use absolute pathnames, or pathnames relative to the executing script. Probably the easiest way to do this is to copy the fix_vars.php script into your template directory and run 'php -q fix_vars.php *.tpl' Be sure you have proper write permission, and backup your scripts first to be safe! The examples in the 1.4.0 documentation have been updated to reflect the changes. +NEW AND IMPROVED COMPILER + Smarty 1.4.0 also has a new compilation process. Instead of compiling all the templates up front, it now compiles them at runtime. This has several advantages. First of all, there is no longer a need to have a single template @@ -23,9 +27,12 @@ being executed instead of everything found in the template directory. The $tpl_file_ext is no longer needed, but kept for backward compatability. Templates can now be named anything you like with any extension. +MINOR FIXES + A workaround for LOCK_EX on Windows systems was added, and changed a couple of -file permissions for better security on public servers. Thanks goes to Fernando -Nunes for his code contributions. +file permissions for better security on public servers. + +CHANGES/ENHANCEMENTS date_format, html_select_date and html_select_time used to require a unix timestamp as the format of the date passed into the template. Smarty is now a @@ -33,6 +40,12 @@ bit smarter at this. It will take a unix timestamp, a mysql timestamp, or any date string that is parsable by strtotime, such as 10/01/2001 or 2001-10-01, etc. Just give some formats a try and see what works. +Smarty now has template filters, meaning that you can run your templates +through custom functions before they are compiled. This is good for things like +removing unwanted comments, "beautifiying" your template code, keep an eye on +words or functionality people are putting in templates, translating XML -> +HTML, etc. See the register_filter documentation for more info. + The format of the files created in the $compile_dir are now a bit different. Instead of reflecting the name and path of the source template, it uses an encoded file name, all in the top level directory. This was done to make way @@ -40,6 +53,8 @@ for arbitrary template resources. Each compiled template has a header that states what template resource was used to create it. From a unix command prompt, you can use "head -2 *" to see the first two lines of each file. +UPGRADE NOTES + When upgrading to 1.4.0, you will want to first clear out all your files in the $compile_dir, since it now uses a new format. If you have $compile_check set to false and the compiled template does not yet exist, it will compile it diff --git a/Smarty.class.php b/Smarty.class.php index 1f7de4db..c189f13e 100644 --- a/Smarty.class.php +++ b/Smarty.class.php @@ -128,6 +128,9 @@ class Smarty var $compiler_class = 'Smarty_Compiler'; // the compiler class used by // Smarty to compile templates + var $resource_functions = array(); // what functions resource handlers are mapped to + var $filter_functions = array(); // what functions templates are filtered through + // before being compiled /**************************************************************************/ /* END SMARTY CONFIGURATION SECTION */ @@ -138,7 +141,6 @@ class Smarty var $_error_msg = false; // error messages. true/false var $_tpl_vars = array(); var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty' - var $_resource_handlers = array(); // what functions resource handlers are mapped to /*======================================================================*\ Function: Smarty @@ -253,7 +255,7 @@ class Smarty \*======================================================================*/ function register_resource($name, $function_name) { - $this->_resource_handlers[$name] = $function_name; + $this->resource_functions[$name] = $function_name; } /*======================================================================*\ @@ -262,9 +264,33 @@ class Smarty \*======================================================================*/ function unregister_resource($name) { - unset($this->_resource_handlers[$name]); + unset($this->resource_functions[$name]); } +/*======================================================================*\ + Function: register_filter + Purpose: Registers a filter function to apply + to a template before compiling +\*======================================================================*/ + function register_filter($function_name) + { + $this->filter_functions[] = $function_name; + } + +/*======================================================================*\ + Function: unregister_filter + Purpose: Unregisters a filter +\*======================================================================*/ + function unregister_filter($function_name) + { + $tmp_array = array(); + foreach($this->filter_functions as $curr_func) { + if($curr_func != $function_name) { + $tmp_array[] = $curr_func; + } + } + $this->filter_functions = $tmp_array; + } /*======================================================================*\ Function: clear_cache() @@ -390,17 +416,19 @@ class Smarty if ($display) { echo $results; return; - } else + } else { return $results; + } } } extract($this->_tpl_vars); - if ($this->show_info_header) + if ($this->show_info_header) { $info_header = ''."\n\n"; - else - $info_header = ""; + } else { + $info_header = ""; + } // if we just need to display the results, don't perform output // buffering - for speed @@ -408,8 +436,7 @@ class Smarty echo $info_header; $this->_process_template($tpl_file, $compile_path); include($compile_path); - } - else { + } else { ob_start(); echo $info_header; $this->_process_template($tpl_file, $compile_path); @@ -543,8 +570,8 @@ class Smarty } break; default: - if(isset($this->_resource_handlers[$resource_type])) { - $funcname = $this->_resource_handlers[$resource_type]; + if(isset($this->resource_functions[$resource_type])) { + $funcname = $this->resource_functions[$resource_type]; if(function_exists($funcname)) { // call the function to fetch the template $funcname($resource_name,$template_source,$template_timestamp); @@ -585,6 +612,7 @@ class Smarty $smarty_compiler->custom_funcs = $this->custom_funcs; $smarty_compiler->custom_mods = $this->custom_mods; $smarty_compiler->version = $this->version; + $smarty_compiler->filter_functions = $this->filter_functions; if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled)) return true; diff --git a/Smarty_Compiler.class.php b/Smarty_Compiler.class.php index 8fad285f..61092a88 100644 --- a/Smarty_Compiler.class.php +++ b/Smarty_Compiler.class.php @@ -53,6 +53,16 @@ class Smarty_Compiler extends Smarty { \*======================================================================*/ function _compile_file($tpl_file, $template_source, &$template_compiled) { + // run template source through functions registered in filter_functions + if(is_array($this->filter_functions) && count($this->filter_functions) > 0) { + foreach($this->filter_functions as $curr_func) { + if(function_exists($curr_func)) { + $template_source = $curr_func($template_source); + } else { + $this->_trigger_error_msg("filter function $curr_func does not exist."); + } + } + } $this->_current_file = $template_source; $this->_current_line_no = 1; diff --git a/docs.sgml b/docs.sgml index d3808b51..7fdb41f1 100644 --- a/docs.sgml +++ b/docs.sgml @@ -779,6 +779,49 @@ $smarty->register_resource("db","get_db_template"); $smarty->unregister_resource("db"); + + + + + register_filter + + + void register_filter + string function_name + + + + Use this to dynamically register filters to run templates + through before they are compiled. See template filters for + more information on how to setup a filtering function. + + +register_filter + + +$smarty->register_filter("remove_dw_comments"); + + + + + + unregister_filter + + + void unregister_filter + string function_name + + + + Use this to dynamically unregister a filter. + + +unregister_filter + + +$smarty->unregister_filter("imbed_asp_jokes"); + @@ -979,9 +1022,11 @@ echo $output; // from PHP script $smarty->display("index.tpl"); $smarty->display("admin/menu.tpl"); +$smarty->display("file:admin/menu.tpl"); // same as one above {* from within Smarty template *} {include file="index.tpl"} +{include file="file:index.tpl"} {* same as one above *} @@ -1015,10 +1060,10 @@ $smarty->display("file:/path/to/my/templates/menu.tpl"); retrieving templates from a database. You do this by first registering your resource handler function, then creating your function to get the template. Smarty expects your function to be of - this form: funcname($tpl_name,&tpl_source, &$tpl_timestamp) {} $tpl - name is passed into the function, and your function should populate - $tpl_source and $tpl_timestamp with the template source and the - last modified time of the template respectively. + this form: funcname($tpl_name,&tpl_source, &$tpl_timestamp) + {} $tpl_name is passed into the function, and your function should + populate $tpl_source and $tpl_timestamp with the template source + and the last modified time of the template respectively. @@ -1046,6 +1091,45 @@ $smarty->display("db:index.tpl"); {* using resource from within Smarty template *} {include file="db:/extras/navigation.tpl"} + + + + + + Smarty Template Filters + + Template filters are PHP functions that your templates are ran through + before they are compiled. This is good for preprocessing your templates + to remove unwanted comments, "beautify" the template code, keep an eye + on what people are putting in their templates, etc. Filters are + processed in the order they are registered. + + + Example of a Template Filter + + Create a function in your application that Smarty will use as a + template filter. Smarty will pass the template source code as the + first argument, an expect the function to return the resulting + template source code. + + + +using a template filter + + +// put this in your application, or in Smarty.addons.php +function remove_dw_comments($tpl_source) { + return preg_replace("/<!--#.*-->/U","",$tpl_source); +} + +// register the filter +$smarty->register_filter("remove_dw_comments"); +$smarty->display("index.tpl"); + +{* from within Smarty template *} +<!--# this line will get removed by the filter --> + @@ -3745,7 +3829,7 @@ function makeTimeStamp($year="",$month="",$day="") A special thanks goes to the members of the php-template mailing list and - the smarty mailing list, whom shared and brought many ideas to the table. + the smarty mailing list, whom sharing and bringing many ideas to the table. Rasmus Lerdorf <rasmus@php.net>: For starting what eventually became diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 1f7de4db..c189f13e 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -128,6 +128,9 @@ class Smarty var $compiler_class = 'Smarty_Compiler'; // the compiler class used by // Smarty to compile templates + var $resource_functions = array(); // what functions resource handlers are mapped to + var $filter_functions = array(); // what functions templates are filtered through + // before being compiled /**************************************************************************/ /* END SMARTY CONFIGURATION SECTION */ @@ -138,7 +141,6 @@ class Smarty var $_error_msg = false; // error messages. true/false var $_tpl_vars = array(); var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty' - var $_resource_handlers = array(); // what functions resource handlers are mapped to /*======================================================================*\ Function: Smarty @@ -253,7 +255,7 @@ class Smarty \*======================================================================*/ function register_resource($name, $function_name) { - $this->_resource_handlers[$name] = $function_name; + $this->resource_functions[$name] = $function_name; } /*======================================================================*\ @@ -262,9 +264,33 @@ class Smarty \*======================================================================*/ function unregister_resource($name) { - unset($this->_resource_handlers[$name]); + unset($this->resource_functions[$name]); } +/*======================================================================*\ + Function: register_filter + Purpose: Registers a filter function to apply + to a template before compiling +\*======================================================================*/ + function register_filter($function_name) + { + $this->filter_functions[] = $function_name; + } + +/*======================================================================*\ + Function: unregister_filter + Purpose: Unregisters a filter +\*======================================================================*/ + function unregister_filter($function_name) + { + $tmp_array = array(); + foreach($this->filter_functions as $curr_func) { + if($curr_func != $function_name) { + $tmp_array[] = $curr_func; + } + } + $this->filter_functions = $tmp_array; + } /*======================================================================*\ Function: clear_cache() @@ -390,17 +416,19 @@ class Smarty if ($display) { echo $results; return; - } else + } else { return $results; + } } } extract($this->_tpl_vars); - if ($this->show_info_header) + if ($this->show_info_header) { $info_header = ''."\n\n"; - else - $info_header = ""; + } else { + $info_header = ""; + } // if we just need to display the results, don't perform output // buffering - for speed @@ -408,8 +436,7 @@ class Smarty echo $info_header; $this->_process_template($tpl_file, $compile_path); include($compile_path); - } - else { + } else { ob_start(); echo $info_header; $this->_process_template($tpl_file, $compile_path); @@ -543,8 +570,8 @@ class Smarty } break; default: - if(isset($this->_resource_handlers[$resource_type])) { - $funcname = $this->_resource_handlers[$resource_type]; + if(isset($this->resource_functions[$resource_type])) { + $funcname = $this->resource_functions[$resource_type]; if(function_exists($funcname)) { // call the function to fetch the template $funcname($resource_name,$template_source,$template_timestamp); @@ -585,6 +612,7 @@ class Smarty $smarty_compiler->custom_funcs = $this->custom_funcs; $smarty_compiler->custom_mods = $this->custom_mods; $smarty_compiler->version = $this->version; + $smarty_compiler->filter_functions = $this->filter_functions; if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled)) return true; diff --git a/libs/Smarty_Compiler.class.php b/libs/Smarty_Compiler.class.php index 8fad285f..61092a88 100644 --- a/libs/Smarty_Compiler.class.php +++ b/libs/Smarty_Compiler.class.php @@ -53,6 +53,16 @@ class Smarty_Compiler extends Smarty { \*======================================================================*/ function _compile_file($tpl_file, $template_source, &$template_compiled) { + // run template source through functions registered in filter_functions + if(is_array($this->filter_functions) && count($this->filter_functions) > 0) { + foreach($this->filter_functions as $curr_func) { + if(function_exists($curr_func)) { + $template_source = $curr_func($template_source); + } else { + $this->_trigger_error_msg("filter function $curr_func does not exist."); + } + } + } $this->_current_file = $template_source; $this->_current_line_no = 1; diff --git a/misc/fix_vars.php b/misc/fix_vars.php index f531e89e..e3c0c0ef 100644 --- a/misc/fix_vars.php +++ b/misc/fix_vars.php @@ -24,10 +24,7 @@ foreach (array_slice($argv, 1) as $template) { die("\nError: could not open $template.out for writing\n\n"); } - if (strnatcmp(PHP_VERSION, '4.0.5') > 0) - $output = preg_replace_callback('!\$(\w+(\.\w+)?/)*\w+(?>\.\w+)*(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*!', 'fix_var', $input); - else - $output = preg_replace('!\$(\w+(\.\w+)?/)*\w+(?>\.\w+)*(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*!F', 'fix_var', $input); + $output = preg_replace('!\$(\w+(\.\w+)?/)*\w+(?>\.\w+)*(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*!F', 'fix_var', $input); fwrite($fp, $output); fclose($fp); @@ -40,7 +37,7 @@ foreach (array_slice($argv, 1) as $template) { function fix_var($match) { $var_expr = $match[0]; - + list($var_ref, $modifiers) = explode('|', substr($var_expr, 1), 2); $sections = explode('/', $var_ref);