Source code for file /pattemplate/patTemplate/Compiler.php
Documentation is available at Compiler.php
* Compiler for patTemplate
* $Id: Compiler.php 206 2004-05-14 16:49:34Z schst $
* WARNING: This is still experimental!
// Check to ensure this file is within the rest of the framework
* Compiler for patTemplate
* $Id: Compiler.php 206 2004-05-14 16:49:34Z schst $
* WARNING: This is still experimental!
* @todo implement all template types
* @todo implement variable modifiers
* @todo implement getParsedTemplate
* @todo check for existing compiled template
* list of all templates that already have been compiled
var $_compiledTemplates =
array();
* file pointer to the compiled template
* Creates a new patTemplate Compiler
* @param string type of the templates, either 'html' or 'tex'
$GLOBALS['patTemplate_Compiler'] =
&$this;
* compile the currently loaded templates
* @param string name of the input (filename, shm segment, etc.)
function compile( $compileName =
null )
$this->_varRegexp =
'/'.
$this->_startTag.
'([^a-z:]+)'.
$this->_endTag.
'/U';
$this->_depRegexp =
'/'.
$this->_startTag.
'TMPL:([^a-z:]+)'.
$this->_endTag.
'/U';
$compileFolder =
$this->getOption( 'compileFolder' );
$compileFile =
sprintf( '%s/%s', $compileFolder, $compileName );
$this->_fp =
fopen( $compileFile, 'w' );
$this->_addToCode( ' * compiled patTemplate file' );
foreach( $this->_templates as $template =>
$spec )
include_once $compileFile;
* @param string name of the template
if( !isset
( $this->_templates[$template] ) )
"Template '$name' does not exist."
* check, if the template has been loaded
* and load it if necessary.
if( $this->_templates[$template]['loaded'] !==
true )
if( $this->_templates[$template]['attributes']['parse'] ==
'on' )
$result =
$this->readTemplatesFromInput( $this->_templates[$template]['attributes']['src'], $this->_templates[$template]['attributes']['reader'], null, $template );
$result =
$this->loadTemplateFromInput( $this->_templates[$template]['attributes']['src'], $this->_templates[$template]['attributes']['reader'], $template );
$this->_addToCode( ' * Compiled version of '.
$template );
$this->_addToCode( ' * Template type is '.
$this->_templates[$template]['attributes']['type'] );
$this->_addToCode( '$this->_prepareCompiledTemplate( "'.
$template.
'" );', 1 );
$this->_addToCode( '$this->prepareTemplate( "'.
$template.
'" );', 1 );
$this->_addToCode( '$this->_templates["'.
$template.
'"]["attributes"] = unserialize( \''.
serialize($this->_templates[$template]['attributes']).
'\' );', 1, 'Read the attributes' );
$this->_addToCode( '$this->_templates["'.
$template.
'"]["copyVars"] = unserialize( \''.
serialize($this->_templates[$template]['copyVars']).
'\' );', 1, 'Read the copyVars' );
$this->_addToCode( 'if( $this->_templates["'.
$template.
'"]["attributes"]["visibility"] != "hidden" ) {', 1, 'Check, whether template is hidden' );
$this->_addToCode( '$this->_templates["'.
$template.
'"]["iteration"] = 0;', 2, 'Reset the iteration' );
$this->_addToCode( '$loop = count( $this->_vars["'.
$template.
'"]["rows"] );', 2, 'Get the amount of loops' );
$this->_addToCode( '$loop = max( $loop, 1 );', 2 );
$this->_addToCode( '$this->_templates["'.
$template.
'"]["loop"] = $loop;', 2 );
$this->_addToCode( 'for( $i = 0; $i < $loop; $i++ ) {', 2, 'Traverse all variables.' );
$this->_addToCode( 'unset( $this->_templates["'.
$template.
'"]["vars"] );', 3 );
$this->_addToCode( '$this->_fetchVariables("'.
$template.
'");', 3 );
* different templates have to be compiled differently
switch( $this->_templates[$template]['attributes']['type'] )
$this->_compileModuloTemplate( $template );
* simple condition template
$this->_compileSimpleConditionTemplate( $template );
$this->_compileConditionTemplate( $template );
$this->_compileStandardTemplate( $template );
$this->_addToCode( '$this->_templates["'.
$template.
'"]["iteration"]++;', 3 );
array_push( $this->_compiledTemplates, $template );
* compile a standard template
* @param string name of the template
function _compileStandardTemplate( $template )
$content =
$this->_templateToPHP( $this->_templates[$template]['content'], $template );
* compile a modulo template
* A modulo template will be compiled into a switch/case
* @param string name of the template
* @todo check special conditions (__first, __last, __default)
function _compileModuloTemplate( $template )
$this->_compileBuiltinConditions( $template );
$this->_addToCode( 'if( !$_displayed ) {', 3, 'Builtin condition has been displayed?' );
$this->_addToCode( 'switch( ( $this->_templates["'.
$template.
'"]["iteration"] + 1 ) % '.
$this->_templates[$template]['attributes']['modulo'].
' ) {', 4 );
foreach( $this->_templates[$template]['subtemplates'] as $condition =>
$spec )
$content =
$this->_templateToPHP( $spec['data'], $template );
* compile a simpleCondition template
* A simpleCondition template will be compiled into an 'if'
* @param string name of the template
function _compileSimpleConditionTemplate( $template )
foreach( $this->_templates[$template]['attributes']['requiredvars'] as $var )
array_push( $conditions, 'isset( $this->_templates["'.
$template.
'"]["vars"]["'.
$var.
'"] )' );
$this->_addToCode( 'if( '.
implode( ' && ', $conditions ).
' ) {', 3, 'Check for required variables' );
$content =
$this->_templateToPHP( $this->_templates[$template]['content'], $template );
* compile a condition template
* A condition template will be compiled into an 'switch/case'
* @param string name of the template
function _compileConditionTemplate( $template )
$this->_compileBuiltinConditions( $template );
$this->_addToCode( 'if( !$_displayed ) {', 3, 'Builtin condition has been displayed?' );
$this->_addToCode( 'switch( $this->_templates["'.
$template.
'"]["vars"]["'.
$this->_templates[$template]["attributes"]["conditionvar"].
'"] ) {', 4 );
foreach( $this->_templates[$template]['subtemplates'] as $condition =>
$spec )
if( $condition ==
'__default' )
$content =
$this->_templateToPHP( $spec['data'], $template );
* compile built-in conditions
* This will create the neccessary PHP code for:
* @param string template name
function _compileBuiltinConditions( $template )
if( isset
( $this->_templates[$template]['subtemplates']['__first'] ) )
$this->_addToCode( 'if( $this->_templates["'.
$template.
'"]["iteration"] == 0 ) {', 3, 'Check for first entry' );
$content =
$this->_templateToPHP( $this->_templates[$template]['subtemplates']['__first']['data'], $template );
if( isset
( $this->_templates[$template]['subtemplates']['__last'] ) )
$this->_addToCode( 'if( $this->_templates["'.
$template.
'"]["iteration"] == ($this->_templates["'.
$template.
'"]["loop"]-1) ) {', 3, 'Check for last entry' );
$content =
$this->_templateToPHP( $this->_templates[$template]['subtemplates']['__last']['data'], $template );
* build PHP code from a template
* This will replace the variables in a template with
* @param string template content
* @param string name of the template
* @return string PHP code
function _templateToPHP( $content, $template )
$content =
preg_replace( $this->_varRegexp, '<?PHP echo $this->_getVar( "'.
$template.
'", "$1"); ?>', $content );
$content =
preg_replace( $this->_depRegexp, '<?PHP compiledTemplate::$1(); ?>', $content );
$content =
'?>'.
$content.
'<?PHP';
* display the compiled template
* This is a replacement for patTemplate::displayParsedTemplate.
* @param string name of the template to display
die( 'Unknown template' );
compiledTemplate::$name();
* add a line to the compiled code
* @param string line to add
* @param integer indentation
function _addToCode( $line, $indent =
0, $comment =
null )
if( !is_null( $comment ) )
fputs( $this->_fp, "\n" );
fputs( $this->_fp, "/* $comment */\n" );
fputs( $this->_fp, $line.
"\n" );
* function, used by the compiler to get a value of a variable
* Checks, whether the value is locally or globally set
* @param string variable name
* @todo check for 'unusedvars' attribute
function _getVar( $template, $varname )
if( isset
( $this->_templates[$template]['vars'][$varname] ) )
return $this->_templates[$template]['vars'][$varname];
if( isset
( $this->_globals[$this->_startTag.
$varname.
$this->_endTag] ) )
return $this->_globals[$this->_startTag.
$varname.
$this->_endTag];
* prepare a template for the compiler
* @param string template name
function _prepareCompiledTemplate( $template )
$this->_templates[$template] =
array(