[php4] moteur de template

Soyez le premier à donner votre avis sur cette source.

Vue 9 249 fois - Téléchargée 352 fois

Description

C'est un classique moteur de template. Realise en php4, le code tiens dans un seul fichier a inclure au debut de vos pages pour pouvoir en profiter. Ce n'est pas le code du siecle mais sa peut toujours servir pour une premiere approche dans le cadre d'une utilisation futur d'un moteur plus pousse (commerciale ou gratuit peu importe) genre phplib par exemple...
Pour ceux qui ne le savent pas, un moteur de template est en fait un code permettant la separation de la partie php et html d'une page web garce a des balises specifiques supporte par le moteur.
Voici la liste des fonctions proposees :
- SetImg() pour les images
- SetBlock() pour les blocks
- SetCss() pour les feuilles de styles
- SetVar() pour les variables
- SetFile() pour l'inclusion de fichier
- ReadFile() pour lire et renvoye le contenu d'un fichier

et 2/3 trucs en plus

Source / Exemple :


<?php
	/*
	
		Engine Template : V1.0.1
		Auteur : IoNAce
		E-Mail : ionace@c4.fr
			
		Fonctionnement du moteur :
			La creation d'une nouvelle classe passe par le constructeur. Ce constructeur prend en parametre le fichier modele
		sur lequel travailler. Un fichier modele est un fichier html (ou autre) comportant des balises specifiques au moteur.
		C'est le fichier qui effectue la mise en place des elements sur une page (le plus souvent) de facon generique.
		Le deuxieme parametre est le chemin et le nom complet du fichier log. Ce fichier comporte toutes les erreurs internes
		du moteur. La date, l'heure, la fonction qui a renvoye l'erreur et le type de l'erreur sont consignes par ecrit. Par 
		defaut, le constructeur surcharge ce parametre pour eviter d'en avoir a se preocuper. ATTENTION ! Le fichier log est 
		creer a l'endroit meme ou est le fichier engine.php !! 
			Une fois le modele charge, toutes les fonctions du moteur agiront sur la copie en memoire. Il est donc important 
		d'appeller la fonction Display() afin d'affiche le resultat. On peut donc utiliser plusieurs fois la meme fonction, 
		le resultat ne sera	disponible qu'a la fin. 

  • /
class Template { var $ContenuModele; var $EngineStatus; var $FichierLog; var $HandleLog; var $TableauOfBlock; var $DelTmpBlock; /* Constructeur. Lit le fichier modele est le fichier place en memoire. Le 3e param permet d'effacer les fichiers temporaires crees par la methode SetBlock()
  • /
function Template($Modele='', $ErrorLog='error.log', $DeleteTmpBlock=false) { // Initialisation de cette variable pour eviter les surprises $this->EngineStatus = false; // Indique a la classe quel est le nom du fichier log $this->FichierLog = $ErrorLog; // Indique a la classe qu'elle doit effacer les fichiers temporaires $this->DelTmpBlock = $DeleteTmpBlock; // Pour eviter les erreurs inutiles, on verifie que tous les parametres sont transmis if ( empty($Modele) ) die($this->SetLog('Template->Constructeur', 'Le fichier servant de modele n\'a pas ete indique. Il est impossible de continuer l\'execution sans ce fichier !')); // On verifie que le fichier existe if ( !file_exists($Modele) ) die($this->SetLog('Template->Constructeur', 'Le fichier indique servant de modele n\'existe pas !')); // On charge d'abord le modele puis on le lit integralement $HandleModele = @fopen($Modele, 'rb') or die($this->SetLog('Template->Constructeur', 'Erreur lors de l\'ouverture du fichier \''.$Modele.'\'.')); $this->ContenuModele = @fread($HandleModele, @filesize($Modele)) or die($this->SetLog('Template->Constructeur', 'Erreur lors de la lecture du fichier \''.$Modele.'\'.')); $this->TableauOfBlock = array(); // Si on en est la c'est bon le chargement est reussi $this->EngineStatus = true; } /* Gere les variables a partir du fichier modele place en memoire par le contructeur. Pour definir une variable -> <engine:var name="nom_de la variable" /> (attention aux guillemets !)
  • /
function SetVAr($NameOfVar='', $Value='') { // Si le moteur n'a pas ete demarre correctement if ( !$this->EngineStatus ) die($this->SetLog('Template->SetVAr()', 'Le moteur n\'a pas ete demarre avant d\'etre utilise !')); // Valeur de la balise a rempalcer $this->ContenuModele = str_replace('<engine:var name="'.$NameOfVar.'" />', $Value, $this->ContenuModele); } /* Gere les blocks. Balise => <engine:block name="nom_du_block">donnees</engine:block:nom_du_block> "Donnees" correspond au code present entre ces balises. On met les variables a traites dans des crochet [] Le 3e parametre ($MiseEnCache) sert a ecrire dans un fichier le modele du block afin d'eviter de le recharger et d'aller plus vite.
  • /
function SetBlock($NameOfBlock='', $Pointer='', $MiseEnCache=false) { // Si le moteur n'a pas ete demarre correctement if ( !$this->EngineStatus ) die($this->SetLog('Template->SetBlock()', 'Le moteur n\'a pas ete demarre avant d\'etre utilise !')); // On regarde si le block n'est pas mis en cache $CachedBlock = md5($NameOfBlock); // Si on veut mettre le block en cache if ( $MiseEnCache ) { // On essaye d'ouvrir le fichier cache $Handle = @fopen($CachedBlock, 'wb+') or die($this->SetLog('Template->SetBlock()', 'Le fichier temporaire pour le block "'.$NameOfBlock.'" ayant pour signature numerique '.$CachedBlock.' n\' a pas pu etre creer.')); $SizeOfFile = @filesize($CachedBlock); // Si le fichier contient du texte if ( $SizeOfFile ) { $ModeleBlock = @fread($Handle, filesize($CacheBlock)); } // Si le fichier est vide else { // Heu complique a expliquer la... :p On extrait le block du modele $First = stristr($this->ContenuModele, '<engine:block name="'.$NameOfBlock.'">'); $ModeleBlock = strrev(stristr(strrev($First), strrev('</engine:block:'.$NameOfBlock.'>'))); // On met en cache le block fputs($Handle, $ModeleBlock, strlen($ModeleBlock)) or die($this->SetLog('Template->SetBlock', 'Impossible d\'ecrire dans le fichier cache.')); } fclose($Handle); } else { // Heu complique a expliquer la... :p On extrait le block du modele $First = stristr($this->ContenuModele, '<engine:block name="'.$NameOfBlock.'">'); $ModeleBlock = strrev(stristr(strrev($First), strrev('</engine:block:'.$NameOfBlock.'>'))); } // Remplacement foreach ( $Pointer as $Index => $Value ) $ModeleBlock = str_replace('['.$Index.']', $Value, $ModeleBlock); // Ajout au tableau general if ( empty($this->TableauOfBlock[$NameOfBlock]) ) $this->TableauOfBlock[$NameOfBlock] = $ModeleBlock; else $this->TableauOfBlock[$NameOfBlock] .= $ModeleBlock; } /* Gere les images. Parametres : 1 - nom de la balise devant etre remplacee 2 - nom de l'image a mettre 3 - nom d'une classe pour eventuellement rajouter une feuille de style a l'image 4 - (FACULTATIF) largeur de l'image 5 - (FACULTATIF) hauteur de l'image Si les 2 derniers parametres ne sont pas transmis, la fonction va essayer de determiner elle meme la largeur et la hauteur de l'image. Si seul un des deux parametres est transmis, la fonction va chercher a calculer l'autre parametre en fonction de celui transmis (calcul du ratio entre les deux) Type de balise : <engine:img name="nom_de_l_image_a_afficher" />
  • /
function SetImg($NameOfBalise='', $Img='', $Class='', $X=0, $Y=0) { // Si le moteur n'a pas ete demarre correctement if ( !$this->EngineStatus ) die($this->SetLog('Template->SetImg()', 'Le moteur n\'a pas ete demarre avant d\'etre utilise !')); // Verfiie les parametres concernant les dimensiosn de l'images if ( !$X and !$Y ) $Action = 1; // calcul automatique else if ( $X and !$Y ) $Action = 2; // on calculera y else if ( !$X and $Y ) $Action = 3; // on calculera x else $Action = 0; // tous les parametres ont ete transmis // Si un calcul est necessaire, on prepare deja les v aleurs essentielles if ( $Action ) { // Recupere la largeur et la ahuteur de l'image $Values = @getimagesize($Img) or die($this->SetLog('Template->SetImg()', 'L\'obtention des dimensions de l\'image '.$Img.' a echouee.')); // X / Y = ratio de l'image $Ratio = $Values[0] / $Values[1]; // Calcul de tous les ratios switch ( $Action ) { case 2: // calcul de y en fonction de x => y = X / Ratio $Y = @round(($X/$Ratio), 0) or die($this->SetLog('Template->SetImg()', 'Division par zero ! Instruction : case ratio_x. $X = '.$X.'; $Ratio = '.$Ratio.';')); break; case 3: // calcul de x en fonction de y => x = Y * Ratio $X = @round(($Y*$Ratio), 0) or die($this->SetLog('Template->SetImg()', 'Division par zero ! Instruction : case ratio_y. $Y = '.$Y.'; $Ratio = '.$Ratio.';')); break; case 1: // simple, on recupere les valeurs du tableau renvoye par getimagesize() :p $X = $Values[0]; $Y = $Values[1]; break; default: die($this->SetLog('Template->SetImg()', 'L\'instruction switch( $Action ){} n\'a pas pu aboutir, la variable $Action a une valeur non-prise en charge.')); } } // Travail :p $this->ContenuModele = str_replace( '<engine:img name="'.$NameOfBalise.'" />', '<img src="'.$Img.'" width="'.$X.'" height="'.$Y.'" class="'.$Class.'" />', $this->ContenuModele ); } /* Gere les feuilles de styles. Balise : <engine:css />
  • /
function SetCss() { // Si le moteur n'a pas ete demarre correctement if ( !$this->EngineStatus ) die($this->SetLog('Template->SetCss()', 'Le moteur n\'a pas ete demarre avant d\'etre utilise !')); // Sinon, on recupere tous ces arguments dans un tableau $Args = @func_get_args(); // Variable recueillant toues les feuilles de styles pour la mise en cache $Css = ''; // On parcours le tableau for ( $i=0; $i<@func_num_args(); $i++ ) { // Details de l'implantation $Css .= '<link media="all" rel="stylesheet" type="text/css" href="'.$Args[$i].'" />'; } // Ajout des feuilles de styles $this->ContenuModele = str_replace('<engine:css />', $Css, $this->ContenuModele);; } /* Charge un fichier et remplace la balise <engine:file name="nom_du_fichier_a_mettre" /> par le contenu de celui-ci
  • /
function SetFile() { // Si le moteur n'a pas ete demarre correctement if ( !$this->EngineStatus ) die($this->SetLog('Template->SetFile()', 'Le moteur n\'a pas ete demarre avant d\'etre utilise !')); // On cherche les balises FILE $Regex = '!<engine:file name="(.+)" />!i'; // Recherche des expressions preg_match($Regex, $this->ContenuModele, $Out); // Travail for ( $i=0; $i<count($Out[0]); $i++ ) { // On nettoie le resultat pour n'obtenir que le nom du fichier demande $Fichier = str_replace('<engine:file name="', '', $Out[0][$i]); $Fichier = str_replace('" />', '', $Fichier); // Probleme : quand il n'y a qu'une seule balise, le deuxieme parametre est toujours egale a 0 donc sa plante. // Pour eviter ce soucis, on regarde si la valeur n'est pas NULL a un moment if ( !empty($Fichier) ) { // On ouvre le fichier demande $Handle = @fopen($Fichier, 'rb') or die($this->SetLog('Template->SetFile()', 'Impossible d\'ouvrir le fichier \''.$Fichier.'\'.')); // On lit tout le fichier et on renvoi son contenu $Contenu = @fread($Handle, @filesize($Fichier)) or die($this->SetLog('Template->SetFile()', 'Impossible de lire le fichier \''.$Fichier.'\'.')); // Preparation de la balise $Balise = '<engine:file name="'.$Fichier.'" />'; // Remplacement $this->ContenuModele = str_replace($Balise, $Contenu, $this->ContenuModele); } } } /* Ecris dans un fichier log les eventuelles erreurs d'execution
  • /
function SetLog($NameOfFonction='', $ErrorValue='') { // Ouverture du fichier $HandleLog = @fopen($this->FichierLog, 'ab') or die('Impossible d\'ouvrir le fichier log.<br>'); // Preparation du texte a ecrire (le \r\r\n permet de sauter une ligne dans un fichier sous Windows) $Date = date('\[\l\e d/m/Y\ \à H\h:i\m:s\s]'); $Log = $Date."\r\r\n".'La fonction '.$NameOfFonction.' a renvoye une erreur : '.$ErrorValue; $Log .= "\r\r\n".'Adresse IP de la connexion : '.$_SERVER['REMOTE_ADDR']."\r\r\n"; $Log .= '_________________'."\r\r\n\r\r\n"; // Ecriture dans le fichier @fputs($HandleLog, $Log) or die('Imossible d\'ecrire dans le fichier log.<br>'); // Fermetture du fichier @fclose($HandleLog); // On informe l'utilisateur qu'il y a eu une erreur return '[ERREUR INTERNE] - Il y a eu une erreur. Consultez le fichier log pour en connaître la raison.<br>Date : '.$Date; } /* Lit un fichier et renvoi son contenu. Peut etre utilise pour la fonction SetBloc() => SetVar('nom_du_bloc', ReadFile('fichier_a_lire'));
  • /
function ReadFile($FileToRead='') { // Si le moteur n'a pas ete demarre correctement if ( !$this->EngineStatus ) die($this->SetLog('Template->ReadFile()', 'Le moteur n\'a pas ete demarre avant d\'etre utilise !')); // On ouvre le fichier demande $Handle = @fopen($FileToRead, 'rb') or die($this->SetLog('Template->ReadFile()', 'Impossible d\'ouvrir le fichier \''.$FileToRead.'\'.')); // On lit tout le fichier et on renvoi son contenu $Contenu = @fread($Handle, @filesize($FileToRead)) or die($this->SetLog('Template->ReadFile()', 'Impossible de lire le fichier \''.$FileToRead.'\'.')); return $Contenu; } /* Fonction gerant le BBCode. Peut etre pas super utile a premiere vue mais peut toujours depanner :-) Si une variable est transmise, la fonction va activer le bbcode sur le contenu de cette variable sinon, elle le fera sur le fichier modele.
  • /
function SetBBCode($Value='') { // Si le moteur n'a pas ete demarre correctement if ( !$this->EngineStatus ) die($this->SetLog('Template->SetBBCode()', 'Le moteur n\'a pas ete demarre avant d\'etre utilise !')); // Si une variables n'a pas ete transmise, on considere $Value comme une reference a $ContenuModele if ( !$Value ) { $Value = &$this->ContenuModele; $Reference = true; } else { $Reference = false; } /* On remplace toutes les balises pouvant etre enleve sans regex */ // Saut de ligne $Value = str_replace('[br]', '<br />', $Value); // Italique $Value = str_replace('[i]', '<i>', $Value); $Value = str_replace('/i', '</i>', $Value); // Gras $Value = str_replace('[b]', '<b>', $Value); $Value = str_replace('/b', '</b>', $Value); // Souligne $Value = str_replace('[u]', '<u>', $Value); $Value = str_replace('/u', '</u>', $Value); // Liste $Value = str_replace('[list]', '<ul>', $Value); $Value = str_replace('/list', '</ul>', $Value); // Puce dans liste $Value = str_replace('[li]', '<li>', $Value); $Value = str_replace('/li', '</li>', $Value); // Toutes les balises fermees qui utilisent des regex pour leurs balises ouvertes $Value = str_replace('/size', '</span>', $Value); $Value = str_replace('/align', '</div>', $Value); $Value = str_replace('/color', '</span>', $Value); $Value = str_replace('/citation', '</span></fieldset><br>', $Value); // Tabulation $Value = str_replace("\t", '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;', $Value); /* On attaque les regex :p */ // Les images $Value = preg_replace( '!\[img\=(http|news|ftp|https){1}(://){1}([a-z0-9]+[a-z0-9/.-]*\.)(gif|bmp|png|jpg|jpeg)\]!i', '<img src="\\1\\2\\3\\4" />', $Value ); // Les liens vers des sites $Value = preg_replace( '!(http|news|ftp|https){1}(://){1}([a-z0-9]+[a-z0-9/.-]*[a-z]+)!i', '<a title="Aller vers \\3" target="_blank" href="\\1\\2\\3">\\1\\2\\3</a>', $Value ); // Les mails $Value = preg_replace( '!([a-z09][a-z0-9._-]*[a-z09]@{1}[a-z09][a-z0-9._-]*[a-z09]\.{1}[a-z]{2,4})!', '<a title="Envoyer un email à \\1" href="mailto:\\1">\\1</a>', $Value ); // La couleur du texte $Value = preg_replace( '!\[color=([a-z#0-9]+)\]!i', '<span style="color:\\1;">', $Value ); // Taille du texte $Value = preg_replace( '!\[size=([0-9]+)\]!i', '<span style="font-size:\\1px;">', $Value ); // Alignement du texte $Value = preg_replace( '!\[align=(center|justify|left|right)\]!i', '<div align="\\1">', $Value ); // Citation $Value = preg_replace( '!\[citation=(.+)\]!i', '<br><fieldset style="background-color:#00CCFF;width:400px;text-align:justify;"><legend><b>\\1 a dit </b></legend><span style="color:#000000;font-size:12px;">', $Value ); if ( !$Reference ) return $Value; } /* Cette fonction affiche le modele en memoire. N'appeller cette fonction qu'a la fin du traitement !
  • /
function Display() { // On affiche les blocks foreach ( $this->TableauOfBlock as $Indice => $Value ) { $Regex = '!<engine:block name="'.$Indice.'">.*</engine:block:'.$Indice.'>!iUms'; $this->ContenuModele = @preg_replace($Regex, $Value, $this->ContenuModele) or die($this->SetLog('Template->Display()', 'Evaluation de l\'expression '.$Regex.' impossible.')); // On efface les derniers blocks ... $this->ContenuModele = str_replace('<engine:block name="'.$Indice.'">', '', $this->ContenuModele); $this->ContenuModele = str_replace('</engine:block:'.$Indice.'>', '', $this->ContenuModele); // ... ainsi que leurs fichiers temporaire if ( $this->DelTmpBlock ) @unlink(md5($Indice)); } // On affiche le contenu du fichier modele echo $this->ContenuModele; } } ?>

Conclusion :


Voila le niveau n'est pas extreme mais il y quelques suptilites, sa sera a vous de juger.
Derniere chose, pour ceux qui se demandent pourquoi j'ai realise une classe en php4 alors que php5 est super, tout simplement parce que mon hebergeur est toujours en php4 ... de toute facon le portage du code en php5 n'est pas d'une difficulte enorme, y a 3 trucs a changer et sa tourne ^^ (mais bon pour ceux qui veulent je peut faire un petit effort et le mettre en zip en php5... ;-) )

En esperant que sa vous plaira

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
449
Date d'inscription
jeudi 26 août 2004
Statut
Membre
Dernière intervention
5 mars 2009

La gestion des blocks imbriques ne marche pas !! Je pensais que c'etait une erreur de me aprt lors de l'implementation du code exploitant le moteur mais en fait pas du tout .... c'ets bien mon code ... donc pour l'instant faudra attendre pour l'imbriquation des blocks .. (par contre pour la mise en cache pas de soucis !)

@++
Messages postés
908
Date d'inscription
jeudi 26 juillet 2001
Statut
Modérateur
Dernière intervention
1 février 2015
2
oui c'est un flood interssant :)
Messages postés
449
Date d'inscription
jeudi 26 août 2004
Statut
Membre
Dernière intervention
5 mars 2009

Voila le code a ete mis a jour :p
Si vous pouviez me dire ce que vous en pensez sa serait cool merci :-)
(pensez a la note sa fait toujours plaisir)
Messages postés
449
Date d'inscription
jeudi 26 août 2004
Statut
Membre
Dernière intervention
5 mars 2009

lol c'est vrai que moi aussi ma boite mail me fait peur tous les jours ^^ !! Mais comme l'a dit malalam, c'est une discution tres interessante.
A propos de la mise en cache des blocks (reponse pour kankrelune) j'ai fini de l'implementer ce week-end.. j'ai encore ma cle usb donc je la met en ligne des demain je pense (si j'ai aps encore oublie :p)

Merci a tous !
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
22
On dira que c'était un flood intéressant, alors.
Afficher les 42 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.