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_error( get_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_error( get_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 , -1 , 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_error( get_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 -> Variable( rand( 1 , 10) , "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.