home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / HTML / Template / Flexy / Compiler / Standard.php < prev   
Encoding:
PHP Script  |  2008-07-02  |  27.6 KB  |  911 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Alan Knowles <alan@akbkhome.com>                            |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Standard.php,v 1.43 2005/02/08 05:35:27 alan_k Exp $
  20. //
  21. //  Base Compiler Class
  22. //  Standard 'Original Flavour' Flexy compiler
  23.  
  24. /*------------------------------------------------------------------------------------------
  25.                                         NOTICE: 
  26.                              THIS COMPILER IS DEPRECIATED 
  27.                                 USE THE FLEXY COMPILER 
  28.      
  29.                       The Flexy Compiler should be Compatible
  30.  
  31. ------------------------------------------------------------------------------------------*/
  32.  
  33. require_once 'HTML/Template/Flexy/Tokenizer.php';
  34. require_once 'HTML/Template/Flexy/Token.php';
  35.  
  36. // cache for po files..
  37. $GLOBALS['_html_template_flexy_compiler_standard']['PO'] = array();
  38.  
  39.  
  40. class HTML_Template_Flexy_Compiler_Standard extends HTML_Template_Flexy_Compiler 
  41. {
  42.     
  43.     
  44.     
  45.     /**
  46.     * The compile method.
  47.     * 
  48.     * @params   object HTML_Template_Flexy
  49.     * @params   string|false string to compile of false to use a file.
  50.     * @return   string   filename of template
  51.     * @access   public
  52.     */
  53.     function compile(&$flexy,$string=false) 
  54.     {
  55.         // read the entire file into one variable
  56.         
  57.         // note this should be moved to new HTML_Template_Flexy_Token
  58.         // and that can then manage all the tokens in one place..
  59.         global $_HTML_TEMPLATE_FLEXY_COMPILER;
  60.         
  61.         $gettextStrings = &$_HTML_TEMPLATE_FLEXY_COMPILER['gettextStrings'];
  62.         $gettextStrings = array(); // reset it.
  63.         
  64.         if (@$this->options['debug']) {
  65.             echo "compiling template $flexy->currentTemplate<BR>";
  66.             
  67.         }
  68.          
  69.         // reset the elements.
  70.         $flexy->_elements = array();
  71.         
  72.         // replace this with a singleton??
  73.         
  74.         $GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions'] = $this->options;
  75.         $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'] = array();
  76.         $GLOBALS['_HTML_TEMPLATE_FLEXY']['filename'] = $flexy->currentTemplate;
  77.         $GLOBALS['_HTML_TEMPLATE_FLEXY']['prefixOutput']  = '';
  78.         $GLOBALS['_HTML_TEMPLATE_FLEXY']['compiledTemplate']  = $flexy->compiledTemplate;
  79.         
  80.         if (is_array($this->options['Translation2'])) {
  81.             require_once 'Translation2.php';
  82.             $this->options['Translation2'] = new Translation2(
  83.                 $this->options['Translation2']['driver'],
  84.                 @$this->options['Translation2']['options']
  85.             );
  86.         }
  87.         
  88.         
  89.         if (is_a($this->options['Translation2'],'Translation2')) {
  90.             $this->options['Translation2']->setLang($this->options['locale']);
  91.             // fixme - needs to be more specific to which template to use..
  92.             foreach ($this->options['templateDir'] as $tt) {
  93.                 $n = basename($flexy->currentTemplate);
  94.                 if (substr($flexy->currentTemplate,0,strlen($tt)) == $tt) {
  95.                     $n = substr($flexy->currentTemplate,strlen($tt)+1);
  96.                 }
  97.                 //echo $n;
  98.             }
  99.             $this->options['Translation2']->setPageID($n);
  100.         } else {
  101.             setlocale(LC_ALL, $this->options['locale']);
  102.         }
  103.         
  104.         
  105.         
  106.         
  107.         
  108.         
  109.         
  110.         $data = $string;
  111.         $res = false;
  112.         if ($string === false) {
  113.             $data = file_get_contents($flexy->currentTemplate);
  114.         }
  115.          
  116.             // PRE PROCESS {_(.....)} translation markers.
  117.         $got_gettext_markup = false;
  118.         
  119.         
  120.         
  121.         if (strpos($data,'{_(') !== false) {
  122.             $matches = array();
  123.             $lmatches = explode ('{_(', $data);
  124.             array_shift($lmatches);
  125.             // shift the first..
  126.             foreach ($lmatches as $k) {
  127.                 if (false === strpos($k,')_}')) {
  128.                     continue;
  129.                 }
  130.                 $x = explode(')_}',$k);
  131.                 $matches[] = $x[0];
  132.             }
  133.         
  134.         
  135.            //echo '<PRE>';print_r($matches);
  136.             // we may need to do some house cleaning here...
  137.             $gettextStrings = $matches;
  138.             $got_gettext_markup = true;
  139.             
  140.             
  141.             // replace them now..  
  142.             // ** leaving in the tag (which should be ignored by the parser..
  143.             // we then get rid of the tags during the toString method in this class.
  144.             foreach($matches as $v) {
  145.                 $data = str_replace('{_('.$v.')_}', '{_('.$this->translateString($v).')_}',$data);
  146.             }
  147.             
  148.         }
  149.             
  150.         if (isset($_HTML_TEMPLATE_FLEXY_COMPILER['cache'][md5($data)])) {
  151.             $res = $_HTML_TEMPLATE_FLEXY_COMPILER['cache'][md5($data)];
  152.         } else {
  153.         
  154.              
  155.             $tokenizer = new HTML_Template_Flexy_Tokenizer($data);
  156.             $tokenizer->fileName = $flexy->currentTemplate;
  157.             
  158.             
  159.             //$tokenizer->debug=1;
  160.             $tokenizer->options['ignore_html'] = $this->options['nonHTML'];
  161.             $tokenizer->options['ignore_php']  = !$this->options['allowPHP'];
  162.             
  163.             $res = HTML_Template_Flexy_Token::buildTokens($tokenizer);
  164.          
  165.             $_HTML_TEMPLATE_FLEXY_COMPILER['cache'][md5($data)] = $res;
  166.             
  167.         }
  168.         
  169.         if (is_a($res,'PEAR_Error')) {
  170.             return $res;
  171.         }   
  172.         // turn tokens into Template..
  173.         
  174.         $data = $res->compile($this);
  175.         
  176.         if (is_a($data,'PEAR_Error')) {
  177.             return $data;
  178.         }
  179.         
  180.         $data = $GLOBALS['_HTML_TEMPLATE_FLEXY']['prefixOutput'] . $data;
  181.         
  182.         if (   @$this->options['debug']) {
  183.             echo "<B>Result: </B><PRE>".htmlspecialchars($data)."</PRE><BR>";
  184.             
  185.         }
  186.  
  187.         if ($this->options['nonHTML']) {
  188.            $data =  str_replace("?>\n","?>\n\n",$data);
  189.         }
  190.         
  191.          
  192.         
  193.         
  194.         // at this point we are into writing stuff...
  195.         if ($this->options['compileToString']) {
  196.             $flexy->elements =  $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'];
  197.             return $data;
  198.         }
  199.         
  200.         
  201.         
  202.         
  203.         // error checking?
  204.         $file  = $flexy->compiledTemplate;
  205.         if (isset($flexy->options['output.block'])) {
  206.             list($file,$part) = explode('#',$file  );
  207.         }
  208.         
  209.         if( ($cfp = fopen( $file , 'w' )) ) {
  210.             if (@$this->options['debug']) {
  211.                 echo "<B>Writing: </B>".htmlspecialchars($data)."<BR>";
  212.                 
  213.             }
  214.             fwrite($cfp,$data);
  215.             fclose($cfp);
  216.             
  217.             chmod($file,0775);
  218.             // make the timestamp of the two items match.
  219.             clearstatcache();
  220.             touch($file, filemtime($flexy->currentTemplate));
  221.             if ($file != $flexy->compiledTemplate) {
  222.                 chmod($flexy->compiledTemplate,0775);
  223.                 // make the timestamp of the two items match.
  224.                 clearstatcache();
  225.                 touch($flexy->compiledTemplate, filemtime($flexy->currentTemplate));
  226.             }
  227.              
  228.             
  229.         } else {
  230.             return HTML_Template_Flexy::raiseError('HTML_Template_Flexy::failed to write to '.$flexy->compiledTemplate,
  231.                 HTML_TEMPLATE_FLEXY_ERROR_FILE ,HTML_TEMPLATE_FLEXY_ERROR_RETURN);
  232.         }
  233.         // gettext strings
  234.         if (file_exists($flexy->getTextStringsFile)) {
  235.             unlink($flexy->getTextStringsFile);
  236.         }
  237.         
  238.         if($gettextStrings && ($cfp = fopen( $flexy->getTextStringsFile, 'w') ) ) {
  239.             
  240.             fwrite($cfp,serialize(array_unique($gettextStrings)));
  241.             fclose($cfp);
  242.         }
  243.         
  244.         // elements
  245.         if (file_exists($flexy->elementsFile)) {
  246.             unlink($flexy->elementsFile);
  247.         }
  248.         
  249.         if( $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements'] &&
  250.             ($cfp = fopen( $flexy->elementsFile, 'w') ) ) {
  251.             fwrite($cfp,serialize( $GLOBALS['_HTML_TEMPLATE_FLEXY']['elements']));
  252.             fclose($cfp);
  253.             // now clear it.
  254.         
  255.         }
  256.         
  257.         return true;
  258.     }
  259.     
  260.     /**
  261.     * Flag indicating compiler is inside {_( .... )_} block, and should not
  262.     * add to the gettextstrings array.
  263.     *
  264.     * @var boolean 
  265.     * @access public
  266.     */
  267.     var $inGetTextBlock = false;
  268.     
  269.     /**
  270.     * This is the base toString Method, it relays into toString{TokenName}
  271.     *
  272.     * @param    object    HTML_Template_Flexy_Token_*
  273.     * 
  274.     * @return   string     string to build a template
  275.     * @access   public 
  276.     * @see      toString*
  277.     */
  278.   
  279.  
  280.     function toString($element) 
  281.     {
  282.         static $len = 26; // strlen('HTML_Template_Flexy_Token_');
  283.         if ($this->options['debug']) {
  284.             $x = $element;
  285.             unset($x->children);
  286.             echo htmlspecialchars(print_r($x,true))."<BR>\n";
  287.         }
  288.         if ($element->token == 'GetTextStart') {
  289.             $this->inGetTextBlock = true;
  290.             return '';
  291.         }
  292.         if ($element->token == 'GetTextEnd') {
  293.             $this->inGetTextBlock = false;
  294.             return '';
  295.         }
  296.         
  297.             
  298.         $class = get_class($element);
  299.         if (strlen($class) >= $len) {
  300.             $type = substr($class,$len);
  301.             return $this->{'toString'.$type}($element);
  302.         }
  303.         
  304.         $ret = $element->value;
  305.         $add = $element->compileChildren($this);
  306.         if (is_a($add,'PEAR_Error')) {
  307.             return $add;
  308.         }
  309.         $ret .= $add;
  310.         
  311.         if ($element->close) {
  312.             $add = $element->close->compile($this);
  313.             if (is_a($add,'PEAR_Error')) {
  314.                 return $add;
  315.             }
  316.             $ret .= $add;
  317.         }
  318.         
  319.         return $ret;
  320.     }
  321.  
  322.  
  323.     /**
  324.     *   HTML_Template_Flexy_Token_Else toString 
  325.     *
  326.     * @param    object    HTML_Template_Flexy_Token_Else
  327.     * 
  328.     * @return   string     string to build a template
  329.     * @access   public 
  330.     * @see      toString*
  331.     */
  332.   
  333.  
  334.     function toStringElse($element) 
  335.      {
  336.         // pushpull states to make sure we are in an area.. - should really check to see 
  337.         // if the state it is pulling is a if...
  338.         if ($element->pullState() === false) {
  339.             return $this->appendHTML(
  340.                 "<font color=\"red\">Unmatched {else:} on line: {$element->line}</font>"
  341.                 );
  342.         }
  343.         $element->pushState();
  344.         return $this->appendPhp("} else {");
  345.     }
  346.     
  347.     /**
  348.     *   HTML_Template_Flexy_Token_End toString 
  349.     *
  350.     * @param    object    HTML_Template_Flexy_Token_Else
  351.     * 
  352.     * @return   string     string to build a template
  353.     * @access   public 
  354.     * @see      toString*
  355.     */
  356.   
  357.     function toStringEnd($element) 
  358.     {
  359.         // pushpull states to make sure we are in an area.. - should really check to see 
  360.         // if the state it is pulling is a if...
  361.         if ($element->pullState() === false) {
  362.             return $this->appendHTML(
  363.                 "<font color=\"red\">Unmatched {end:} on line: {$element->line}</font>"
  364.                 );
  365.         }
  366.          
  367.         return $this->appendPhp("}");
  368.     }
  369.  
  370.     /**
  371.     *   HTML_Template_Flexy_Token_EndTag toString 
  372.     *
  373.     * @param    object    HTML_Template_Flexy_Token_EndTag
  374.     * 
  375.     * @return   string     string to build a template
  376.     * @access   public 
  377.     * @see      toString*
  378.     */
  379.   
  380.  
  381.  
  382.     function toStringEndTag($element) 
  383.     {
  384.         return $this->toStringTag($element);
  385.     }
  386.         
  387.     
  388.     
  389.     /**
  390.     *   HTML_Template_Flexy_Token_Foreach toString 
  391.     *
  392.     * @param    object    HTML_Template_Flexy_Token_Foreach 
  393.     * 
  394.     * @return   string     string to build a template
  395.     * @access   public 
  396.     * @see      toString*
  397.     */
  398.   
  399.     
  400.     function toStringForeach($element) 
  401.     {
  402.     
  403.         $loopon = $element->toVar($element->loopOn);
  404.         if (is_a($loopon,'PEAR_Error')) {
  405.             return $loopon;
  406.         }
  407.         
  408.         $ret = 'if ($this->options[\'strict\'] || ('.
  409.             'is_array('. $loopon. ')  || ' .
  410.             'is_object(' . $loopon  . '))) ' .
  411.             'foreach(' . $loopon  . " ";
  412.             
  413.         $ret .= "as \${$element->key}";
  414.         
  415.         if ($element->value) {
  416.             $ret .=  " => \${$element->value}";
  417.         }
  418.         $ret .= ") {";
  419.         
  420.         $element->pushState();
  421.         $element->pushVar($element->key);
  422.         $element->pushVar($element->value);
  423.         return $this->appendPhp($ret);
  424.     }
  425.     /**
  426.     *   HTML_Template_Flexy_Token_If toString 
  427.     *
  428.     * @param    object    HTML_Template_Flexy_Token_If
  429.     * 
  430.     * @return   string     string to build a template
  431.     * @access   public 
  432.     * @see      toString*
  433.     */
  434.   
  435.     function toStringIf($element) 
  436.     {
  437.         
  438.         $var = $element->toVar($element->condition);
  439.         if (is_a($var,'PEAR_Error')) {
  440.             return $var;
  441.         }
  442.         
  443.         $ret = "if (".$element->isNegative . $var .")  {";
  444.         $element->pushState();
  445.         return $this->appendPhp($ret);
  446.     }
  447.  
  448.    /**
  449.     *  get Modifier Wrapper 
  450.     *
  451.     * converts :h, :u, :r , .....
  452.     * @param    object    HTML_Template_Flexy_Token_Method|Var
  453.     * 
  454.     * @return   array prefix,suffix
  455.     * @access   public 
  456.     * @see      toString*
  457.     */
  458.  
  459.     function getModifierWrapper($element) 
  460.     {
  461.         $prefix = 'echo ';
  462.         
  463.         $suffix = '';
  464.         $modifier = strlen(trim($element->modifier)) ? $element->modifier : ' ';
  465.         
  466.         switch ($modifier{0}) {
  467.             case 'h':
  468.                 break;
  469.             case 'u':
  470.                 $prefix = 'echo urlencode(';
  471.                 $suffix = ')';
  472.                 break;
  473.             case 'r':
  474.                 $prefix = 'echo \'<pre>\'; echo htmlspecialchars(print_r(';
  475.                 $suffix = ',true)); echo \'</pre>\';';
  476.                 break;                
  477.             case 'n': 
  478.                 // blank or value..
  479.                 $numberformat = @$GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['numberFormat'];
  480.                 $prefix = 'echo number_format(';
  481.                 $suffix = $GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['numberFormat'] . ')';
  482.                 break;
  483.             case 'b': // nl2br + htmlspecialchars
  484.                 $prefix = 'echo nl2br(htmlspecialchars(';
  485.                 
  486.                 // add language ?
  487.                 $suffix = '))';
  488.                 break;
  489.             case ' ':
  490.                 $prefix = 'echo htmlspecialchars(';
  491.                 // add language ?
  492.                 $suffix = ')';
  493.                 break;
  494.             default:
  495.                $prefix = 'echo $this->plugin("'.trim($element->modifier) .'",';
  496.                $suffix = ')'; 
  497.             
  498.             
  499.         }
  500.         
  501.         return array($prefix,$suffix);
  502.     }
  503.  
  504.  
  505.  
  506.   /**
  507.     *   HTML_Template_Flexy_Token_Var toString 
  508.     *
  509.     * @param    object    HTML_Template_Flexy_Token_Method
  510.     * 
  511.     * @return   string     string to build a template
  512.     * @access   public 
  513.     * @see      toString*
  514.     */
  515.   
  516.     function toStringVar($element) 
  517.     {
  518.         // ignore modifier at present!!
  519.         
  520.         $var = $element->toVar($element->value);
  521.         if (is_a($var,'PEAR_Error')) {
  522.             return $var;
  523.         }
  524.         list($prefix,$suffix) = $this->getModifierWrapper($element);
  525.         return $this->appendPhp( $prefix . $var . $suffix .';');
  526.     }
  527.    /**
  528.     *   HTML_Template_Flexy_Token_Method toString 
  529.     *
  530.     * @param    object    HTML_Template_Flexy_Token_Method
  531.     * 
  532.     * @return   string     string to build a template
  533.     * @access   public 
  534.     * @see      toString*
  535.     */
  536.   
  537.     function toStringMethod($element) 
  538.     {
  539.  
  540.               
  541.         // set up the modifier at present!!
  542.         list($prefix,$suffix) = $this->getModifierWrapper($element);
  543.         
  544.         // add the '!' to if
  545.         
  546.         if ($element->isConditional) {
  547.             $prefix = 'if ('.$element->isNegative;
  548.             $element->pushState();
  549.             $suffix = ')';
  550.         }  
  551.         
  552.         
  553.         // check that method exists..
  554.         // if (method_exists($object,'method');
  555.         $bits = explode('.',$element->method);
  556.         $method = array_pop($bits);
  557.         
  558.         $object = implode('.',$bits);
  559.         
  560.         $var = $element->toVar($object);
  561.         if (is_a($var,'PEAR_Error')) {
  562.             return $var;
  563.         }
  564.         
  565.         if (($object == 'GLOBALS') && 
  566.             $GLOBALS['_HTML_TEMPLATE_FLEXY']['currentOptions']['globalfunctions']) {
  567.             // we should check if they something weird like: GLOBALS.xxxx[sdf](....)
  568.             $var = $method;
  569.         } else {
  570.             $prefix = 'if ($this->options[\'strict\'] || (isset('.$var.
  571.                 ') && method_exists('.$var .",'{$method}'))) " . $prefix;
  572.             $var = $element->toVar($element->method);
  573.         }
  574.         
  575.  
  576.         if (is_a($var,'PEAR_Error')) {
  577.             return $var;
  578.         }
  579.         
  580.         $ret  =  $prefix;
  581.         $ret .=  $var . "(";
  582.         $s =0;
  583.          
  584.        
  585.          
  586.         foreach($element->args as $a) {
  587.              
  588.             if ($s) {
  589.                 $ret .= ",";
  590.             }
  591.             $s =1;
  592.             if ($a{0} == '#') {
  593.                 $ret .= '"'. addslashes(substr($a,1,-1)) . '"';
  594.                 continue;
  595.             }
  596.             
  597.             $var = $element->toVar($a);
  598.             if (is_a($var,'PEAR_Error')) {
  599.                 return $var;
  600.             }
  601.             $ret .= $var;
  602.             
  603.         }
  604.         $ret .= ")" . $suffix;
  605.         
  606.         if ($element->isConditional) {
  607.             $ret .= ' { ';
  608.         } else {
  609.             $ret .= ";";
  610.         }
  611.         
  612.         
  613.         
  614.         return $this->appendPhp($ret); 
  615.         
  616.          
  617.  
  618.    }
  619.    /**
  620.     *   HTML_Template_Flexy_Token_Processing toString 
  621.     *
  622.     * @param    object    HTML_Template_Flexy_Token_Processing 
  623.     * 
  624.     * @return   string     string to build a template
  625.     * @access   public 
  626.     * @see      toString*
  627.     */
  628.  
  629.  
  630.     function toStringProcessing($element) 
  631.     {
  632.         // if it's XML then quote it..
  633.         if (strtoupper(substr($element->value,2,3)) == 'XML') { 
  634.             return $this->appendPhp("echo '" . str_replace("'","\\"."'", $element->value) . "';");
  635.         }
  636.         // otherwise it's PHP code - so echo it..
  637.         return $element->value;
  638.     }
  639.     
  640.     /**
  641.     *   HTML_Template_Flexy_Token_Text toString 
  642.     *
  643.     * @param    object    HTML_Template_Flexy_Token_Text
  644.     * 
  645.     * @return   string     string to build a template
  646.     * @access   public 
  647.     * @see      toString*
  648.     */
  649.  
  650.  
  651.  
  652.     function toStringText($element) 
  653.     {
  654.         
  655.         // first get rid of stuff thats not translated etc.
  656.         // empty strings => output.
  657.         // comments -> just output
  658.         // our special tags -> output..
  659.         
  660.         if (!strlen(trim($element->value) )) {
  661.             return $this->appendHtml($element->value);
  662.         }
  663.         // dont add comments to translation lists.
  664.          
  665.         if (substr($element->value,0,4) == '<!--') {
  666.             return $this->appendHtml($element->value);
  667.         }
  668.         // ignore anything wrapped with {_( .... )_}
  669.         if ($this->inGetTextBlock) {
  670.             return $this->appendHtml($element->value);
  671.         }
  672.         
  673.         // argTokens is built before the tag matching (it combined
  674.         // flexy tags into %s, into the string,
  675.         // and made a list of tokens in argTokens.
  676.         
  677.         if (!count($element->argTokens) && !$element->isWord()) {
  678.             return $this->appendHtml($element->value);
  679.         }
  680.         
  681.         // grab the white space at start and end (and keep it!
  682.         
  683.         $value = ltrim($element->value);
  684.         $front = substr($element->value,0,-strlen($value));
  685.         $value = rtrim($element->value);
  686.         $rear  = substr($element->value,strlen($value));
  687.         $value = trim($element->value);
  688.         
  689.         
  690.         // convert to escaped chars.. (limited..)
  691.         //$value = strtr($value,$cleanArray);
  692.         
  693.         $this->addStringToGettext($value);
  694.         $value = $this->translateString($value);
  695.         // its a simple word!
  696.         if (!count($element->argTokens)) {
  697.             return $this->appendHtml($front . $value . $rear);
  698.         }
  699.         
  700.         
  701.         // there are subtokens..
  702.         // print_r($element->argTokens );
  703.         $args = array();
  704.         // these should only be text or vars..
  705.         
  706.         foreach($element->argTokens as $i=>$token) {
  707.             $args[] = $token->compile($this);
  708.         }
  709.         
  710.         // we break up the translated string, and put the compiled tags 
  711.         // in between the values here.
  712.         
  713.         $bits = explode('%s',$value);
  714.         $ret  = $front;
  715.         
  716.         foreach($bits as $i=>$v) {
  717.             $ret .= $v . @$args[$i];
  718.         }
  719.         
  720.         return  $ret . $rear;
  721.         
  722.     }
  723.     /**
  724.     * addStringToGettext 
  725.     *
  726.     * Adds a string to the gettext array. 
  727.     * 
  728.     * @param   mixed        preferably.. string to store
  729.     *
  730.     * @return   none
  731.     * @access   public
  732.     */
  733.     
  734.     function addStringToGettext($string) 
  735.     {
  736.     
  737.         
  738.         
  739.         
  740.         if (!is_string($string)) {
  741.             return;
  742.         }
  743.         
  744.         if (!preg_match('/[a-z]+/i', $string)) {
  745.             return;
  746.         }
  747.         $string = trim($string);
  748.         
  749.         if (substr($string,0,4) == '<!--') {
  750.             return;
  751.         }
  752.         
  753.         $GLOBALS['_HTML_TEMPLATE_FLEXY_COMPILER']['gettextStrings'][] = $string;
  754.     }
  755.     
  756.     
  757.     /**
  758.     * translateString - a gettextWrapper
  759.     *
  760.     * tries to do gettext or falls back on File_Gettext
  761.     * This has !!!NO!!! error handling - if it fails you just get english.. 
  762.     * no questions asked!!!
  763.     * 
  764.     * @param   string       string to translate
  765.     *
  766.     * @return   string      translated string..
  767.     * @access   public
  768.     */
  769.   
  770.     function translateString($string)
  771.     {
  772.          
  773.         
  774.         
  775.         if (is_a($this->options['Translation2'],'Translation2')) {
  776.             $result = $this->options['Translation2']->get($string);
  777.             if (!empty($result)) {
  778.                 return $result;
  779.             }
  780.             return $string;
  781.         }
  782.         
  783.         // note this stuff may have been broken by removing the \n replacement code 
  784.         // since i dont have a test for it... it may remain broken..
  785.         // use Translation2 - it has gettext backend support
  786.         // and should sort out the mess that \n etc. entail.
  787.         
  788.         
  789.         $prefix = basename($GLOBALS['_HTML_TEMPLATE_FLEXY']['filename']).':';
  790.         if (@$this->options['debug']) {
  791.             echo __CLASS__.":TRANSLATING $string<BR>";
  792.         }
  793.         if (function_exists('gettext') && !$this->options['textdomain']) {
  794.             if (@$this->options['debug']) {
  795.                 echo __CLASS__.":USING GETTEXT?<BR>";
  796.             }
  797.             $t = gettext($string);
  798.             if ($t != $string) {
  799.                 return $t;
  800.             }
  801.             $tt = gettext($prefix.$string);
  802.             if ($tt != $prefix.$string) {
  803.                 return $tt;
  804.             }
  805.             // give up it's not translated anywhere...
  806.             return $t;
  807.              
  808.         }
  809.         if (!$this->options['textdomain'] || !$this->options['textdomainDir']) {
  810.             // text domain is not set..
  811.             if (@$this->options['debug']) {
  812.                 echo __CLASS__.":MISSING textdomain settings<BR>";
  813.             }
  814.             return $string;
  815.         }
  816.         $pofile = $this->options['textdomainDir'] . 
  817.                 '/' . $this->options['locale'] . 
  818.                 '/LC_MESSAGES/' . $this->options['textdomain'] . '.po';
  819.         
  820.         
  821.         // did we try to load it already..
  822.         if (@$GLOBALS['_'.__CLASS__]['PO'][$pofile] === false) {
  823.             if (@$this->options['debug']) {
  824.                 echo __CLASS__.":LOAD failed (Cached):<BR>";
  825.             }
  826.             return $string;
  827.         }
  828.         if (!@$GLOBALS['_'.__CLASS__]['PO'][$pofile]) {
  829.             // default - cant load it..
  830.             $GLOBALS['_'.__CLASS__]['PO'][$pofile] = false;
  831.             if (!file_exists($pofile)) {
  832.                  if (@$this->options['debug']) {
  833.                 echo __CLASS__.":LOAD failed: {$pofile}<BR>";
  834.             }
  835.                 return $string;
  836.             }
  837.             
  838.             if (!@include_once 'File/Gettext.php') {
  839.                 if (@$this->options['debug']) {
  840.                     echo __CLASS__.":LOAD no File_gettext:<BR>";
  841.                 }
  842.                 return $string;
  843.             }
  844.             
  845.             $GLOBALS['_'.__CLASS__]['PO'][$pofile] = File_Gettext::factory('PO',$pofile);
  846.             $GLOBALS['_'.__CLASS__]['PO'][$pofile]->load();
  847.             //echo '<PRE>'.htmlspecialchars(print_r($GLOBALS['_'.__CLASS__]['PO'][$pofile]->strings,true));
  848.             
  849.         }
  850.         $po = &$GLOBALS['_'.__CLASS__]['PO'][$pofile];
  851.         // we should have it loaded now...
  852.         // this is odd - data is a bit messed up with CR's
  853.         $string = str_replace('\n',"\n",$string);
  854.         
  855.         if (isset($po->strings[$prefix.$string])) {
  856.             return $po->strings[$prefix.$string];
  857.         }
  858.         
  859.         if (!isset($po->strings[$string])) {
  860.             if (@$this->options['debug']) {
  861.                     echo __CLASS__.":no match:<BR>";
  862.             }
  863.             return $string;
  864.         }
  865.         if (@$this->options['debug']) {
  866.             echo __CLASS__.":MATCHED: {$po->strings[$string]}<BR>";
  867.         }
  868.         
  869.         // finally we have a match!!!
  870.         return $po->strings[$string];
  871.         
  872.     } 
  873.      /**
  874.     *   HTML_Template_Flexy_Token_Tag toString 
  875.     *
  876.     * @param    object    HTML_Template_Flexy_Token_Tag
  877.     * 
  878.     * @return   string     string to build a template
  879.     * @access   public 
  880.     * @see      toString*
  881.     */
  882.   
  883.     function toStringTag($element) {
  884.         if (strpos($element->tag,':') === false) {
  885.             $namespace = 'Tag';
  886.         } else {
  887.             $bits =  explode(':',$element->tag);
  888.             $namespace = $bits[0];
  889.         }
  890.         if ($namespace{0} == '/') {
  891.             $namespace = substr($namespace,1);
  892.         }
  893.         if (empty($this->tagHandlers[$namespace])) {
  894.             
  895.             require_once 'HTML/Template/Flexy/Compiler/Standard/Tag.php';
  896.             $this->tagHandlers[$namespace] = &HTML_Template_Flexy_Compiler_Standard_Tag::factory($namespace,$this);
  897.             if (!$this->tagHandlers[$namespace] ) {
  898.                 return HTML_Template_Flexy::raiseError('HTML_Template_Flexy::failed to create Namespace Handler '.$namespace . 
  899.                     ' in file ' . $GLOBALS['_HTML_TEMPLATE_FLEXY']['filename'],
  900.                     HTML_TEMPLATE_FLEXY_ERROR_SYNTAX ,HTML_TEMPLATE_FLEXY_ERROR_RETURN);
  901.             }
  902.                 
  903.         }
  904.         return $this->tagHandlers[$namespace]->toString($element);
  905.         
  906.         
  907.     }
  908.     
  909.  
  910. }
  911.