Началось все с того что мне не нравятся существующие темплейтеры типа smarty. Не прет.
Написал свой, простенький, но для повседневности хватает.
вот такой вот класс:
- <?php
- class Template {
- private $template;
- private $vars;
- private $blocks;
- private $res;
- private $registry;
- function __construct($registry) {
- $this->registry = $registry;
- }
- private function getvars($block="")
- {
- $str="";
- if ($block=="")
- {
- $str=$this->res;
- }
- else
- {
- if (isset($this->blocks[$block]))
- {
- $str=$this->blocks[$block];
- }
- }
- $m=array();
- preg_match_all("/{%(.*)?%}/ismU",$str,$m,PREG_SET_ORDER);
- return $this->assoc($m);
- }
- private function assoc($arr)
- {
- $r=array();
- if (count($arr)>0)
- {
- foreach ($arr as $v)
- {
- $r[$v[1]]=$v[0];
- }
- }
- return $r;
- }
- private function getblocks()
- {
- $m=array();
- preg_match_all("/<!--(.*)?-->.*?<!--\/\\1-->/ismU", $this->template, $m ,PREG_SET_ORDER);
- $this->blocks=$this->assoc($m);
- }
- private function getinclude($data)
- {
- $m=array();
- preg_match_all("/<!--include:(.*)?-->/ismU", $this->template, $m ,PREG_SET_ORDER);
- foreach ($m as $i)
- {
- $t=new template($this->registry);
- $this->res=str_replace($i[0],$t->compile($data,site_path.$i[1]),$this->res);
- unset($t);
- }
- }
- function getphp()
- {
- $m=array();
- preg_match_all("/{--(.*)?--}/ismU", $this->res, $m ,PREG_SET_ORDER);
- $out="";
- foreach ($m as $p)
- {
- ob_start();
- eval ("echo ".$p[1].";");
- $out = ob_get_clean();
- $this->res=str_replace($p[0],$out,$this->res);
- }
- }
- private function setvars($tpl,$vars,$d)
- {
- $str=$tpl;
- foreach ($vars as $var => $search)
- {
- if (isset($d[$var]))
- {
- $str=str_replace($search,$d[$var],$str);
- }
- else
- {
- $str=str_replace($search,"",$str);
- }
- }
- return $str;
- }
- private function compileblock($block,$data)
- {
- $tpl=$this->blocks[$block];
- $res="";
- $vars = $this->getvars($block);
- //print_r($vars);
- foreach($data as $d)
- {
- $res.=$this->setvars($tpl,$vars,$d)."\n\n";
- }
- $this->res=str_replace($tpl,$res,$this->res);
- }
- function compile($data,$tplfile)
- {
- $this->template=file_get_contents($tplfile);
- $this->res=$this->template;
- $this->getblocks();
- foreach ($this->blocks as $block => &$v)
- {
- if (isset($data[$block]))
- {
- $this->compileblock($block,$data[$block]);
- }
- else
- {
- $this->res=str_replace($this->blocks[$block],"",$this->res);
- }
- }
- $this->res=$this->setvars($this->res,$this->getvars(),$data);
- $this->getinclude($data);
- $this->getphp();
- return $this->res;
- }
- function html($data,$tplfile)
- {
- echo $this->compile($data,site_path.$tplfile);
- }
- }
- ?>
Чтобы было проще понять, вот пример шаблона:
- <!--include:tpl/header.tpl-->
- <table class="adminlist" style="width:300px;">
- <tr>
- <th class="title" width="3%"><input name="toggle" id="toggle" value="1" onclick="checkAll(1);" type="checkbox" /></th>
- <th class="title" width="97%"> </th>
- </tr>
- <!--users-->
- {--('1'=='{%flag%}') ? '<tr><td colspan="2">{%gname%}</td></tr>':'' --}
- <tr class="row0">
- <td><input type="checkbox" class="checkbox" name="check_{%id%}" /></td>
- <td><a href="/users/edit/{%id%}">{%name%}</a></td></tr>
- <!--/users-->
- {--('write'=='{%right%}') ? '<tr><td colspan="6" style="text-align:center;"><a href="/users/create">Добавить</a></td></tr>':''--}
- </table>
- <!--include:tpl/footer.tpl-->
Как использовать? примерно вот так:
- <?php
- $d=array();
- $d['users'][1]['id']=1;
- $d['users'][1]['name']='User 1';
- $d['users'][1]['game']='Group 1';
- $d['users'][1]['flag']=1;
- $d['users'][2]['id']=2;
- $d['users'][2]['name']='User 2';
- $d['users'][2]['game']='Group 1';
- $d['users'][2]['flag']=0;
- $d['users'][3]['id']=3;
- $d['users'][3]['name']='User 3';
- $d['users'][3]['game']='Group 2';
- $d['users'][3]['flag']=1;
- $d['right']='right';
- $template = new Template($registry);
- $template->html($d,'tpl/usersform.tpl');
- ?>
Поподробнее про теги шаблона:
{%name%} — переменная
<!—include:file.tpl—> — включение внешнего шаблона (количество включений ограничено только оперативной памятью 🙂
повторяющиеся блоки оформляются так
<!—blockname—>
{%name%}
<!—/blockname—>
где blockname — это массив значений в передаваемом параметре
условия задаются вот так:
{—(‘1’=='{%flag%}’) ? ‘{%var1%}’:'{%var2%}’ —}
ссылочка на файлик класса: template.phps
$registry можно убрать, в этой версии оно не используется. а так глобальная переменная в которой все 🙂
Ну да, Smarty монстр, но зачем велосипед-то изобретать? Все уже изобретено до нас. Например, TemplatePower. Быстрый, простой и ничего лишнего.
Иногда изобрести велосипед во-первых интереснее, во-вторых полезнее, а в-третьих оптимальнее 😉
Большое спасибо автору за интересную статью 😉
Спасибо, полезная инфа!