Buona notte a tutti, sono le 4:32 e domani ( anzi direi oggi ) ho un festa della birra che mi aspetta.
Spero anche che ci facciano entrare data la mia/nostra età ( 17 anni ).

Bando alle ciance: ho deciso di creare questa pillola in quanto conosco l'esigenza di dover dividere il codice html da quello php professionalmente.

L'unica cosa di cui abbiamo bisogno è di una cartella chmoddata con i permessi 0777 e di una classe che gestisce i template, non ho inserito i commenti in quanto successivamente spiegherò il funzionamento dei rispettivi metodi ( i commenti sono inseriti solo per dividere il codice ).

Codice PHP:
<?php

class Tpl_Template
{    
    
/**
    *
    */
    
var $tpl_tag;
    
    
/**
    *
    */
    
var $tpl_dir;
    
    
/**
    *
    */
    
var $tpl_ext;
    
    
/**
    *
    */
    
var $tpl_html;    
    
    
/**
    *
    */
    
var $tpl_cache;
    
    
    
/**
    *
    *
    */
    
function Tpl_Template$tpl_dir $tpl_ext $tpl_cache )
    {
        
$this->tpl_dir      $tpl_dir;
        
$this->tpl_ext      $tpl_ext;
        
$this->tpl_cache $tpl_cache;
        
        
//
        
$this->Check_Dir();
    }
    
    
/**
    *
    *
    */
    
function Check_Dir()
    {
        foreach ( array( 
$this->tpl_dir $this->tpl_cache ) AS $value )
        {
            if ( ! 
is_dir$value ) OR ! is_writable$value ) )
            {
                
trigger_errorget_class$this ) . "::Check_Dir() La cartella: ´{$value}´ non esiste o non è scrivibile." E_USER_ERROR );
            }
        }
    }
    
    
/**
    *
    *
    */
    
function Check_File$file )
    {
        if ( ! 
file_exists"$this->tpl_dir/$file.$this->tpl_ext) )
        {
            
trigger_errorget_class$this ) . "::Check_File()Il file: ´{$file}´ non esiste." E_USER_ERROR );
        }
    }
    
    
/**
    *
    *
    */
    
function Variable$param $value null )
    {
        if ( 
is_array$param ) )
        {
            foreach ( 
$param as $key => $value )
            {
                
$this->tpl_tag[$key] = $value;
            }
        }
        else
        {
            
$this->tpl_tag[$value] = $param;
        }
    }
    
    
/**
    *
    *
    */
    
function Load_Template$file )
    {
        
//
        
$this->Check_File$file );
        
        
//
        
$this->Compile_Template$file );
        
        
//
        
$this->Execute_Template$file );
    }
    
    
/**
    *
    *
    */
    
function Compile_Template$file )
    {
        
//
        
if ( file_exists"$this->tpl_cache/$file.php" ) )
        {
            return;
        }
        
        
//
        
$subject  file_get_contents"$this->tpl_dir/$file.$this->tpl_ext);
        
$pattern  "@(#\s*comment\s*#)|(#\s*/comment\s*#)|(#\s*foreach\s*direct\s*=\s*['|\"].*?['|\"]\s*#)|(#\s*/endforeach\s*#)|(#\s*if\s*direct\s*=\s*['|\"].*?['|\"]\s*#)|(#\s*elseif\s*direct\s*=\s*['|\"].*?['|\"]\s*#)|(#\s*else\s*#)|(#\s*/endif\s*#)@is";
        
$contents preg_split$pattern $subject , -PREG_SPLIT_DELIM_CAPTURE PREG_SPLIT_NO_EMPTY );
        
        
//
        
$loop $comment 0;
        
$this->tpl_html  "";
        
        
//
        
while ( $tpl array_shift$contents ) )
        {
            
//
            
if ( preg_match"@(#\s*comment\s*#)@is" $tpl ) )
            {
                
$comment++;
            }
            
            
//
            
elseif ( preg_match"@(#\s*/endcomment\s*#)@is" $tpl ) )
            {
                
$comment--;
            }
            
            
//
            
elseif ( preg_match"@(#\s*foreach\s*direct\s*=\s*['|\"](.*?)['|\"]\s*#)@is" $tpl $skin ) )
            {
                
$loop                $loop 1;
                
$vars                $this->Var_Replace$skin[2] );
                
$this->tpl_html .= "\n<?php foreach ( $vars as \$key_$loop => \$value_$loop ) { ?>\n";
            }
            
            
//
            
elseif ( preg_match"@(#\s*/endforeach\s*#)@is" $tpl ) )
            {
                
$loop                $loop 1;
                
$this->tpl_html .= "\n<?php } ?>\n";
            }
            
            
//
            
elseif ( preg_match"@(#\s*if\s*direct\s*=\s*['|\"](.*?)['|\"]\s*#)@is" $tpl $skin ) )
            {
                
$vars                $this->Var_Replace$skin[2] );
                
$this->tpl_html .= "\n<?php if ( $vars ) { ?>\n";
            }
            
            
//
            
elseif ( preg_match"@(#\s*elseif\s*direct\s*=\s*['|\"](.*?)['|\"]\s*#)@is" $tpl $skin ) )
            {
                
$vars                $this->Var_Replace$skin[2] );
                
$this->tpl_html .= "\n<?php } elseif ( $vars ) { ?>\n";
            }
            
            
//
            
elseif ( preg_match"@(#\s*else\s*#)@is" $tpl ) )
            {
                
$this->tpl_html .= "\n<?php } else { ?>\n";
            }
            
            
//
            
elseif ( preg_match"@(#\s*/endif\s*#)@is" $tpl ) )
            {
                
$this->tpl_html .= "\n<?php } ?>\n";
            }
            
            
//
            
else
            {
                if ( ! 
$comment )
                {
                    
$this->tpl_html .= $this->Var_Replace$tpl $loop true );
                }
            }
        }
        
        
//
        
$this->Create_Template$file );
    }
    
    
/**
    *
    *
    */
    
function Var_Replace$vars $loop false $echo false )
    {        
        
//
        
if ( $echo )
        {
            
$return preg_replace"@#\s+%(.*?)%\s+#@is" "<?php echo \$this->tpl_tag['$1'] ?>" $vars );
        }
        
        
//
        
else
        {
            
$return preg_replace"@%(.*?)%@" "\$this->tpl_tag['$1']" $vars );
        }
        
        
//
        
if ( $loop )
        {
            
$return preg_replace'#<\?php\s+echo\s*\$this->tpl_tag\[\'(key|value)\'\]\s*\?>#' "<?php echo \$$1_$loop ?>" $return );
        }
    
        return 
$return;
    }
    
    
/**
    *
    *
    */
    
function Create_Template$file )
    {
        if ( ! 
$fp = @ fopen"$this->tpl_cache/$file.php" "wb" ) )
        {
            
trigger_errorget_class$this ) . "::Create_Template() Impossibile creare il file ´{$file}´." E_USER_ERROR );
        }
        else
        {
            @ 
fwrite$fp $this->tpl_html );
            @ 
fclose$fp );
        }
    }
    
    
/**
    *
    *
    */
    
function Execute_Template$file )
    {
        
//
        
ob_start();

        
//
        
echo( "\n" );
        require_once( 
"$this->tpl_cache/$file.php" );
        echo( 
"\n" );

        
//
        
ob_end_flush();
    }
}

?>
Passiamo alla spiegazione della classe:

- Tpl_Template():
Questo metodo non fa altro che salvare il nome della cartella in cui sono salvati i template, la loro estensione e la cartella in cui verranno compilati. ( es. $tpl = new Tpl_Template( "./skin" , "tpl" , "./cache" ); )

- Check_Dir():
Non fa altro che controllare che la cartella "/skin" e "/cache" siano rispettivamente scrivibili ed esistenti.

- Check_File():
Controlla che il file skin ( es. prova.tpl ) esista realmente.

- Variable():
Salva tutte le variabili/array nell'array $this->tpl_tag che successivamente verrà utilizzata nel template compilato.

- Compile_Template():
Innanzi tutto controlla se il file esiste già in cache, se non esiste, esegue un file_get_contents sul file .tpl, dopodichè con un preg_split divide il codice e successivamente scorre il codice diviso con un while e sostituisce tutti i tag tpl ( es. # else # con <?php } else { ?> ).

- Var_Replace():
Sostituisce tutte le variabili nel file tpl, precisamente si comporta in tre modi diversi:
1) - Se la variabile si trova libera nel codice ( es. # %nome_var% # ) sostituisce i delimitatori con i tag php l'array $this->tpl_tag ( es .[b]<?php echo $this->tpl_tag['nome_var'] ?> );
2) - Se la variabile si trova in un if/elseif/foreach elimina i delimitatori e l'echo;
3) - Se la variabile si chiama # %key% # o # %value% #, la sostituisce rispettivamente con <?php echo $this->tpl_tag['key{$NUMERO_DEL_LOOP}'] ?> e <?php echo $this->tpl_tag['value{$NUMERO_DEL_LOOP}'] ?>;

- Create_Template():
Non fa altro che creare il file .php nella cartella "/cache" compilato.

- Execute_Template():
Include il file .php compilato.

Per chiarire con un esempio pratico il tutto, creiamo 2 cartelle: "cache" e "skin", dopodichè nella directory principale creiamo due file: "classe.php" ( il template engine ) e "index.php".
Nel file "index.php" inseriamo:
Codice PHP:
<?php

include "classe.php";

$tpl  = new Tpl_Template"./skin" "tpl" "./cache" );
$tpl -> Variable"Prima Variabile" "var1" );
$tpl -> Variable( array( "chiave1" => "valore1" "chiave2" => "valore2" "chiave3" => "valore3" ) );

$array = array( "array" => array( "luca" => "rossi" "marco" => "verdi" "giulia" => "bianchi" ) );
$tpl -> Variable$array );

$tpl -> Variablerand10) , "caso" );
 
$tpl -> Load_Template"prova" );

?>
Ora creiamo il file skin/prova.tpl :
codice:
<html><head></head><body>

Variabile: # %var1% #

Array1: # %chiave1% #

Array2: # %chiave2% #

Array3: # %chiave3% #


# comment #
Commento: ( ovviamente sarà cancellato )
# /endcomment #

# foreach direct = '%array%' #
 Nome: # %key% # => Cognome: # %value% # 

# /endforeach #

# if direct = '%caso% == "1"' #
  WoooW primo!!!

# elseif direct = '%caso% == "2"' #
  Non male, secondo!!!

# else #
  Andrà meglio la prossima volta!!!

# /endif #

</body></html>
Ed eseguiamo il codice... Non siate troppo severi, è la mia prima pillola.