Fast Template CVS revision 1.2.0

Publicado por Ragen Dazs 08/10/2003

[ Hits: 8.050 ]

Homepage: http://www.orkut.com

Download FastTemplate.class.php




A Fast Template é uma classe muito eficiente na utilização de modelos
para scripts PHP. Elas nos permite ganho de
tempo e facilita em muito a tarefa do web designer, que deixa
de ter acesso aos códigos PHP do site, ou seja, o código PHP fica totalmente separado dos scripts PHP.

Fiz algumas implementações nessa classe e estou diponibilizando aqui:

- Sistema de cache
- Suporte a script tags '<? ?>' em blocos dinâmicos, gerando assim páginas cacheadas dinâmicas


Vale a pena =]

  



Esconder código-fonte

<?

/*
    CVS Revision. 1.1.0 - Default Fast Template

   
    CVS Revision. 1.2.0 - Cache functions added

    Author: Allyson Francisco de Paula Reis
    E-mail: ragen@oquerola.com
*/

class FastTemplate {

   var $FILELIST   =   array();   //   Holds the array of filehandles
                           //   FILELIST[HANDLE] == "fileName"

   var $DYNAMIC   =   array();   //   Holds the array of dynamic
                           //   blocks, and the fileHandles they
                           //   live in.

   var $PARSEVARS   =   array();   //   Holds the array of Variable
                           //   handles.
                           //   PARSEVARS[HANDLE] == "value"

   var   $LOADED      =   array();   //   We only want to load a template
                           //   once - when it's used.
                           //   LOADED[FILEHANDLE] == 1 if loaded
                           //   undefined if not loaded yet.

   var   $HANDLE      =   array();   //   Holds the handle names assigned
                           //   by a call to parse()

   var   $ROOT      =   "";         //   Holds path-to-templates

   var $WIN32      =   false;      //   Set to true if this is a WIN32 server

   var $ERROR      =   "";         //   Holds the last error message

   var $LAST      =   "";         //   Holds the HANDLE to the last
                           //   template parsed by parse()

   var $STRICT      =   true;      //   Strict template checking.
                           //   Unresolved vars in templates will
                           //   generate a warning when found.

   var $USE_CACHE  =   false;      //  Enable caching mode. 
                                   //  Default: false

   var $UPDT_TIME  =   '60';       //  Time in seconds to expire cache 
                                   //  files
   
   var $CACHE_PATH =   './cache';  //  Dir for save cached files 

   var $CACHING    =   false;      //  Control variable of cache. It 
                                   //  prevents the return of an archive
                           //  in cache while they are generated
                           //  (To prevent pages with "corrupted"
                           //  return) 


//   ************************************************************

   function FastTemplate ($pathToTemplates = "")
   {

      global $php_errormsg;

      if(!empty($pathToTemplates))
      {
         $this->set_root($pathToTemplates);
      }

   }   // end (new) FastTemplate ()


//   ************************************************************
//   All templates will be loaded from this "root" directory
//   Can be changed in mid-process by re-calling with a new
//   value.

   function set_root ($root)
   {
      $trailer = substr($root,-1);

      if(!$this->WIN32)
      {
         if( (ord($trailer)) != 47 )
         {
            $root = "$root". chr(47);
         }

         if(is_dir($root))
         {
            $this->ROOT = $root;
         }
         else
         {
            $this->ROOT = "";
            $this->error("Specified ROOT dir [$root] is not a directory");
         }
      }
      else
      {
         // WIN32 box - no testing
         if( (ord($trailer)) != 92 )
         {
            $root = "$root" . chr(92);
         }
         $this->ROOT = $root;
      }

   }   // End set_root()


//  **************************************************************
//  Calculates current microtime
//   I throw this into all my classes for benchmarking purposes
//   It's not used by anything in this class and can be removed
//   if you don't need it.


   function utime ()
   {
      $time = explode( " ", microtime());
      $usec = (double)$time[0];
      $sec = (double)$time[1];
      return $sec + $usec;
    }

//  **************************************************************
//   Strict template checking, if true sends warnings to STDOUT when
//   parsing a template with undefined variable references
//   Used for tracking down bugs-n-such. Use no_strict() to disable.

   function strict ()
   {
      $this->STRICT = true;
   }

//   ************************************************************
//   Silently discards (removes) undefined variable references
//   found in templates

   function no_strict ()
   {
      $this->STRICT = false;
   }

//   ************************************************************
//   A quick check of the template file before reading it.
//   This is -not- a reliable check, mostly due to inconsistencies
//   in the way PHP determines if a file is readable.

   function is_safe ($filename)
   {
      if(!file_exists($filename))
      {
         $this->error("[$filename] does not exist",0);
         return false;
      }
      return true;
   }

//   ************************************************************
//   Grabs a template from the root dir and 
//   reads it into a (potentially REALLY) big string

   function get_template ($template)
   {
      if(empty($this->ROOT))
      {
         $this->error("Cannot open template. Root not valid.",1);
         return false;
      }

      $filename   =   "$this->ROOT"."$template";

      $contents = implode("",(@file($filename)));
      if( (!$contents) or (empty($contents)) )
      {
         $this->error("get_template() failure: [$filename] $php_errormsg",1);
      }

      return $contents;

   } // end get_template

//   ************************************************************
//   Prints the warnings for unresolved variable references
//   in template files. Used if STRICT is true

   function show_unknowns ($Line)
   {
      $unknown = array();
      if (ereg("({[A-Z0-9_]+})",$Line,$unknown))
      {
         $UnkVar = $unknown[1];
         if(!(empty($UnkVar)))
         {
            @error_log("[FastTemplate] Warning: no value found for variable: $UnkVar ",0);
         }
      }
   }   // end show_unknowns()

//   ************************************************************
//   This routine get's called by parse() and does the actual
//   {VAR} to VALUE conversion within the template.

   function parse_template ($template, $tpl_array)
   {
      while ( list ($key,$val) = each ($tpl_array) )
      {
         if (!(empty($key)))
         {
            if(gettype($val) != "string")
            {
               settype($val,"string");
            }

            $template = ereg_replace("{$key}","$val","$template");
            //$template = str_replace("{$key}","$val","$template");
         }
      }

      if(!$this->STRICT)
      {
         // Silently remove anything not already found

         $template = ereg_replace("{([A-Z0-9_]+)}","",$template);
      }
      else
      {
         // Warn about unresolved template variables
         if (ereg("({[A-Z0-9_]+})",$template))
         {
            $unknown = split("\n",$template);
            while (list ($Element,$Line) = each($unknown) )
            {
               $UnkVar = $Line;
               if(!(empty($UnkVar)))
               {
                  $this->show_unknowns($UnkVar);
               }
            }
         }
      }
      return $template;

   }   // end parse_template();

//   ************************************************************
//   The meat of the whole class. The magic happens here.

   function parse ( $ReturnVar, $FileTags )
   {
      $append = false;
      $this->LAST = $ReturnVar;
      $this->HANDLE[$ReturnVar] = 1;

      if (gettype($FileTags) == "array")
      {
         unset($this->$ReturnVar);   // Clear any previous data

         while ( list ( $key , $val ) = each ( $FileTags ) )
         {
            if ( (!isset($this->$val)) || (empty($this->$val)) )
            {
               $this->LOADED["$val"] = 1;
               if(isset($this->DYNAMIC["$val"]))
               {
                  $this->parse_dynamic($val,$ReturnVar);
               }
               else
               {
                  $fileName = $this->FILELIST["$val"];
                  $this->$val = $this->get_template($fileName);
               }
            }

            //   Array context implies overwrite

            $this->$ReturnVar = $this->parse_template($this->$val,$this->PARSEVARS);

            //   For recursive calls.

            $this->assign( array( $ReturnVar => $this->$ReturnVar ) );

         }
      }   // end if FileTags is array()
      else
      {
         // FileTags is not an array

         $val = $FileTags;

         if( (substr($val,0,1)) == '.' )
         {
            // Append this template to a previous ReturnVar

            $append = true;
            $val = substr($val,1);
         }

         if ( (!isset($this->$val)) || (empty($this->$val)) )
         {
               $this->LOADED["$val"] = 1;
               if(isset($this->DYNAMIC["$val"]))
               {
                  $this->parse_dynamic($val,$ReturnVar);
               }
               else
               {
                  $fileName = $this->FILELIST["$val"];
                  $this->$val = $this->get_template($fileName);
               }
         }

         if($append)
         {
            $this->$ReturnVar .= $this->parse_template($this->$val,$this->PARSEVARS);
         }
         else
         {
            $this->$ReturnVar = $this->parse_template($this->$val,$this->PARSEVARS);
         }

         //   For recursive calls.

         $this->assign(array( $ReturnVar => $this->$ReturnVar) );

      }
      return;
   }   //   End parse()


//   ************************************************************
//  Cache in CVS revision 1.2.0 by ragen@oquerola.com

   function FastPrint ( $template = "" )
   {
      if(empty($template))
      {
         $template = $this->LAST;
      }

      if( (!(isset($this->$template))) || (empty($this->$template)) )
      {
         $this->error("Nothing parsed, nothing printed",0);
         return;
      }
      elseif ($this->USE_CACHE)
      {
         $this->cache_file($this->$template);         
      }
      else {
         print $this->$template;
      }
      return;
   }

//   ************************************************************
//  Try to use cached files. Duh! - ragen@oquerola.com

   function USE_CACHE () {
      $this->USE_CACHE = true;
      $this->verify_cached_files();
   }

//   ************************************************************
//  Verify if cache files are updated (in function of $UPDT_TIME)
//  then return cached page and exit - ragen@oquerola.com

   function verify_cached_files () {

      if (($this->USE_CACHE) && ($this->cache_file_is_updated())) 
      {

         // self_script() - return script as called Fast Template class

         require $this->self_script();
         echo "<script>alert('Usando cache')</script>";
         exit(1);
      }

   }

//   ************************************************************
//   Return script as called Fast Template class 
//  by ragen@oquerola.com

   function self_script () {

      $fname = getenv('SCRIPT_NAME');
      $fname = $this->cache_path($fname);

      return $fname;
   }

//   ************************************************************
//   Return the real path for write cache files 
//  by ragen@oquerola.com

   function cache_path ( $fname )
   {
      $fname = explode("/",$fname);
      $fname = $fname[count($fname) - 1];
      return $this->CACHE_PATH."/".$fname;
   }

// *************************************************************
// Return the script as called Fast Template in cache dir
// by ragen@oquerola.com

   function self_script_in_cache_path ()
   {
      $fname = explode("/",$this->self_script());
      $fname = $fname[count($fname) - 1];
      return $this->CACHE_PATH."/".$fname;
   }


//   ************************************************************
//   Verify if cache file is updated or expired 
//  by ragen@oquerola.com

   function cache_file_is_updated() {

      // Verification of cache expiration
      // filemtime() -> return unix time of last modification in file
      // time() -> return unix time

      $fname = $this->self_script_in_cache_path();
      if (!file_exists($fname)) {
         return false;         
      }
      
      $expire_time = time() - filemtime($fname);
      
      if ($expire_time >= $this->UPDT_TIME) 
      {
         return false;         
      } 
      else 
      { 
         return true;
      }

   }

//   ************************************************************
//   The meat of the whole class. The magic happens here.
//  by ragen@oquerola.com

   function cache_file ( $content = "" )
   {

      if (($this->USE_CACHE) && (!$this->cache_file_is_updated())) {

         $fname = $this->self_script_in_cache_path();

         // Tendo certeza que o arquivo existe e que há permissão de escrita primeiro.
         //if (is_writable($fname)) {
            
            // Opening $fname in writing only mode
            
            if (!$fp = fopen($fname, 'w')) {
               $this->error("Error while opening cache file ($fname)",0);
               return;
            }

            // Writing $content to open file.
            
            if (!fwrite($fp, $content)) {
               $this->error("Error while writing cache file ($fname)",0);
               return;
            }
            else {
               fclose($fp);
               require $this->self_script_in_cache_path();
               return;
            }

            fclose($fp);

         //} else {
         //   $this->error("The cache file $fname is not writable",0);
         //   return;
         //}
         
      }
   }

//   ************************************************************

   function fetch ( $template = "" )
   {
      if(empty($template))
      {
         $template = $this->LAST;
      }
      if( (!(isset($this->$template))) || (empty($this->$template)) )
      {
         $this->error("Nothing parsed, nothing printed",0);
         return "";
      }

      return($this->$template);
   }


//   ************************************************************

   function define_dynamic ($Macro, $ParentName)
   {
      //   A dynamic block lives inside another template file.
      //   It will be stripped from the template when parsed
      //   and replaced with the {$Tag}.

      $this->DYNAMIC["$Macro"] = $ParentName;
      return true;
   }

//   ************************************************************

   function parse_dynamic ($Macro,$MacroName)
   {
      // The file must already be in memory.

      $ParentTag = $this->DYNAMIC["$Macro"];
      if( (!$this->$ParentTag) or (empty($this->$ParentTag)) )
      {
         $fileName = $this->FILELIST[$ParentTag];
         $this->$ParentTag = $this->get_template($fileName);
         $this->LOADED[$ParentTag] = 1;
      }
      if($this->$ParentTag)
      {
         $template = $this->$ParentTag;
         $DataArray = split("\n",$template);
         $newMacro = "";
         $newParent = "";
         $outside = true;
         $start = false;
         $end = false;
         while ( list ($lineNum,$lineData) = each ($DataArray) )
         {
            $lineTest = trim($lineData);
            if("<!-- BEGIN DYNAMIC BLOCK: $Macro -->" == "$lineTest" )
            {
               $start = true;
               $end = false;
               $outside = false;
            }
            if("<!-- END DYNAMIC BLOCK: $Macro -->" == "$lineTest" )
            {
               $start = false;
               $end = true;
               $outside = true;
            }
            if( (!$outside) and (!$start) and (!$end) )
            {
               $newMacro .= "$lineData\n"; // Restore linebreaks
            }
            if( ($outside) and (!$start) and (!$end) )
            {
               $newParent .= "$lineData\n"; // Restore linebreaks
            }
            if($end)
            {
               $newParent .= "{$MacroName}\n";
            }
            // Next line please
            if($end) { $end = false; }
            if($start) { $start = false; }
         }   // end While

         $this->$Macro = $newMacro;
         $this->$ParentTag = $newParent;
         return true;

      }   // $ParentTag NOT loaded - MAJOR oopsie
      else
      {
         @error_log("ParentTag: [$ParentTag] not loaded!",0);
         $this->error("ParentTag: [$ParentTag] not loaded!",0);
      }
      return false;
   }

//   ************************************************************
//   Strips a DYNAMIC BLOCK from a template.

   function clear_dynamic ($Macro="")
   {
      if(empty($Macro)) { return false; }

      // The file must already be in memory.

      $ParentTag = $this->DYNAMIC["$Macro"];

      if( (!$this->$ParentTag) or (empty($this->$ParentTag)) )
      {
         $fileName = $this->FILELIST[$ParentTag];
         $this->$ParentTag = $this->get_template($fileName);
         $this->LOADED[$ParentTag] = 1;
      }

      if($this->$ParentTag)
      {
         $template = $this->$ParentTag;
         $DataArray = split("\n",$template);
         $newParent = "";
         $outside = true;
         $start = false;
         $end = false;
         while ( list ($lineNum,$lineData) = each ($DataArray) )
         {
            $lineTest = trim($lineData);
            if("<!-- BEGIN DYNAMIC BLOCK: $Macro -->" == "$lineTest" )
            {
               $start = true;
               $end = false;
               $outside = false;
            }
            if("<!-- END DYNAMIC BLOCK: $Macro -->" == "$lineTest" )
            {
               $start = false;
               $end = true;
               $outside = true;
            }
            if( ($outside) and (!$start) and (!$end) )
            {
               $newParent .= "$lineData\n"; // Restore linebreaks
            }
            // Next line please
            if($end) { $end = false; }
            if($start) { $start = false; }
         }   // end While

         $this->$ParentTag = $newParent;
         return true;

      }   // $ParentTag NOT loaded - MAJOR oopsie
      else
      {
         @error_log("ParentTag: [$ParentTag] not loaded!",0);
         $this->error("ParentTag: [$ParentTag] not loaded!",0);
      }
      return false;
   }


//   ************************************************************

   function define ($fileList)
   {
      while ( list ($FileTag,$FileName) = each ($fileList) )
      {
         $this->FILELIST["$FileTag"] = $FileName;
      }
      return true;
   }

//   ************************************************************

   function clear_parse ( $ReturnVar = "")
   {
      $this->clear($ReturnVar);
   }

//   ************************************************************

   function clear ( $ReturnVar = "" )
   {
      // Clears out hash created by call to parse()

      if(!empty($ReturnVar))
      {
         if( (gettype($ReturnVar)) != "array")
         {
            unset($this->$ReturnVar);
            return;
         }
         else
         {
            while ( list ($key,$val) = each ($ReturnVar) )
            {
               unset($this->$val);
            }
            return;
         }
      }

      // Empty - clear all of them

      while ( list ( $key,$val) = each ($this->HANDLE) )
      {
         $KEY = $key;
         unset($this->$KEY);
      }
      return;

   }   //   end clear()

//   ************************************************************

   function clear_all ()
   {
      $this->clear();
      $this->clear_assign();
      $this->clear_define();
      $this->clear_tpl();

      return;

   }   //   end clear_all

//   ************************************************************

   function clear_tpl ($fileHandle = "")
   {
      if(empty($this->LOADED))
      {
         // Nothing loaded, nothing to clear

         return true;
      }
      if(empty($fileHandle))
      {
         // Clear ALL fileHandles

         while ( list ($key, $val) = each ($this->LOADED) )
         {
            unset($this->$key);
         }
         unset($this->LOADED);

         return true;
      }
      else
      {
         if( (gettype($fileHandle)) != "array")
         {
            if( (isset($this->$fileHandle)) || (!empty($this->$fileHandle)) )
            {
               unset($this->LOADED[$fileHandle]);
               unset($this->$fileHandle);
               return true;
            }
         }
         else
         {
            while ( list ($Key, $Val) = each ($fileHandle) )
            {
               unset($this->LOADED[$Key]);
               unset($this->$Key);
            }
            return true;
         }
      }

      return false;

   }   // end clear_tpl

//   ************************************************************

   function clear_define ( $FileTag = "" )
   {
      if(empty($FileTag))
      {
         unset($this->FILELIST);
         return;
      }

      if( (gettype($Files)) != "array")
      {
         unset($this->FILELIST[$FileTag]);
         return;
      }
      else
      {
         while ( list ( $Tag, $Val) = each ($FileTag) )
         {
            unset($this->FILELIST[$Tag]);
         }
         return;
      }
   }

//   ************************************************************
//   Aliased function - used for compatibility with CGI::FastTemplate
   function clear_parse ()
   {
      $this->clear_assign();
   }

//   ************************************************************
//   Clears all variables set by assign()

   function clear_assign ()
   {
      if(!(empty($this->PARSEVARS)))
      {
         while(list($Ref,$Val) = each ($this->PARSEVARS) )
         {
            unset($this->PARSEVARS["$Ref"]);
         }
      }
   }

//   ************************************************************

   function clear_href ($href)
   {
      if(!empty($href))
      {
         if( (gettype($href)) != "array")
         {
            unset($this->PARSEVARS[$href]);
            return;
         }
         else
         {
            while (list ($Ref,$val) = each ($href) )
            {
               unset($this->PARSEVARS[$Ref]);
            }
            return;
         }
      }
      else
      {
         // Empty - clear them all

         $this->clear_assign();
      }
      return;
   }

//   ************************************************************

   function assign ($tpl_array, $trailer="")
   {
      if(gettype($tpl_array) == "array")
      {
         while ( list ($key,$val) = each ($tpl_array) )
         {
            if (!(empty($key)))
            {
               //   Empty values are allowed
               //   Empty Keys are NOT

               $this->PARSEVARS["$key"] = $val;
            }
         }
      }
      else
      {
         // Empty values are allowed in non-array context now.
         if (!empty($tpl_array))
         {
            $this->PARSEVARS["$tpl_array"] = $trailer;
         }
      }
   }

//   ************************************************************
//   Return the value of an assigned variable.
//   Christian Brandel cbrandel@gmx.de

   function get_assigned($tpl_name = "")
   {
      if(empty($tpl_name)) { return false; }
      if(isset($this->PARSEVARS["$tpl_name"]))
      {
         return ($this->PARSEVARS["$tpl_name"]);
      }
      else
      {
         return false;
        }
   }

//   ************************************************************

   function error ($errorMsg, $die = 0)
   {
      $this->ERROR = $errorMsg;
      echo "ERROR: $this->ERROR <BR> \n";
      if ($die == 1)
      {
         exit;
      }

      return;

   } // end error()


//   ************************************************************


//   ************************************************************

} // End FastTemplate.class.php

?>

Scripts recomendados

Tabela Temporária PHP

Contador Automático

framework ajaxphp

Monitoramento simples de servidores [versão 1.0]

Folha de Ponto, com datas móveis como Carnaval Sexta-Feira Santa e Corpus Christi


  

Comentários
[1] Comentário enviado por Ragen em 08/10/2003 - 15:55h

Comentem a linha 382 -> echo "<script>alert('Usando cache')</script>";

Esqueci de remover esse comando enquanto debugava a classe.

-------------------
Exemplo do uso da classe:

crie um dir ./cache (Configuração padrão)

<!-- programa index.php -->
<?php
include "FastTemplate.class.php";

// Inicializando a fast template
$template = new FastTemplate('./html');

// Setando o uso de cache
$template->USE_CACHE();

$template-> define (
array (
'pagina' => 'index.htm'
)
);


// Substituindo em 08/10/2003 a data atual
$template->assign('08/10/2003',date("d/m/Y"));

// Substituindo em {HORA} a função de retorno de hora atual
// para geração um cache dinâmico
$template->assign('{HORA}','<?=date("H:i:s")?>');

// atribui ao handle OUTPUT a saída do processamento do modelo
$template->parse('OUTPUT','pagina');

// imprime na tela o conteúdo de OUTPUT
$template->FastPrint('OUTPUT');
?>
<!-- fim programa -->

<!-- ./html/index.htm -->
<HTML>
<BODY BGCOLOR="#ffffff">
<h2>Um Simples Modelo</h2>
Data de hoje é ...08/10/2003<br>
E a hora: {HORA}
</BODY>
</HTML>
<!-- fim do modelo -->

[2] Comentário enviado por Ragen em 08/10/2003 - 15:59h

Blah!

O site do Viva o Linux usa templates aqui a chave { DATA } já esta reservada, vou portar o exemplo novamente :)


--------------------

<!-- programa index.php -->
<?php
include "FastTemplate.class.php";

// Inicializando a fast template
$template = new FastTemplate('./html');

// Setando o uso de cache
$template->USE_CACHE();

$template-> define (
array (
'pagina' => 'index.htm'
)
);


// Substituindo em {DATA_ATUAL} a data atual
$template->assign('{DATA_ATUAL}',date("d/m/Y"));

// Substituindo em {HORA} a função de retorno de hora atual
// para geração um cache dinâmico
$template->assign('{HORA}','<?=date("H:i:s")?>');

// atribui ao handle OUTPUT a saída do processamento do modelo
$template->parse('OUTPUT','pagina');

// imprime na tela o conteúdo de OUTPUT
$template->FastPrint('OUTPUT');
?>
<!-- fim programa -->

<!-- ./html/index.htm -->
<HTML>
<BODY BGCOLOR="#ffffff">
<h2>Um Simples Modelo</h2>
Data de hoje é ...{DATA_ATUAL}<br>
E a hora: {HORA}
</BODY>
</HTML>
<!-- fim do modelo -->


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts