Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Klasa tpl, i parsowanie {SECTION} od smarty'iego
radziel
post 20.01.2004, 13:31:33
Post #1





Grupa: Zarejestrowani
Postów: 103
Pomógł: 0
Dołączył: 25.04.2003
Skąd: Olsztyn

Ostrzeżenie: (0%)
-----


Napisałem sobie na własny użytek taką oto klase do obsługi szablonów (jako alternatywe dla Smarty, gdyż on baaaardzo opóźnia mój skrypt(tak bylo pod PHP4) i nie dziala pod PHP5 :/)

[php:1:7869633014]<?php
class template
{
var $parsed;
var $unparse;
var $blocks;

var $dir;

function __construct($dir)
{
$this->_setDir($dir);
}

function _setDir($dir)
{
if (is_dir($dir))
{
$this-> dir = $dir;
return true;
}
else
{
die("[TEMPLATE]Root dir no exists!");
}
}
function Assign($var, $value=null)
{
if(is_array($var))
{
reset($var);
foreach ($var as $name => $val)
{
$this -> blocks[$name] = $val;
}
}
else
{
$this -> blocks[$var] = $value;
}
}

function Display($file)
{
$this -> unparse = @file($dir . $file . '.tpl');
echo $this -> _parse();
}

function _parse()
{
$this -> parse = '';
for ($i=0; $i<= count($this->unparse); $i++)
{
$line = $this -> unparse[$i];
$found = array();

if(preg_match_all("#{(.+?)}#is", $line, $found))
{
foreach ($found[1] as $block)
{
$block_names[]='{'.$block.'}';
$block_values[] = $this -> blocks[$block];
}
$line = str_replace($block_names, $block_values, $line);
}

$this -> parsed .= $line;
}
unset($this->unparse);
return $this -> parsed;
}
function _parseSectionTag()
{
// e? co tu napisac?
}


}
?>[/php:1:7869633014]

Jak już pewnie niektórzy zauważyli jest to modyfikacja kodu ze strony Webcity.pl Dodalem pare rzeczy, usunełem niepotrzebne ale...
Mam problem ze znacznikiem {SECTION}{SECTION} uzywam go bardzo czesto więc musze napisać odpowiedni parser dla niego...

Kompletnie nie wiem jak za to się zabrać... Przykladowy tpl:
Kod
<table border="1">

  {section name=config_value loop=$data}

    <tr>

      <td>{$data[config_value].name}</td>

      <td>{$data[config_value].value}</td>

    </tr>

  {/section}

</table>


Składnia jest taka sama jak u smartiego...
Przeglądałem kod SMARTY'iego, ale nie mogę wyciągnąć funcji za to odpowiedzialnej... strasznie zakręcone to wszystko :/

Ma ktoś pomysł jak to rozwiązać? Niech rzuci kodem, albo niech da jakas wskazówke tongue.gif


--------------------
r.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 10)
Bora
post 20.01.2004, 14:32:48
Post #2





Grupa: Zarejestrowani
Postów: 270
Pomógł: 0
Dołączył: 15.06.2003

Ostrzeżenie: (0%)
-----


kiedyś napisałem coś takiego:

[php:1:7d21b2379c]<?php
class template
{
var $file;
var $inc = array("default" => "");
var $blocks = array("default" => "");
var $moduls = array("default" => "");
function load($file){
$file = "pages/".$_SESSION['page']."/templates/".$file.".tpl";
if(file_exists($file)){
$plik = fopen($file, 'r');
$unparsed = fread($plik, filesize($file));
fclose($plik);
}else{
die("brak pliku $file");
}
// wylapuje moduły
preg_match_all( "#[INCLUDE:(.+?)]#is", $unparsed, $include);
$unparsed = preg_replace("#[INCLUDE:(.+?)]#is","{INCLUDE:$1}", $unparsed);
$unparsed = str_replace("n", "|ent|", $unparsed);
preg_match_all( '/[MODUL.*](.+)[/MODUL.*]/Uise', $unparsed, $znalezione);
// zamienia moduły na ich odpowiedniki
$unparsed =
preg_replace('/[MODUL:(.*?)](.*?)[/MODUL:(.*?)]/i','{MODUL:$1}',
$unparsed);
$unparsed = str_replace("|ent|", "n", $unparsed);
$znalezione[0] = str_replace("|ent|", "n", $znalezione[0]);
$znalezione[1] = str_replace("|ent|", "n", $znalezione[1]);
$mod = array();
foreach ($znalezione[0] as $i_parser){
preg_match("/[MODUL:(.*?)]/i",$i_parser, $znal);
$pref = $znal[1];
$m = preg_replace('/[MODUL:(.*?)]/i','', $i_parser);
$m = preg_replace('/[/MODUL:(.*?)]/i','', $m);
$mod["$pref"]=$m;
}
// wyłapuje include i wstawia pliki
foreach ($include[0] as $i_parser){
preg_match("/[INCLUDE:(.*?)]/i",$i_parser, $znal);
$in = preg_replace("#[INCLUDE:(.+?)]#is","$1", $i_parser);
$pref = $znal[1];
$prefix = $znal[1];
$pref = "templates/".$pref.".tpl";
if(file_exists($pref)){
$plik = fopen($pref, 'r');
$files = fread($plik, filesize($pref));
$unparsed = str_replace('{INCLUDE:'.$prefix.'}',$files, $unparsed);
fclose($plik);
}else{
die("brak pliku $pref");
}
}
$this -> moduls = $znalezione[1];
$this -> mods = $mod;
$this -> unparsed = $unparsed;
return true;
}
function parse($unparsed,$blocks = array()){
if(preg_match_all('#{(.+?)}#is', $unparsed, $found)){
$parsed = $unparsed;
foreach($found[1] as $block){
// var_dump($block);
// var_dump($blocks);
$parsed = str_replace('{'.$block.'}', $blocks[$block], $parsed);
}
}
return $parsed;
}
}
class modul
{
var $file;
var $mod;
var $blocks = array("default" => "");
var $moduls = array("default" => "");
function parse($unparsed,$blocks = array()){
if(preg_match_all('#{(.+?)}#is', $unparsed, $found)){
$parsed = $unparsed;
foreach($found[1] as $block){
$parsed = str_replace('{'.$block.'}', $blocks[$block], $parsed);
}
}
return $parsed;
}
}
?>[/php:1:7d21b2379c]

[xml:1:7d21b2379c]<!--- [MODUL:koment] dolna czesc-->
<tr>
<td class="forum1">
autor:{koment:autor} - {koment:kasuj} - data:{koment:data}
<br>
{koment:tresc}
<br>
{koment:ip} - {koment:host}
</td>
</tr>
<!--- [/MODUL:koment] dolna czesc-->[/xml:1:7d21b2379c]


może ci sie przyda

update to jest bardzo stary kod i juz nie pammiętam jak działał. ale patrząc w zródło stronki jest strasznie zawiłe.

* * * * * * * * * * * * * * * * * * *
Post nr: [100] smile.gif trza to oblać smile.gif
Go to the top of the page
+Quote Post
radziel
post 21.01.2004, 09:46:24
Post #3





Grupa: Zarejestrowani
Postów: 103
Pomógł: 0
Dołączył: 25.04.2003
Skąd: Olsztyn

Ostrzeżenie: (0%)
-----


Hm... ciekawe...

Ma może ktoś jeszcze jakieś pomysły?


--------------------
r.
Go to the top of the page
+Quote Post
Bora
post 21.01.2004, 11:29:02
Post #4





Grupa: Zarejestrowani
Postów: 270
Pomógł: 0
Dołączył: 15.06.2003

Ostrzeżenie: (0%)
-----


jesatem w trakcie pisana niedługo dam gotową klase
Go to the top of the page
+Quote Post
gulldarek
post 21.01.2004, 11:45:43
Post #5





Grupa: Zarejestrowani
Postów: 156
Pomógł: 15
Dołączył: 13.09.2003
Skąd: London

Ostrzeżenie: (0%)
-----


Bora: nie wiem czy widziałeś kod z vbulletina któy wkleiłem do mojego wątku o szablonach. Może się przydać smile.gif

Ps. Daj znać jak ją skończysz winksmiley.jpg
Go to the top of the page
+Quote Post
Bora
post 21.01.2004, 13:10:04
Post #6





Grupa: Zarejestrowani
Postów: 270
Pomógł: 0
Dołączył: 15.06.2003

Ostrzeżenie: (0%)
-----


Napiałem radzi sobie narazie tylko z 1 subsekcją , próbowałem z zagnieżdżonymi ale narazie nie wychodzi.

[php:1:94a80b8b43]<?php
class template
{
var $parsed;
var $unparse;
var $blocks;
var $lines;

var $dir;

//function __construct($dir)
function template($dir)
{
$this->_setDir($dir);
}

function _setDir($dir)
{
if (is_dir($dir))
{
$this-> dir = $dir;
return true;
}
else
{
die("[TEMPLATE]Root dir no exists!");
}
}
function Assign($var, $value=null)
{
if (strstr($var, '.') )
{
$var = explode('.',$var);
for ($i=0;$i<count($value);++$i)
{
$this -> blocks[$var['0']][$i][$var['1']] = $value;
}
}else{
$this -> blocks[$var] = $value;
}
}

function Display($file)
{
$this -> unparse = file($dir . $file . '.tpl');
$fh = fopen($dir . $file . '.tpl', "r");
$this -> unparse = chop(fread($fh, filesize($dir . $file . '.tpl')));
$i=0;
while ( ereg( '{section name', $this->unparse) )
{
$this -> _parseTab();
++$i;
if ($i>6){exit('za dluga petla');}
}
$this -> unparse = $this->_parse($this -> unparse);
echo $this -> unparse ;
}

function _parseTab()
{
$line = $this -> unparse;
preg_match( '/{section name=(.+?)}(.*){/section}/is', $line, $found);
$line = preg_replace( '/{section name=(.*)}(.+){/section}/is',
$this->_parse_intab($found['2'],$this->blocks[$found['1']]['0'],$found['1'])
,$line);
$line = str_replace('{tmp}', '', $line);
$this->unparse = $line;
return false;
}


function _parse($line)
{
$found = array();

if(preg_match_all("#{(.+?)}#is", $line, $found))
{
foreach ($found['1'] as $block)
{
$block = str_replace('$', '', $block);
$block_names='{$'.$block.'}';
$block_values = $this -> blocks[$block];
$line = str_replace($block_names, $block_values, $line);
}
$line = str_replace($block_names, $block_values, $line);
}
return $line;
}

function _parse_intab($line,$val,$mod)
{

$found = array();
$count_var = count($val);
if(preg_match_all("#{[$]{$mod}[.](.+?)}#is", $line, $found))
{
foreach ($found['1'] as $block)
{
$block_mod = $block['0'];
$block_names='{$'.$mod.".".$block.'}';
$block_values = $this->blocks[$mod]['0'][$block]['0'];
if (!empty($lines))
{
$lines=explode('{tmp}',$lines);
for ($i=0;$i<$count_var;++$i)
{
$lines[$i] = str_replace($block_names, $block_values[$i], $lines[$i]);
}
$lines=implode('{tmp}',$lines);
}else{
for ($i=0;$i<$count_var;++$i)
{
$lines[$i] = str_replace($block_names,
$block_values[$i], $line);

}
$lines=implode('{tmp}',$lines);
}
}
}
return $lines;
}
}
?>[/php:1:94a80b8b43]


Kod
test Parsera - {$tpl}-

<table border="1">

  {section name=config_value}

    <tr>

      <td>[{$config_value.name}]</td>

      <td>[{$config_value.value}]</td>

    </tr>

  {/section}



</table>


[php:1:94a80b8b43]<?php
include('tpl_class.php');
$tpl= new template('.');
$tpl->Assign("config_value.id",array('aaa1i','bbbb2i','cccc3i'));
$tpl->Assign("config_value.name",array(array('aaa1n','bbbb2n','cccc3n')));
$tpl->Assign("config_value.value",array(array('aaa1v','bbbb2v','cccc3v')));
$tpl->Assign("config_test.name",array(array('configa1v','configb2v','configc3v')));
$tpl->Assign('tpl','templates');
$tpl = $tpl->Display('tpl');
?>[/php:1:94a80b8b43]

UPDATE

wersja poprawiona
Go to the top of the page
+Quote Post
gulldarek
post 21.01.2004, 13:23:40
Post #7





Grupa: Zarejestrowani
Postów: 156
Pomógł: 15
Dołączył: 13.09.2003
Skąd: London

Ostrzeżenie: (0%)
-----


Bora: teraz przydalaby sie eszcze funkcja do parsowania <if>'ow...
Go to the top of the page
+Quote Post
radziel
post 21.01.2004, 13:39:43
Post #8





Grupa: Zarejestrowani
Postów: 103
Pomógł: 0
Dołączył: 25.04.2003
Skąd: Olsztyn

Ostrzeżenie: (0%)
-----


Bora: nieco musisz zmodyfikowac te parsowanie sectionów
Kod
<table border="1">

  {section name=config_value loop=$data}

    <tr>

      <td>{$data[config_value].name}</td>

      <td>{$data[config_value].value}</td>

    </tr>

  {/section}

</table>


powininieneś w assign podawać tylko assign($data), parser sam powinien podstawic (jezeli to tablica) odpowiednie wartości za $data[config_value].name i $data[config_value].value...

Te dane w tych kwadratowych nawiasach to info ze ta zmienna nalezy do sekcji config_value.

Przydałoby się jeszcze aby parsował loop i tyle razy powtarzał ten kod ile ma $data tych "indexów" w sobie.. to by oszczedziło nieco czasu przy zmianie klas ze smarty na tą...

Sorry ze tak pisze jak dla lamera, ale chce zeby tez poczatkujacy to zrozumieli smile.gif

Czekam az beda dzialac zagnieżdzone sectiony winksmiley.jpg Dobrze sie zapowiada smile.gif


--------------------
r.
Go to the top of the page
+Quote Post
Bora
post 21.01.2004, 13:48:01
Post #9





Grupa: Zarejestrowani
Postów: 270
Pomógł: 0
Dołączył: 15.06.2003

Ostrzeżenie: (0%)
-----


teraz męcze sie z wyrażniem regularnym , które mnie przerasta

mam coś takiego:
Kod
{section name=config_value}

    <tr>

      <td>[{$config_value.name}]</td>

      <td>[{$config_value.value}]</td>

    </tr>

    {section name=config_test}[[{$config_test.name}]]{/section}

  {/section}

licze ilosc otwartych subsekcji
[php:1:17fb8f4b41]<?php
substr_count($found['0'], '{section name');
?>[/php:1:17fb8f4b41]
i teraz zaczyna sei jazda , chce wyciągnąć z tego stringa który kończyłby sie po zamknięciu ostatniej otwartej subsekcji czyli w tym przypadku po 2gim
Kod
{/section}


UPDATE
powyższy kod poprawiony[/code]
Go to the top of the page
+Quote Post
Bora
post 21.01.2004, 15:48:24
Post #10





Grupa: Zarejestrowani
Postów: 270
Pomógł: 0
Dołączył: 15.06.2003

Ostrzeżenie: (0%)
-----


Tak jak chciałęś radziel Assign jak w smarty co do sposobu czytania z tpl zostawiam to na pozniej jak juz bede miał gotowe wyrażenie.


[php:1:a29cc6a01f]<?php
include('tpl_class.php');
$tpl= new template('.');
$tpl->Assign("config_test",array(array('configa1v','configb2v','configc3v')));
$tpl->Assign("config_value",array('name'=>array('aaa1n','bbbb2n','cccc3n'),'value'=>array('aaa1v','bbbb2v','cccc3v')));
$tpl->Assign('tpl','templates');
$tpl = $tpl->Display('tpl');
?>[/php:1:a29cc6a01f]

Kod
test Parsera - {$tpl}-

<table border="1">

  {section name=config_value}

    <tr>

      <td>[{$config_value.name}]</td>

      <td>[{$config_value.value}]</td>

    </tr>



  {/section}

</table>



[php:1:a29cc6a01f]<?php
class template
{
var $parsed;
var $unparse;
var $blocks;

var $dir;

//function __construct($dir)
function template($dir)
{
$this->_setDir($dir);
}

function _setDir($dir)
{
if (is_dir($dir))
{
$this-> dir = $dir;
return true;
}
else
{
die("[TEMPLATE]Root dir no exists!");
}
}
function Assign($var, $value=null)
{
if (is_array($value))
{
$wymiar=count($value);
if ($wymiar==1)
{
foreach ($value as $val)
{
$this -> blocks[$var] = $val;
}
}else{
$klucze = array_keys($value);
foreach ($klucze as $klucz)
{
foreach ($value[$klucz] as $val)
{
$this -> blocks[$var][$klucz][] = $val;
}
}
}
}else{
$this -> blocks[$var] = $value;
}
}

function Display($file)
{
$this -> unparse = file($dir . $file . '.tpl');
$fh = fopen($dir . $file . '.tpl', "r");
$this -> unparse = chop(fread($fh, filesize($dir . $file . '.tpl')));
$i=0;
while ( ereg( '{section name', $this->unparse) )
{
$this -> _parseTab();
++$i;
if ($i>6){exit('za dluga petla');}
}
$this -> unparse = $this->_parse($this -> unparse);
echo $this -> unparse ;
}

function _parseTab()
{
$line = $this -> unparse;
preg_match( '/{section name=(.+?)}(.*){/section}/is', $line, $found);
$line = preg_replace( '/{section name=(.*)}(.+){/section}/is', $this->_parse_intab($found['2'],$this->blocks[$found['1']]['0'],$found['1']),$line);
$line = str_replace('{tmp}', '', $line);
$this->unparse = $line;
return false;
}


function _parse($line)
{
$found = array();

if(preg_match_all("#{(.+?)}#is", $line, $found))
{
foreach ($found['1'] as $block)
{
$block = str_replace('$', '', $block);
$block_names='{$'.$block.'}';
$block_values = $this -> blocks[$block];
$line = str_replace($block_names, $block_values, $line);
}
$line = str_replace($block_names, $block_values, $line);
}
return $line;
}

function _parse_intab($line,$val,$mod)
{

$found = array();

if(preg_match_all("#{[$]{$mod}[.](.+?)}#is", $line, $found))
{
foreach ($found['1'] as $block)
{
$block_names='{$'.$mod.".".$block.'}';
$block_values = $this->blocks[$mod][$block];
$count_var = count($this->blocks[$mod][$block]);
if (!empty($lines))
{
$lines=explode('{tmp}',$lines);
for ($i=0;$i<$count_var;++$i)
{
$lines[$i] = str_replace($block_names, $block_values[$i], $lines[$i]);
}
$lines=implode('{tmp}',$lines);
}else{
for ($i=0;$i<$count_var;++$i)
{
$lines[$i] = str_replace($block_names, $block_values[$i], $line);

}
$lines=implode('{tmp}',$lines);
}
}
}
return $lines;
}
}

?>[/php:1:a29cc6a01f]
Go to the top of the page
+Quote Post
radziel
post 27.01.2004, 18:47:23
Post #11





Grupa: Zarejestrowani
Postów: 103
Pomógł: 0
Dołączył: 25.04.2003
Skąd: Olsztyn

Ostrzeżenie: (0%)
-----


Jako że temat dotyczy powyższego, postanowiłem napisać w tymże temacie winksmiley.jpg

Problem:
Powiedzmy dostaję zmienną o wartości "{$data[testowa].name}" a chce przekształcić ten string na "$data['name']" wie ktoś jak to zrobic? Nie mogę wyrazenia ułożyć - to moja słaba strona sad.gif


--------------------
r.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 01:47