added caching, force compile, force cache, misc performance updates

This commit is contained in:
mohrt
2001-01-30 21:54:59 +00:00
parent b915dd35b1
commit 0e589508f7
4 changed files with 245 additions and 62 deletions

8
NEWS
View File

@@ -1,10 +1,10 @@
- fixed bug that would not respect nested template directories and would
put all compiled files into top-level one. (Andrei)
Version 1.2.2 Version 1.2.2
------------- -------------
- fixed bug using $PHP_VERSION instead of environment var PHP_VERSION. - fixed bug that would not respect nested template directories and would
- couple small warning fixes put all compiled files into top-level one. (Andrei)
- fixed bug using $PHP_VERSION instead of environment var PHP_VERSION.
- couple small warning fixes
Version 1.2.1 Version 1.2.1
------------- -------------

View File

@@ -47,17 +47,32 @@ class Smarty
// This is generally set to false once the // This is generally set to false once the
// application is entered into production and // application is entered into production and
// initially compiled. Leave set to true // initially compiled. Leave set to true
// during development. // during development. true/false
var $compile_force = false; // force templates to compile every time.
// overrides compile_check. true/false
var $allow_url_compile = true; // allow forced recompile from URL ?compile_force=1
// NOTE: all cache directives override
// compiling directives. If a cached version
// is available, that will be used regardless
// of compile settings.
var $cache_engine = true; // whether to use caching or not. true/false
var $cache_expire = 5; // number of seconds cached content will expire.
// 0 = never expires. default is one hour (3600)
var $cache_force = false; // force caches to expire every time. true/false
var $allow_url_cache = true; // allow forced cache expire from URL ?cache_force=1
var $template_dir = "./templates"; // name of directory for templates var $template_dir = "./templates"; // name of directory for templates
var $compile_dir = "./templates_c"; // name of directory for compiled templates var $compile_dir = "./templates_c"; // name of directory for compiled templates
var $cache_dir = "./cache"; // name of directory for template cache
var $tpl_file_ext = ".tpl"; // template file extentions var $tpl_file_ext = ".tpl"; // template file extentions
var $allow_php = false; // whether or not to allow embedded php var $allow_php = false; // whether or not to allow embedded php
// in the templates. By default, php tags // in the templates. By default, php tags
// are escaped. // are escaped. true/false
var $left_delimiter = "{"; // template tag delimiters. var $left_delimiter = "{"; // template tag delimiters.
var $right_delimiter = "}"; var $right_delimiter = "}";
@@ -83,7 +98,7 @@ class Smarty
); );
// internal vars // internal vars
var $_error_msg = false; // error messages var $_error_msg = false; // error messages. true/false
var $_tpl_vars = array(); var $_tpl_vars = array();
var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part
var $_literal_blocks = array(); // keeps literal template blocks var $_literal_blocks = array(); // keeps literal template blocks
@@ -183,13 +198,7 @@ class Smarty
function display($tpl_file) function display($tpl_file)
{ {
// compile files print $this->fetch($tpl_file);
$this->_compile($this->template_dir);
//assemble compile directory path to file
$_compile_file = $this->compile_dir.'/'.$tpl_file.'.php';
extract($this->_tpl_vars);
include($_compile_file);
} }
/*======================================================================*\ /*======================================================================*\
@@ -199,10 +208,49 @@ class Smarty
function fetch($tpl_file) function fetch($tpl_file)
{ {
global $HTTP_GET_VARS,$PHP_SELF;
if($this->cache_engine)
{
if($this->allow_url_cache && $HTTP_GET_VARS["cache_force"])
$this->cache_force = true;
// cache id = template path + the invoked script
$cache_file = $this->cache_dir."/".urlencode($tpl_file."@".$PHP_SELF).".che";
if(!$this->cache_force &&
(file_exists($cache_file) &&
($this->cache_expire == 0 ||
(mktime() - filectime($cache_file) <= $this->cache_expire)
)))
{
echo "DEBUG: using cache<br>\n";
$results = $this->_read_file($cache_file);
$results = $this->_process_cached_inserts($results);
return $results;
}
}
echo "DEBUG: not using cache<br>\n";
if($this->allow_url_compile && $HTTP_GET_VARS["compile_force"])
$this->compile_force = true;
ob_start(); ob_start();
$this->display($tpl_file); // compile files
$results = ob_get_contents(); $this->_compile($this->template_dir);
//assemble compile directory path to file
$_compile_file = $this->compile_dir."/".$tpl_file.".php";
extract($this->_tpl_vars);
include($_compile_file);
$results = ob_get_contents();
ob_end_clean(); ob_end_clean();
if($this->cache_engine)
{
$this->_write_file($cache_file,$results);
$results = $this->_process_cached_inserts($results);
}
return $results; return $results;
} }
@@ -213,7 +261,7 @@ class Smarty
function _compile($tpl_dir) function _compile($tpl_dir)
{ {
if($this->compile_check) if($this->compile_check || $this->compile_force)
{ {
if($this->_traverse_files($tpl_dir, 0)) if($this->_traverse_files($tpl_dir, 0))
return true; return true;
@@ -222,8 +270,8 @@ class Smarty
} }
else else
return false; return false;
} }
/*======================================================================*\ /*======================================================================*\
Function: _traverse_files() Function: _traverse_files()
Purpose: traverse the template files & process each one Purpose: traverse the template files & process each one
@@ -241,7 +289,8 @@ class Smarty
$filepath = $tpl_dir."/".$curr_file; $filepath = $tpl_dir."/".$curr_file;
if(is_readable($filepath)) { if(is_readable($filepath)) {
if(is_file($filepath) && preg_match('!' . preg_quote($this->tpl_file_ext, '!') . '$!', $curr_file)) {
if(is_file($filepath) && substr($curr_file,-strlen($this->tpl_file_ext)) == $this->tpl_file_ext) {
if(!$this->_process_file($filepath)) if(!$this->_process_file($filepath))
return false; return false;
} else if(is_dir($filepath)) { } else if(is_dir($filepath)) {
@@ -291,8 +340,8 @@ class Smarty
} }
} }
// compile the template file if none exists or has been modified // compile the template file if none exists or has been modified or compile_force
if (!file_exists($compile_dir."/".$tpl_file_name) || if (!file_exists($compile_dir."/".$tpl_file_name) || $this->compile_force ||
($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) { ($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) {
if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name)) if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name))
return false; return false;
@@ -383,6 +432,44 @@ class Smarty
return true; return true;
} }
function _process_cached_inserts($results)
{
preg_match_all("/\{\{\{insert_cache name=([^ ]+) (.*)\}\}\}/Uis",$results,$match);
$fulltags = $match[0];
$names = $match[1];
$args = $match[2];
for($curr_tag = 0; $curr_tag < count($fulltags); $curr_tag++)
{
$attrs = $this->_parse_attrs($args[$curr_tag]);
$name = substr($attrs['name'], 1, -1);
if (empty($names[$curr_tag])) {
$this->_syntax_error("missing insert name");
}
foreach ($attrs as $arg_name => $arg_value) {
if ($arg_name == 'name') continue;
if (is_bool($arg_value))
$arg_value = $arg_value ? 'true' : 'false';
$arg_list[] = "'$arg_name' => $arg_value";
}
$evalcode = "print insert_".$names[$curr_tag]."(array(".implode(',', (array)$arg_list)."));";
ob_start();
eval($evalcode);
$replace = ob_get_contents();
ob_end_clean();
$results = str_replace($fulltags[$curr_tag],$replace,$results);
}
return $results;
}
function _compile_tag($template_tag) function _compile_tag($template_tag)
{ {
/* Matched comment. */ /* Matched comment. */
@@ -468,7 +555,6 @@ class Smarty
} }
} }
function _compile_custom_tag($tag_command, $tag_args) function _compile_custom_tag($tag_command, $tag_args)
{ {
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
@@ -482,12 +568,14 @@ class Smarty
return "<?php $function(array(".implode(',', (array)$arg_list).")); ?>"; return "<?php $function(array(".implode(',', (array)$arg_list).")); ?>";
} }
function _compile_insert_tag($tag_args) function _compile_insert_tag($tag_args)
{ {
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
$name = substr($attrs['name'], 1, -1); $name = substr($attrs['name'], 1, -1);
if($this->cache_engine)
return "<?php print \"{{{insert_cache ".addslashes($tag_args)."}}}\"; ?>";
if (empty($name)) { if (empty($name)) {
$this->_syntax_error("missing insert name"); $this->_syntax_error("missing insert name");
} }
@@ -500,9 +588,8 @@ class Smarty
} }
return "<?php print insert_$name(array(".implode(',', (array)$arg_list).")); ?>"; return "<?php print insert_$name(array(".implode(',', (array)$arg_list).")); ?>";
} }
function _compile_config_load_tag($tag_args) function _compile_config_load_tag($tag_args)
{ {
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);

View File

@@ -14,7 +14,7 @@
<address><email>andrei@ispi.net</email></address> <address><email>andrei@ispi.net</email></address>
</affiliation> </affiliation>
</author> </author>
<edition>Version 1.2.1</edition> <edition>Version 1.2.2</edition>
<copyright><year>2001</year><holder>ispi of Lincoln, Inc.</holder></copyright> <copyright><year>2001</year><holder>ispi of Lincoln, Inc.</holder></copyright>
</bookinfo> </bookinfo>
<chapter> <chapter>
@@ -1129,26 +1129,26 @@ e-mail: jane@mydomain.com
{* This is an example of printing an associative array {* This is an example of printing an associative array
of data within a section *} of data within a section *}
{section name=customer loop=$contacts} {section name=customer loop=$contacts}
{$customer/contacts.name}&lt;br&gt; name: {$customer/contacts.name}&lt;br&gt;
{$customer/contacts.home}&lt;br&gt; home: {$customer/contacts.home}&lt;br&gt;
{$customer/contacts.cell}&lt;br&gt; cell: {$customer/contacts.cell}&lt;br&gt;
{$customer/contacts.email}&lt;br&gt; e-mail: {$customer/contacts.email}&lt;p&gt;
{/section} {/section}
OUTPUT: OUTPUT:
name: John Smith&lt;br&gt; name: John Smith&lt;br&gt;
home: 555-555-5555&lt;p&gt; home: 555-555-5555&lt;br&gt;
cell: 555-555-5555&lt;p&gt; cell: 555-555-5555&lt;br&gt;
e-mail: john@mydomain.com&lt;p&gt; e-mail: john@mydomain.com&lt;p&gt;
name: Jack Jones&lt;br&gt; name: Jack Jones&lt;br&gt;
home phone: 555-555-5555&lt;p&gt; home phone: 555-555-5555&lt;br&gt;
cell phone: 555-555-5555&lt;p&gt; cell phone: 555-555-5555&lt;br&gt;
e-mail: jack@mydomain.com&lt;p&gt; e-mail: jack@mydomain.com&lt;p&gt;
name: Jane Munson&lt;p&gt; name: Jane Munson&lt;br&gt;
home phone: 555-555-5555&lt;p&gt; home phone: 555-555-5555&lt;br&gt;
cell phone: 555-555-5555&lt;p&gt; cell phone: 555-555-5555&lt;br&gt;
e-mail: jane@mydomain.com&lt;p&gt; e-mail: jane@mydomain.com&lt;p&gt;
@@ -1934,6 +1934,15 @@ function makeTimeStamp($year="",$month="",$day="")
</example> </example>
</sect1> </sect1>
</chapter> </chapter>
<chapter id="resources">
<title>Resources</title>
<para>
Smarty's homepage is located at http://www.phpinsider.com/php/code/Smarty/.
You can join the mailing list by sending an e-mail to
subscribe-smarty@lists.ispi.net. An archive of the mailing list can be
viewed at http://marc.theaimsgroup.com/ under www/smarty.
</para>
</chapter>
<chapter id="bugs"> <chapter id="bugs">
<title>BUGS</title> <title>BUGS</title>
<para> <para>

View File

@@ -47,17 +47,32 @@ class Smarty
// This is generally set to false once the // This is generally set to false once the
// application is entered into production and // application is entered into production and
// initially compiled. Leave set to true // initially compiled. Leave set to true
// during development. // during development. true/false
var $compile_force = false; // force templates to compile every time.
// overrides compile_check. true/false
var $allow_url_compile = true; // allow forced recompile from URL ?compile_force=1
// NOTE: all cache directives override
// compiling directives. If a cached version
// is available, that will be used regardless
// of compile settings.
var $cache_engine = true; // whether to use caching or not. true/false
var $cache_expire = 5; // number of seconds cached content will expire.
// 0 = never expires. default is one hour (3600)
var $cache_force = false; // force caches to expire every time. true/false
var $allow_url_cache = true; // allow forced cache expire from URL ?cache_force=1
var $template_dir = "./templates"; // name of directory for templates var $template_dir = "./templates"; // name of directory for templates
var $compile_dir = "./templates_c"; // name of directory for compiled templates var $compile_dir = "./templates_c"; // name of directory for compiled templates
var $cache_dir = "./cache"; // name of directory for template cache
var $tpl_file_ext = ".tpl"; // template file extentions var $tpl_file_ext = ".tpl"; // template file extentions
var $allow_php = false; // whether or not to allow embedded php var $allow_php = false; // whether or not to allow embedded php
// in the templates. By default, php tags // in the templates. By default, php tags
// are escaped. // are escaped. true/false
var $left_delimiter = "{"; // template tag delimiters. var $left_delimiter = "{"; // template tag delimiters.
var $right_delimiter = "}"; var $right_delimiter = "}";
@@ -83,7 +98,7 @@ class Smarty
); );
// internal vars // internal vars
var $_error_msg = false; // error messages var $_error_msg = false; // error messages. true/false
var $_tpl_vars = array(); var $_tpl_vars = array();
var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part
var $_literal_blocks = array(); // keeps literal template blocks var $_literal_blocks = array(); // keeps literal template blocks
@@ -183,13 +198,7 @@ class Smarty
function display($tpl_file) function display($tpl_file)
{ {
// compile files print $this->fetch($tpl_file);
$this->_compile($this->template_dir);
//assemble compile directory path to file
$_compile_file = $this->compile_dir.'/'.$tpl_file.'.php';
extract($this->_tpl_vars);
include($_compile_file);
} }
/*======================================================================*\ /*======================================================================*\
@@ -199,10 +208,49 @@ class Smarty
function fetch($tpl_file) function fetch($tpl_file)
{ {
global $HTTP_GET_VARS,$PHP_SELF;
if($this->cache_engine)
{
if($this->allow_url_cache && $HTTP_GET_VARS["cache_force"])
$this->cache_force = true;
// cache id = template path + the invoked script
$cache_file = $this->cache_dir."/".urlencode($tpl_file."@".$PHP_SELF).".che";
if(!$this->cache_force &&
(file_exists($cache_file) &&
($this->cache_expire == 0 ||
(mktime() - filectime($cache_file) <= $this->cache_expire)
)))
{
echo "DEBUG: using cache<br>\n";
$results = $this->_read_file($cache_file);
$results = $this->_process_cached_inserts($results);
return $results;
}
}
echo "DEBUG: not using cache<br>\n";
if($this->allow_url_compile && $HTTP_GET_VARS["compile_force"])
$this->compile_force = true;
ob_start(); ob_start();
$this->display($tpl_file); // compile files
$results = ob_get_contents(); $this->_compile($this->template_dir);
//assemble compile directory path to file
$_compile_file = $this->compile_dir."/".$tpl_file.".php";
extract($this->_tpl_vars);
include($_compile_file);
$results = ob_get_contents();
ob_end_clean(); ob_end_clean();
if($this->cache_engine)
{
$this->_write_file($cache_file,$results);
$results = $this->_process_cached_inserts($results);
}
return $results; return $results;
} }
@@ -213,7 +261,7 @@ class Smarty
function _compile($tpl_dir) function _compile($tpl_dir)
{ {
if($this->compile_check) if($this->compile_check || $this->compile_force)
{ {
if($this->_traverse_files($tpl_dir, 0)) if($this->_traverse_files($tpl_dir, 0))
return true; return true;
@@ -222,8 +270,8 @@ class Smarty
} }
else else
return false; return false;
} }
/*======================================================================*\ /*======================================================================*\
Function: _traverse_files() Function: _traverse_files()
Purpose: traverse the template files & process each one Purpose: traverse the template files & process each one
@@ -241,7 +289,8 @@ class Smarty
$filepath = $tpl_dir."/".$curr_file; $filepath = $tpl_dir."/".$curr_file;
if(is_readable($filepath)) { if(is_readable($filepath)) {
if(is_file($filepath) && preg_match('!' . preg_quote($this->tpl_file_ext, '!') . '$!', $curr_file)) {
if(is_file($filepath) && substr($curr_file,-strlen($this->tpl_file_ext)) == $this->tpl_file_ext) {
if(!$this->_process_file($filepath)) if(!$this->_process_file($filepath))
return false; return false;
} else if(is_dir($filepath)) { } else if(is_dir($filepath)) {
@@ -291,8 +340,8 @@ class Smarty
} }
} }
// compile the template file if none exists or has been modified // compile the template file if none exists or has been modified or compile_force
if (!file_exists($compile_dir."/".$tpl_file_name) || if (!file_exists($compile_dir."/".$tpl_file_name) || $this->compile_force ||
($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) { ($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) {
if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name)) if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name))
return false; return false;
@@ -383,6 +432,44 @@ class Smarty
return true; return true;
} }
function _process_cached_inserts($results)
{
preg_match_all("/\{\{\{insert_cache name=([^ ]+) (.*)\}\}\}/Uis",$results,$match);
$fulltags = $match[0];
$names = $match[1];
$args = $match[2];
for($curr_tag = 0; $curr_tag < count($fulltags); $curr_tag++)
{
$attrs = $this->_parse_attrs($args[$curr_tag]);
$name = substr($attrs['name'], 1, -1);
if (empty($names[$curr_tag])) {
$this->_syntax_error("missing insert name");
}
foreach ($attrs as $arg_name => $arg_value) {
if ($arg_name == 'name') continue;
if (is_bool($arg_value))
$arg_value = $arg_value ? 'true' : 'false';
$arg_list[] = "'$arg_name' => $arg_value";
}
$evalcode = "print insert_".$names[$curr_tag]."(array(".implode(',', (array)$arg_list)."));";
ob_start();
eval($evalcode);
$replace = ob_get_contents();
ob_end_clean();
$results = str_replace($fulltags[$curr_tag],$replace,$results);
}
return $results;
}
function _compile_tag($template_tag) function _compile_tag($template_tag)
{ {
/* Matched comment. */ /* Matched comment. */
@@ -468,7 +555,6 @@ class Smarty
} }
} }
function _compile_custom_tag($tag_command, $tag_args) function _compile_custom_tag($tag_command, $tag_args)
{ {
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
@@ -482,12 +568,14 @@ class Smarty
return "<?php $function(array(".implode(',', (array)$arg_list).")); ?>"; return "<?php $function(array(".implode(',', (array)$arg_list).")); ?>";
} }
function _compile_insert_tag($tag_args) function _compile_insert_tag($tag_args)
{ {
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
$name = substr($attrs['name'], 1, -1); $name = substr($attrs['name'], 1, -1);
if($this->cache_engine)
return "<?php print \"{{{insert_cache ".addslashes($tag_args)."}}}\"; ?>";
if (empty($name)) { if (empty($name)) {
$this->_syntax_error("missing insert name"); $this->_syntax_error("missing insert name");
} }
@@ -500,9 +588,8 @@ class Smarty
} }
return "<?php print insert_$name(array(".implode(',', (array)$arg_list).")); ?>"; return "<?php print insert_$name(array(".implode(',', (array)$arg_list).")); ?>";
} }
function _compile_config_load_tag($tag_args) function _compile_config_load_tag($tag_args)
{ {
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);