Problème avec mon moteur de template - Blocs imbriqués

cs_christophedlr Messages postés 267 Date d'inscription samedi 3 janvier 2004 Statut Membre Dernière intervention 23 août 2023 - 19 févr. 2011 à 09:18
cs_christophedlr Messages postés 267 Date d'inscription samedi 3 janvier 2004 Statut Membre Dernière intervention 23 août 2023 - 22 févr. 2011 à 15:59
Bonjour à tous,

Voila je suis entrain de programmer mon site internet et je suis tombé sur un gros bug avec mon moteur de template. Quand la fonction assign_block_vars remplace un bloc, aucun soucis mais dès que c'est le bloc parent (cas des blocs imbriqués), tout est bon SAUF le dernier remplacement à effectuer où là le moteur laisse la balise de fin de bloc.

Sur mon moteur, les blocs sont composés comme ceci : <!--BLOCK_NOM--> et pour la fin : <!--/BLOCK_NOM-->, les variables dedans sont composés comme ceci : {NOMBLOC.VAR}.

Voici le code du moteur :
<?php

class Template
{
private $directory; //Nom du répertoire de base des templates
private $contentfile = array(); //Contenu des fichiers ouverts
private $allcontentblock = array(); //Contenu complet (masque complet) des blocs

/*Constructeur de la classe*/
function __construct($directory)
{
if ( is_string($directory) )
{
$this->directory = $directory.'/';
return;
}

echo "Erreur Template::__construct - Vous n'avez pas spécifié une chaîne de caractères
";
}

/*Ouvre un template*/
function open($filename, $directory = '')
{
if ( !is_string($filename) )
{
echo "Erreur Template::open - Vous n'avez pas entré un nom de fichier
";
}

/*Si le fichier existe à l'emplacement par défaut*/
if ( file_exists($this->directory.$filename) )
{
$this->contentfile[$filename] = file_get_contents($this->directory.$filename);
return $filename;
}

else
{
/*Si le fichier est dans un répertoire différent, par exemple un module*/
if ( file_exists($directory.$this->directory.$filename) )
{
$this->contentfile[$directory.$this->directory.$filename] = file_get_contents($directory.$this->directory.$filename);
return $directory.$this->directory.$filename;
}

/*Si le fichier n'existe pas du tout*/
else
{
echo "Erreur Template::open - Vous n'avez pas indiqué un fichier éxistant
";
return FALSE;
}
}
}

/*Remplace les {QUELQUECHOSE} par la valeur*/
function assign_vars($template, $array)
{
if ( isset($this->contentfile[$template]) )
{
foreach ($array as $key => $value)
{
$this->contentfile[$template] = str_replace('{'.$key.'}', $value, $this->contentfile[$template]);
}
}

else
{
echo "Erreur Template::assign_vars - Vous n'avez pas indiqué le nom d'un template ouvert
";
}
}

/*Remplace les blocs de code*/
function assign_block_vars($template, $block, $array)
{
if ( isset($this->contentfile[$template]) )
{
if ( preg_match('#\<!--BLOCK_'.$block.'--\>(.+)\<!--/BLOCK_'.$block.'--\>#sU', $this->contentfile[$template], $matches) )
{
$this->allcontentblock[$block] = $matches[0];
$contentblock = $matches[1];

foreach ($array as $key => $value)
{
$contentblock = str_replace('{'.$block.'.'.$key.'}', $value, $contentblock);
}
$this->contentfile[$template] = preg_replace('#\<!--BLOCK_'.$block.'--\>(.+)\<!--/BLOCK_'.$block.'--\>#sU',
$contentblock.$this->allcontentblock[$block], $this->contentfile[$template]);
}
}

else
{
echo "Erreur Template:assign_block_vars - Vous n'avez pas indiqué le nom d'un template ouvert
";
}
}

/*Affiche le template*/
function display($filename, $debug = FALSE)
{
if ( $debug === FALSE )
{
$this->removedebug($filename);
}

else if ($debug !== TRUE)
{
echo "Erreur Template::display - Vous n'avez pas indiqué un booléen comme second paramètre
";
}

echo $this->contentfile[$filename];
}

/*Supprime les variables et blocs non utilisés*/
private function removedebug($filename)
{
$this->contentfile[$filename] = preg_replace('#\<!--BLOCK_(.+)--\>(.+)\<!--/BLOCK_(.+)--\>#sU',
'', $this->contentfile[$filename]);

$this->contentfile[$filename] = preg_replace('#\{(.+)\}#sU', '', $this->contentfile[$filename]);
}
}

?>


Je ne comprend pas pourquoi il me laisse cette balise de fin, j'ai tout tenter mais sans résultat.


Merci d'avance pour votre aide.

25 réponses

cs_christophedlr Messages postés 267 Date d'inscription samedi 3 janvier 2004 Statut Membre Dernière intervention 23 août 2023 5
21 févr. 2011 à 16:34
Le champ est créer bon sang, c'est le champ block dans ChrisSoftware_menu. Si je te fais chier dit le bon sang au lieu de faire sembler de m'aider.
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
22 févr. 2011 à 14:16
Si je te fais chier dit le bon sang au lieu de faire sembler de m'aider.
Avec cette réflexion, ouais, tu commence à me gaver !

Pourquoi ne pas utiliser le champs ID ??
Il ne faut pas utiliser le champs ID comme référence conditionnel, dans ce cas précis, puisque tel est son type ce n'est pas une valeur fixe : c'est une suite arithmétique de 1 qui s'incrémente tout seul ! Donc ça joue aussi, elle ne fait pas référence à un bloc.

<?php
class Template
{
private $contentfile; //Contenu des fichiers ouverts
private $parsecode =  array();
private $filename;


public function __construct($contentfile, $file)
{
$this->filename = $file;
$this->contentfile=$contentfile;
}

function assign_block_vars($blockName, $vars)
{	
if(empty($vars))
return false;

$tempStock = '';
if(preg_match('#\<!--BLOCK_'.$blockName.'--\>(.+)\<!--/BLOCK_'.$blockName.'--\>#sU', $this->contentfile, $matches) )
foreach($vars as $key => $value) {
if(empty($tempStock))
$tempStock .= preg_replace('/\{'.$blockName.'.'.$key.'\}/', $value, $matches[1]);
else
$tempStock = preg_replace('/\{'.$blockName.'.'.$key.'\}/', $value, $tempStock);
}

$tempStock = preg_replace('#\<!--BLOCK_(.+)--\>(.+)\<!--/BLOCK_(.+)--\>#sU', '', $tempStock);

return $this->parsecode[$this->filename][] = $tempStock;
}

/*Affiche le template*/
function display($fileName)
{
echo implode('',$this->parsecode[$fileName]);
}

}

$contenu_recuperer = '
<!--BLOCK_A-->
<tr>
<td> {A.title} </td>
</tr>
<!--BLOCK_B-->
<tr>
<td>[{B.url} {B.art}][ID : {B.ID}]</td>
</tr>	
<!--/BLOCK_B-->	
<!--/BLOCK_A-->	';


$tpl  = new Template($contenu_recuperer, 'index.tpl');


$connexion= mysql_connect('', '', '');// A REMPLIRRRRRRRRRRRRR
mysql_select_db('');// A REMPLIRRRRRRRRRRRRR

$sql1 = mysql_query('SELECT * FROM chrissoftware_block');
while($block = mysql_fetch_array($sql1)) {
    $tpl->assign_block_vars('A', array('title' => strval($block['name']) ));

$sql2 = mysql_query('SELECT * FROM chrissoftware_menu WHERE block='.$block['module'].'');
    while($menu= mysql_fetch_array($sql2))
$tpl->assign_block_vars('B', array('art' => strval($menu['name']), 'url' => strval($menu['url']), 'ID' => strval($menu['id'])));
}

echo '';
$tpl->display('index.tpl');
echo '
';

?>



BDD :

[Table block]
INSERT INTO `chrissoftware_block` (`id`, `name`, `description`, `module`) VALUES
(1, 'Menu acceuil ', 'test 1', 1),
(2, 'Menu codes ', 'test 2', 2);

[Table menu]
INSERT INTO `chrissoftware_menu` (`id`, `block`, `name`, `url`) VALUES
(1, 1, 'Lien Mon compte ', 'lien compte'),
(2, 1, ' Lien Mes sources', 'lien source'),
(3, 2, 'Lien Tous les codes', 'lien code'),
(4, 2, 'Lien Ajouter un code', 'lien ajout code');



Voilà maintenant tu peux voir par toi-même si ce n'est pas ce que tu veux...croute alors !!

______________________________________________________________________
0
cs_christophedlr Messages postés 267 Date d'inscription samedi 3 janvier 2004 Statut Membre Dernière intervention 23 août 2023 5
22 févr. 2011 à 14:30
Bon ben je vois que tu en as rien à foutre de mon blem, donc ben tan pis je finirais pas mon site avant x mois le temps de trouver tout seul. Tu me parles de ce putain de champ module qui n'est pas ce que je veux. Le champ ID tu crois qu'il sert à quoi ? C'est justement ce genre de champ qui est utilisé donc arrête ton petit baratin de faux intello c'est pénible. Je viens avec un problème et toi au lieu de chercher à m'aider, tu me sors qu'il faut utiliser le champ module et que c'est donc la requête qui as un problème.

Donc ben tan pis, quand j'aurais enfin trouver je te mettrait le nez dans le caca et tu verras bien que tu as tord à 100%.
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
22 févr. 2011 à 14:51
Si je voulais pas t'aider je ne l'aurais pas fait OK !
As-tu au moins tester ce que je de t'ai donner ??? PAS si sûre !!

Concernant ton champs ID je n'ai pas dit qu'il n'a pas lieu d'exister, je suis entrain de dire que tu ne dois l'utiliser comme référence dans ton cas, puisque c'est un champs autoincrémente.
Si tu n'est pas capable de le comprendre ça, ben tanpis !
Celui qui vient quémander, sur un ton plus que limite c'est pas MOI !
Et je pense pas que tu domine le sujet mieux que moi.

Sur ce BONNE CHANCE !

______________________________________________________________________
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_christophedlr Messages postés 267 Date d'inscription samedi 3 janvier 2004 Statut Membre Dernière intervention 23 août 2023 5
22 févr. 2011 à 15:59
Tu viens me dire fait ci, fait ça alors que tes solutions n'en sont pas. Je le répète encore et encore, si les blocs ne sont pas imbriqués aucun problème. Donc déjà cela prouve que mes requêtes sont parfaitement fonctionnelle tout comme le code du traitement. Par contre cela montre un problème sur le moteur de template, donc pourquoi tester un truc que tu me dis alors que je sais d'où viens le problème, ce que je ne sais pas c'est comment le corriger.


D'ailleurs, en y réfléchissant plus, je pense à déterminé avec précision le problème, à savoir que pour pouvoir continuer à traiter un bloc, il faut une fois traité la première fois, le réécrire dessous. Je pense que le soucis viens de là, à savoir que quand la boucle fait repassé sue le traitement du second bloc une fois que le premier fût traité encore une fois, il y a toujours de l'autre bloc, le bloc imbriqué, donc ça le remplace en même temps.

Ce que je ne sais pas, c'est comment déterminer si il y a encore besoin de bouclé, à cela je vois une solution que je testerais dès mon retour sous Linux : Créer une fonction qui supprimera dans un bloc déterminé, tout les blocs présents dedans. Ainsi, au moment de la sortie du while traitant le second bloc, j'appel cette fonction qui va alors supprimer ce bloc rajouté, puis on peut traiter correctement le bloc parent.

Je suis sur qu'il doit y avoir une meilleur façon de faire que ça, mais si ça marche ce sera déjà ça de pris histoire de pouvoir enfin continuer.



Enfin bref, ce que je vois c'est que je t'ai expliqué où se situe le problème, et toi tu me sors que c'est à un autre endroit alors que tout mes tests révèlent bien là où j'ai indiqué.
0
Rejoignez-nous