хотя мне больше нравиться так: PHP: <? // (c) cms-lite =) define("__s1__","{"); define("__s2__","}"); class view{ protected $tpl = ""; protected $from = array(); protected $to = array(); public function __construct($t){ $this->tpl = file_get_contents($t); } public function __set($k,$v){ $this->from[$k] = __s1__.$k.__s2__; $this->to[$k] = $v; } public function __get($k){ if(isset($this->to[$k]))return $this->to[$k]; return ""; } public function __toString(){ return str_replace($this->from,$this->to,$this->tpl); } } ?>
Для рендеринга пассивных шаблонов этого почти достаточно (не хватает некоторых проверок, кэширования и динамических блоков). Что же касается активных шаблонов?... А нужно ли логику представления возлагать на шаблоны?
PHP: <?php echo get('pager')?> <table> <tr> <th>Col1</th> <th>Col2</th> <th>Col3</th> <th>Col4</th> <th>Col5</th> </tr> <?php if (is_set('data')):?> <?php foreach (get('data') as $v):?> <tr> <td><?php echo $v['col1']?></td> <td><?php echo $v['col2']?></td> <td><?php echo $v['col3']?></td> <td><?php echo $v['col4']?></td> <td><?php echo $v['col5']?></td> </tr> <?php endforeach;?> <?php else:?> <tr> <td colspan="5" class="hint">No data found</td> </tr> <?php endif;?> </table> <?php echo get('pager')?> Куда уж там без логики...
я б делал так PHP: <?php foreach ($pages as $link => $n) { $pnum = new view('./..../pginator_col.tpl'); $pnum -> link = $link; $pnum -> num = $n; $view -> pages .= $pnum; } и кэшируем! ;D
Табличные у меня данные, и "Срааать! Срать я хотел на дивы!". Там где контент дивами, там дивы. Где таблицы - там таблицы. Так что, ИМХО, замечание не уместно.
У меня в итоге получилось так: PHP: <?php class Template{ /** * Буфер переменных. * @var array */ protected $vars=array(); /** * Путь к шаблону. * @var string; */ protected $path=null; /** * Нужно ли кэшировать шаблон. * @var boolean */ protected $needCache=null; /** * Дирректория с кэшем шаблона. * @var string */ protected $cacheDir=null; /** * Конструктор * * @param String $path Путь к файлу шаблона */ public function __construct($path, $cache=null, $dir=null){ global $vf; $this->path=$path; $this->needCache= $cache==null ? $vf["tpl"]["needCache"] : $cache; $this->cacheDir= $dir==null ? $vf["dir"]["cacheDir"] : $dir; } /** * Магическая запись переменной в буфер. * * @param string $var Имя переменной * @param mixed $val Значение переменной */ public function __set($var, $val){ $this->vars[$var]=$val; } /** * Мангическое получение значения переменной. * * @param string $var Имя переменной * @return mixed Значение переменной */ public function __get($var){ if (isset($this->$var)){ return $this->$var; } return $this->vars[$var]; } /** * Вытаскивает из массива значения для переменых шаблона. * * В случае асоциативного массива присваивает переменной шаблона с именем ключа массива соответсвующее значение массива. * Если массив нумерованный (или имена начинаются с цифр), то создаются переменные типа vN, где N ключ массива. * * @param array $arr Массив со значениями. */ public function arraySet($arr){ foreach($arr as $key=>$val){ if ($key+0==0){ $this->$key=$val; } else{ $var="v".$key; $this->$var=$val; } } } /** * Высчитывает хэш шаблона. * * @return string Хэш шаблона. */ public function hashCode(){ $hash = 0; $this->ksortVars(); $hash = md5(serialize($this)); return $hash; } /** * Сортирует массивы переменных шаблона и подшаблонов по ключам. */ public function ksortVars(){ deepKsort($this->vars); foreach($this->vars as $var){ if ($var instanceof Template){ $var->ksortVars(); } } } /** * Возвращает имя файла с кэшем. * * @return string Имя файла с кэшем. */ protected function getCacheFileName(){ if(!file_exists($this->cacheDir)){ mkdir($this->cacheDir); } return $this->cacheDir."/".basename($this->path, ".tpl")."_".$this->hashCode(); } /** * Преобразование шаблона в строку. * * @return string Результат выполнения шаблона */ public function __toString(){ if ($this->needCache){ $cacheFileName=$this->getCacheFileName(); if (file_exists($cacheFileName)){ return file_get_contents($cacheFileName); } else{ $rez=$this->compile(); file_put_contents($cacheFileName, $rez); return $rez; } } else{ return $this->compile(); } } /** * Выполнение шаблона * * @return string Результат выполнения шаблона */ public function compile(){ extract($this->vars); ob_start(); include($this->path); return ob_get_clean(); } }
Жесть, ну почему у одних получается нормально? У других помойная куча? При почти одинаковых подходах... Volt(220), объясни? Почему у тебя не получилась помойная куча? P.S. отдать кеширование и подсчет хешей на откуп самим подшаблонам не?
1) Стартовали от разных реализаций. 2) Делал изменения по ходу развития темы. 1) При первом прогоне подшаблоны закешируются. 2) Если собирать конечную страницу из кешей подшаблонов, то получатся дополнительные операции чтения с диска, которых можно избежать. 3) Если подсчет хешей отдать подшаблонам, то надо организовывать цикл по поиску подшаблонов и возникает вопрос куда девать эти хеши.
никуда, ты берешь хеш хешей. Т.е. вместо вытаскивания переменных, ты просто спрашиваешь у подшаблона его хеш. Зачем? Есть два варианта: - тупо спрашивать "дай контент" и класть его в свой кеш не беспокоясь о том, что есть кеши подшаблонов. - говорить дай хеш, а потом уже решать нужен ли нам контент. Я бы выбрал первый вариант. То что подшаблон чего-то там кеширует - меня не должно волновать. В крайнем случае можешь принудительно подшаблонам выставлять no_cache
Я так сначала и делал. Что тогда делать с остальными переменными, в том числе с массивами? Примерно так и происходит. Шаблон смотрит: "А не закеширован ли я? Закеширован? Тогда на тебе кеш. Не закеширован? Тогда сейчас выполнюсь." И во время выполнения уже запрашивается контент подшаблона, который решает то ли свой кеш отдать, то ли выпониться.
я походу не в теме. но.. PHP: public function __construct($path, $cache=null, $dir=null){ global $vf;
Мне он нужен для законченности идеи. Чтобы когда понадобиться 1) Мозг уже имел некоторую информацию по теме. 2) можно было взять готовое. Что именно смущает? global $vf;? Это массив настроек. Я пока не нашел более удобного способа для хранения настроек.
PHP: global $vf; это передача массива настроек в конструктор. есть много более удобных способов хранения и передачи настроек чем массив в глобальной области. не очень хороший подход. идея типа хочу кеширование не идея. попробую дать тебе идею. хочу кеширование чтоб выйграть на компиляции статики в шаблонах. хотя, для натив пхп, это тоже бредовая идея =)
[vs] Логично. =)) PHP: <?php function deepKsort(&$arr){ ksort($arr); foreach($arr as $key=>$val){ if (is_array($val)){ deepKsort($arr[$key]); } } }
Константы, ini файлы, подключение файла настроек в самом в конструкторе. Пока больше ничего не вспоминается. Если есть желание обсудить этот вопрос, то я создам отдельную тему. не-не... Идея типа хочу знать как можно сделать кеширование.