Source for file Standard.php
Documentation is available at Standard.php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Alan Knowles <alan@akbkhome.com> |
// +----------------------------------------------------------------------+
// $Id: Standard.php,v 1.26 2004/04/22 03:48:53 alan_k Exp $
// Standard 'Original Flavour' Flexy compiler
require_once 'HTML/Template/Flexy/Tokenizer.php';
$GLOBALS['_html_template_flexy_compiler_standard']['PO'] = array ();
class HTML_Template_Flexy_Compiler_Standard extends HTML_Template_Flexy_Compiler {
* @params object HTML_Template_Flexy
* @params string|false string to compile of false to use a file.
* @return string filename of template
function compile (&$flexy,$string=false )
// read the entire file into one variable
// note this should be moved to new HTML_Template_Flexy_Token
// and that can then manage all the tokens in one place..
global $_HTML_TEMPLATE_FLEXY_COMPILER;
$gettextStrings = &$_HTML_TEMPLATE_FLEXY_COMPILER['gettextStrings'];
$gettextStrings = array (); // reset it.
if (@$this->options['debug']) {
echo " compiling template $flexy->currentTemplate<BR>";
$flexy->_elements = array ();
// replace this with a singleton??
$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions'] = $this->options;
$GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'] = array ();
$GLOBALS['_HTML_TEMPLATE_FLEXY']['filename'] = $flexy->currentTemplate;
if (is_array($this->options['Translation2'])) {
require_once 'Translation2.php';
$this->options['Translation2'] = new Translation2 (
$this->options['Translation2']['driver'],
@$this->options['Translation2']['options']
if (is_a($this->options['Translation2'],'Translation2')) {
$this->options['Translation2']->setLang ($this->options['locale']);
// fixme - needs to be more specific to which template to use..
$this->options['Translation2']->setPageID (basename($flexy->currentTemplate ));
// PRE PROCESS {_(.....)} translation markers.
$got_gettext_markup = false;
if (strpos($data,'{_(') !== false ) {
$lmatches = explode ('{_(', $data);
foreach ($lmatches as $k) {
if (false === strpos($k,')_}')) {
//echo '<PRE>';print_r($matches);
// we may need to do some house cleaning here...
$gettextStrings = $matches;
$got_gettext_markup = true;
// ** leaving in the tag (which should be ignored by the parser..
// we then get rid of the tags during the toString method in this class.
foreach($matches as $v) {
$data = str_replace('{_('. $v. ')_}', '{_('. $this->translateString ($v). ')_}',$data);
$tokenizer = new HTML_Template_Flexy_Tokenizer ($data);
$tokenizer->fileName = $flexy->currentTemplate;
if ($this->options['nonHTML']) {
$tokenizer->ignoreHTML = true;
if ($this->options['allowPHP']) {
$tokenizer->ignorePHP = false;
$res = HTML_Template_Flexy_Token ::buildTokens ($tokenizer);
if (is_a($res,'PEAR_Error')) {
// turn tokens into Template..
$data = $res->compile ($this);
if (is_a($data,'PEAR_Error')) {
if ( @$this->options['debug']) {
if ($this->options['nonHTML']) {
// at this point we are into writing stuff...
if ($this->options['compileToString']) {
$flexy->elements = $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'];
if( ($cfp = fopen( $flexy->compiledTemplate , 'w' )) ) {
if (@$this->options['debug']) {
chmod($flexy->compiledTemplate ,0775 );
// make the timestamp of the two items match.
return PEAR ::raiseError ('HTML_Template_Flexy::failed to write to '. $flexy->compiledTemplate ,
unlink($flexy->getTextStringsFile );
if($gettextStrings && ($cfp = fopen( $flexy->getTextStringsFile , 'w') ) ) {
if( $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'] &&
($cfp = fopen( $flexy->elementsFile , 'w') ) ) {
* Flag indicating compiler is inside {_( .... )_} block, and should not
* add to the gettextstrings array.
var $inGetTextBlock = false;
* This is the base toString Method, it relays into toString{TokenName}
* @param object HTML_Template_Flexy_Token_*
* @return string string to build a template
function toString ($element)
static $len = 26; // strlen('HTML_Template_Flexy_Token_');
if ($this->options ['debug']) {
if ($element->token == 'GetTextStart') {
$this->inGetTextBlock = true;
if ($element->token == 'GetTextEnd') {
$this->inGetTextBlock = false;
return $this->{'toString'. $type}($element);
$add = $element->compileChildren ($this);
if (is_a($add,'PEAR_Error')) {
$add = $element->close ->compile ($this);
if (is_a($add,'PEAR_Error')) {
* HTML_Template_Flexy_Token_Else toString
* @param object HTML_Template_Flexy_Token_Else
* @return string string to build a template
function toStringElse ($element)
// pushpull states to make sure we are in an area.. - should really check to see
// if the state it is pulling is a if...
if ($element->pullState () === false ) {
return $this->appendHTML (
" <font color=\"red\">Unmatched {else:} on line: {$element->line }</font>"
return $this->appendPhp ("} else {");
* HTML_Template_Flexy_Token_End toString
* @param object HTML_Template_Flexy_Token_Else
* @return string string to build a template
function toStringEnd ($element)
// pushpull states to make sure we are in an area.. - should really check to see
// if the state it is pulling is a if...
if ($element->pullState () === false ) {
return $this->appendHTML (
" <font color=\"red\">Unmatched {end:} on line: {$element->line }</font>"
return $this->appendPhp ("}");
* HTML_Template_Flexy_Token_EndTag toString
* @param object HTML_Template_Flexy_Token_EndTag
* @return string string to build a template
function toStringEndTag ($element)
return $this->toStringTag ($element);
* HTML_Template_Flexy_Token_Foreach toString
* @param object HTML_Template_Flexy_Token_Foreach
* @return string string to build a template
function toStringForeach ($element)
$loopon = $element->toVar ($element->loopOn );
if (is_a($loopon,'PEAR_Error')) {
$ret = 'if (is_array('. $loopon. ") || " .
'is_object(' . $loopon . ')) ' .
'foreach(' . $loopon . " ";
$ret .= " as \${$element->key }";
$ret .= " => \${$element->value }";
$element->pushVar ($element->key);
$element->pushVar ($element->value );
return $this->appendPhp ($ret);
* HTML_Template_Flexy_Token_If toString
* @param object HTML_Template_Flexy_Token_If
* @return string string to build a template
function toStringIf ($element)
$var = $element->toVar ($element->condition );
if (is_a($var,'PEAR_Error')) {
$ret = "if (". $element->isNegative . $var . ") {";
return $this->appendPhp ($ret);
* converts :h, :u, :r , .....
* @param object HTML_Template_Flexy_Token_Method|Var
* @return array prefix,suffix
function getModifierWrapper ($element)
$modifier = $element->modifier . ' ';
$prefix = 'echo urlencode(';
$prefix = 'echo \'<pre>\'; echo htmlspecialchars(print_r(';
$suffix = ',true)); echo \'</pre>\';';
$numberformat = @$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['numberFormat'];
$prefix = 'echo number_format(';
$suffix = $GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['numberFormat'] . ')';
case 'b': // nl2br + htmlspecialchars
$prefix = 'echo nl2br(htmlspecialchars(';
$prefix = 'echo htmlspecialchars(';
return array ($prefix,$suffix);
* HTML_Template_Flexy_Token_Var toString
* @param object HTML_Template_Flexy_Token_Method
* @return string string to build a template
function toStringVar ($element)
// ignore modifier at present!!
$var = $element->toVar ($element->value );
if (is_a($var,'PEAR_Error')) {
list ($prefix,$suffix) = $this->getModifierWrapper ($element);
return $this->appendPhp ( $prefix . $var . $suffix . ';');
* HTML_Template_Flexy_Token_Method toString
* @param object HTML_Template_Flexy_Token_Method
* @return string string to build a template
function toStringMethod ($element)
// set up the modifier at present!!
list ($prefix,$suffix) = $this->getModifierWrapper ($element);
if ($element->isConditional ) {
$prefix = 'if ('. $element->isNegative;
// check that method exists..
// if (method_exists($object,'method');
$bits = explode('.',$element->method );
$var = $element->toVar ($object);
if (is_a($var,'PEAR_Error')) {
if (($object == 'GLOBALS') &&
$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['globalfunctions']) {
// we should check if they something weird like: GLOBALS.xxxx[sdf](....)
$prefix = 'if (isset('. $var.
') && method_exists('. $var ." ,'{$method}')) " . $prefix;
$var = $element->toVar ($element->method );
if (is_a($var,'PEAR_Error')) {
foreach($element->args as $a) {
$var = $element->toVar ($a);
if (is_a($var,'PEAR_Error')) {
if ($element->isConditional ) {
return $this->appendPhp ($ret);
* HTML_Template_Flexy_Token_Processing toString
* @param object HTML_Template_Flexy_Token_Processing
* @return string string to build a template
function toStringProcessing ($element)
// if it's XML then quote it..
return $this->appendPhp ("echo '" . str_replace("'","\\". "'", $element->value ) . "';");
// otherwise it's PHP code - so echo it..
* HTML_Template_Flexy_Token_Text toString
* @param object HTML_Template_Flexy_Token_Text
* @return string string to build a template
function toStringText ($element)
// if it's XML then quote it..
* Global variable for gettext replacement
* static object vars will be nice in PHP5 :)
global $_HTML_TEMPLATE_FLEXY_COMPILER;
$gettextStrings = &$_HTML_TEMPLATE_FLEXY_COMPILER['gettextStrings'];
static $cleanArray = array (
static $uncleanArray = false;
$uncleanArray = array_flip ($cleanArray);
if (!strlen (trim ($element->value ) )) {
return $this->appendHtml ($element->value );
// dont add comments to translation lists.
if (substr($element->value ,0 ,4 ) == '<!--') {
return $this->appendHtml ($element->value );
if (!count($element->argTokens ) && !$element->isWord ()) {
return $this->appendHtml ($element->value );
// ignore anything wrapped with {_( .... )_}
if ($this->inGetTextBlock ) {
return $this->appendHtml ($element->value );
for ($i=0; $i< strlen($element->value ); $i++ ) {
if (strpos(" \n\t\r\0\x0B", $element->value {$i}) !== false ) {
$front .= $element->value {$i};
for ($i= strlen($element->value )-1; $i>-1; $i-- ) {
if (strpos(" \n\t\r\0\x0B", $element->value {$i}) !== false ) {
$rear = $element->value {$i} . $rear;
$value = trim($element->value );
// convert to escaped chars.. (limited..)
$value = strtr($value,$cleanArray);
if (!count($element->argTokens )) {
$gettextStrings[] = $value;
$value = $this->translateString ($value);
$value = strtr($value,$uncleanArray);
return $this->appendHtml ($front . $value . $rear);
// print_r($element->argTokens );
// these should only be text or vars..
foreach($element->argTokens as $i=> $token) {
$args[] = $token->compile ($this);
$gettextStrings[] = $value;
$value = $this->translateString ($value);
$value = strtr($value,$uncleanArray);
foreach($bits as $i=> $v) {
* translateString - a gettextWrapper
* tries to do gettext or falls back on File_Gettext
* This has !!!NO!!! error handling - if it fails you just get english..
* @param string string to translate
* @return string translated string..
function translateString ($string)
if (is_a($this->options ['Translation2'],'Translation2')) {
$result = $this->options ['Translation2']->get ($string);
$prefix = basename($GLOBALS['_HTML_TEMPLATE_FLEXY']['filename']). ':';
if (@$this->options ['debug']) {
echo __CLASS__." :TRANSLATING $string<BR>";
if (@$this->options ['debug']) {
echo __CLASS__. ":USING GETTEXT?<BR>";
if ($tt != $prefix. $string) {
// give up it's not translated anywhere...
if (!$this->options ['textdomain'] || !$this->options ['textdomainDir']) {
// text domain is not set..
if (@$this->options ['debug']) {
echo __CLASS__. ":MISSING textdomain settings<BR>";
$pofile = $this->options ['textdomainDir'] .
'/' . $this->options ['locale'] .
'/LC_MESSAGES/' . $this->options ['textdomain'] . '.po';
// did we try to load it already..
if (@$GLOBALS['_'.__CLASS__ ]['PO'][$pofile] === false ) {
if (@$this->options ['debug']) {
echo __CLASS__. ":LOAD failed (Cached):<BR>";
if (!@$GLOBALS['_'.__CLASS__ ]['PO'][$pofile]) {
// default - cant load it..
$GLOBALS['_'.__CLASS__ ]['PO'][$pofile] = false;
if (@$this->options ['debug']) {
echo __CLASS__." :LOAD failed: {$pofile}<BR>";
if (!@include_once 'File/Gettext.php') {
if (@$this->options ['debug']) {
echo __CLASS__. ":LOAD no File_gettext:<BR>";
$GLOBALS['_'.__CLASS__ ]['PO'][$pofile] = File_Gettext ::factory ('PO',$pofile);
$GLOBALS['_'.__CLASS__ ]['PO'][$pofile]->load ();
//echo '<PRE>'.htmlspecialchars(print_r($GLOBALS['_'.__CLASS__]['PO'][$pofile]->strings,true));
$po = &$GLOBALS['_'.__CLASS__ ]['PO'][$pofile];
// we should have it loaded now...
// this is odd - data is a bit messed up with CR's
if (isset ($po->strings [$prefix. $string])) {
return $po->strings [$prefix. $string];
if (!isset ($po->strings [$string])) {
if (@$this->options ['debug']) {
echo __CLASS__. ":no match:<BR>";
if (@$this->options ['debug']) {
echo __CLASS__." :MATCHED: {$po->strings [$string]}<BR>";
// finally we have a match!!!
return $po->strings [$string];
* HTML_Template_Flexy_Token_Tag toString
* @param object HTML_Template_Flexy_Token_Tag
* @return string string to build a template
function toStringTag ($element) {
if (strpos($element->tag ,':') === false ) {
$bits = explode(':',$element->tag );
if ($namespace{0 } == '/') {
if (empty ($this->tagHandlers [$namespace])) {
require_once 'HTML/Template/Flexy/Compiler/Standard/Tag.php';
$this->tagHandlers [$namespace] = &HTML_Template_Flexy_Compiler_Standard_Tag ::factory ($namespace,$this);
if (!$this->tagHandlers [$namespace] ) {
return PEAR ::raiseError ('HTML_Template_Flexy::failed to create Namespace Handler '. $namespace .
' in file ' . $GLOBALS['_HTML_TEMPLATE_FLEXY']['filename'],
return $this->tagHandlers [$namespace]->toString ($element);
Documentation generated on Mon, 11 Mar 2019 10:15:15 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|