Forum Webscript.Ru

Программирование => PHP => Тема начата: D1g174LM4n14c от 18 Апреля 2003, 17:50:53

Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 18 Апреля 2003, 17:50:53
Тема шаблонов в PHP поднимается часто...
Каждый раз кто-то предлагает свои классы, половина из которых сразу обливаются грязью и забываются.
Все же я не посмотрел на это. Зря наверно :)

Читал тут про FastTemplate и решил написать свой класс, похожий на FT. Зацените пожалуйста: что нравиться, что не нравиться, что нужно поменять...

Скажу честно, весь нижеприведенный код я писал 10-15 минут максимум... Не реализовал динамические блоки как в ФастТемплейте, но это неважно... надо будет - сделаю...

В общем, вот сам код:

class Template
{
   var $path = \'templates\';
   
   var $tpls = array();
   var $vars = array();
   
   var $rl = \'{\'; // variable limiters
   var $ll = \'}\'; //
   
   var $ext = \'.tpl\';
   
   ////////////////////////////////////////////////////////////////////////////////
   
   function Template($path = 0)
   {
      $this->path = ($path === 0 ? $this->path : $path);
   }
   
   function define($tpl, $filename = 0)
   {
      if (is_array($tpl))
      {
         foreach ($tpl as $key => $val)
            $this->tpls[$key] = $val;
      }
      else $this->tpls[$tpl] = $filename;
   }
   
   function assign($var, $value = 0)
   {
      if (is_array($var))
      {
         foreach ($var as $key => $val)
            $this->vars[$key] = $val;
      }
      else $this->vars[$var] = $value;
   }
   
   function parse($var, $tpl)
   {
      $tpl = file_get_contents($this->path.\'/\'.$this->tpls[$tpl].$this->ext);
     
      foreach ($this->vars as $key => $val)
         $tpl = str_replace($this->rl.$key.$this->ll, $val, $tpl);
     
      $this->vars[$var] = $tpl;
   }
   
   function output($tpl)
   {
      echo $this->vars[$tpl];
   }
}
?>

гы. Какой-то он примитивный получился - но пашет как надо.
Название: class Template. Зацените.
Отправлено: Tronyx от 18 Апреля 2003, 18:51:38
Цитировать
D1g174LM4n14c:
что нравиться

Ничего
Цитировать
D1g174LM4n14c:
что не нравиться, что нужно поменять

Всё. Можешь только имена функций не менять.
Цитировать
D1g174LM4n14c:
Скажу честно, весь нижеприведенный код я писал 10-15 минут максимум...

Что ты хотел получить? Или ты хотел всем показать что ты умеешь писать галимые и практически не функциональные шаблонизаторы? Я своего "зверя" уже наверное пол года пишу (просто мало времени ему уделял и раза три координально менял алгоритм работы) и только недавно закончил ядро и оснастил его "небольшой" функциональностью, а твои 15 минут не просто не существенны, а совершенно ни чего не значат. Лучше возьми какой-нибудь готовый или напиши хороший, хотя хороший шаблонизатор это ОЧЕНЬ спорное понятие.
Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 18 Апреля 2003, 18:59:49
Но почему же?
То что я написал работает как надо. Относительно быстро.
Да и код получается довольно выразительный.

toplevel.tpl




{TL_TITLE}


{HEADER}

{LEFT}

{CONTENT}

{RIGHT}

{FOOTER}




script.php

require \'inc/class.template.php\';

$tpl = new Template;
$tpl->define(array(\'TOPLEVEL\' => \'toplevel\',
                   \'HEADER\' => \'header\',
                   \'LEFT\' => \'left\',
                   \'CONTENT\' => \'content\',
                   \'RIGHT\' => \'right\',
                   \'FOOTER\' => \'footer\'));

$tpl->assign(\'TL_TITLE\', \'Заголовок страницы\');

   $tpl->parse(\'MT_HEADER\', \'HEADER\');
   $tpl->parse(\'MT_LEFT\', \'LEFT\');
   $tpl->parse(\'MT_CONTENT\', \'CONTENT\');
   $tpl->parse(\'MT_RIGHT\', \'RIGHT\');
   $tpl->parse(\'MT_FOOTER\', \'FOOTER\');
$tpl->parse(\'TOPLEVEL\', \'TOPLEVEL\');

$tpl->output(\'TOPLEVEL\');
?>
Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 18 Апреля 2003, 19:05:17
Цитировать
Tronyx:
Или ты хотел всем показать что ты умеешь писать галимые и практически не функциональные шаблонизаторы?

конечно, согласен что это не совершенство... но я считаю, что если ты делаешь для себя какой-то класс, то нужно реализовать в нем ТОЛЬКО те функции, которыми ты пользуешься. Зачем писать больше? Это-же не стандартную библиотеку пишешь!
Название: class Template. Зацените.
Отправлено: Tronyx от 18 Апреля 2003, 20:24:37
Цитировать
D1g174LM4n14c:
нужно реализовать в нем ТОЛЬКО те функции, которыми ты пользуешься

Я тоже так считаю. Но ты просил оценить, я оценил.
Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 18 Апреля 2003, 20:31:57
нет. за оценку, конечно, спасибо!
только я не понимаю, что можно сюда еще добавить кроме функциональности? Или есть способы реально оптимизировать реализованные функции? В частности str_replace заменить на что-то более быстрое...
Название: class Template. Зацените.
Отправлено: Макс от 18 Апреля 2003, 20:47:48
Цитировать
Зацените.
малофункциональный (хотя признаю что быстрый)
Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 18 Апреля 2003, 20:51:27
функции - это так... главное чтобы работало хорошо и быстро. короче, как тебе надо! если надо что-то новое - добавить всегда можно. А так - просто и быстро :D
Название: class Template. Зацените.
Отправлено: Макс от 18 Апреля 2003, 21:04:10
если хочешь скорости, возьми http://php-templates.sourceforge.net/
Там функциональность в порядке.
Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 18 Апреля 2003, 22:07:59
посмотрю... ради интереса... спасибо.
Название: class Template. Зацените.
Отправлено: Tronyx от 18 Апреля 2003, 22:45:42
Цитировать
D1g174LM4n14c:
только я не понимаю, что можно сюда еще добавить кроме функциональности?

1. Разрешить php код в шаблоне.
2. Контроль ошибок ("блок не найден", "Неверный формат параметра" и т.п.), но это имеет смысл делать если у тебя функционал побольше.
3. Модульность(?)
4. Отказаться от assign (?) - сейчас меня Макс будет "ругать" за это ;)

Цитировать
D1g174LM4n14c:
В частности str_replace заменить на что-то более быстрое...

Компиляция в PHP код, тогда шаблон подключается обычным include`ом
Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 18 Апреля 2003, 23:07:11
Цитировать
Tronyx:
Контроль ошибок ("блок не найден", "Неверный формат параметра" и т.п.), но это имеет смысл делать если у тебя функционал побольше.
я же говорил, что это не библиотечный класс. Зачем делать обработку ошибок в своем же классе. Главное - внимательно писать код - тогда не нужно будет тратить время на обработку ошибок.

Цитировать
Tronyx:
Модульность(?)
а что ты имеешь ввиду под модкльностью в данном контексте?


Цитировать
Tronyx:
Компиляция в PHP код, тогда шаблон подключается обычным include`ом
ды, с таким же успехом можно обойтись вообще без шаблонизаторов. просто в нужных местах юзать include\\require операторы...
Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 18 Апреля 2003, 23:43:22
Цитировать
Tronyx:
Разрешить php код в шаблоне.

реально. вот как я это сделал:

вместо кода
$tpl = file_get_contents($this->path.\'/\'.$this->tpls[$tpl].$this->ext);я сделал так:
ob_start();
require $this->path.\'/\'.$this->tpls[$tpl].$this->ext;
$tpl = ob_get_contents();
ob_end_clean();

be simple! ;)
Название: class Template. Зацените.
Отправлено: Макс от 18 Апреля 2003, 23:45:37
Tronyx
Цитировать
4. Отказаться от assign (?) - сейчас меня Макс будет "ругать" за это
неее, ругать буду за :
Цитировать
1. Разрешить php код в шаблоне.
;) ИМХО это противоречит самой идеологии шаблонов
Дизайнер (или html-кодер) тебе там такого php-кода напишет :D

Насчет отказа от assign-а
ты имеешь ввиду сделать как в шаблонизаторе Britva-ы, где шаблонизатор использует для подстановки меток переменные из глобального пространства имен ? И таким образом не нужно делать assign.
Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 19 Апреля 2003, 00:45:26
Цитировать
Макс:
Разрешить php код в шаблоне
ну почему бы и нет? есть некоторые "моменты", которые намного прроще сделать со вставкой ПХП-кода в шаблон, чем геммороиться с подставляемыми переменными... хотя с другой стороны - ты прав. Это не абстрагирует html от php, а шаблоны как раз и преследуют эту цель.


Цитировать
Макс:
Насчет отказа от assign-а
ты имеешь ввиду сделать как в шаблонизаторе Britva-ы, где шаблонизатор использует для подстановки меток переменные из глобального пространства имен ? И таким образом не нужно делать assign.
м-да... мусора много и, как я уже говорил,
Цитировать
D1g174LM4n14c:
ды, с таким же успехом можно обойтись вообще без шаблонизаторов. просто в нужных местах юзать include\\require операторы...
Название: class Template. Зацените.
Отправлено: nagash от 19 Апреля 2003, 01:10:16
а вообще смысл всего этого кода если в итоге получается надо писать то же самое что и в данном случае

$patterns = array (
"%tool%",
"%header%",
"%maintext%",
"%rootfolder%",
"%spacer%")

$replacements = array (
$tool,
$header,
$maintext,
$rootfolder,
$spacer);

$tpl = str_replace($patterns, $replacements, $tpl);

я не вижу смысла написания этого класса?
Название: class Template. Зацените.
Отправлено: Croaker от 19 Апреля 2003, 01:55:44
Цитировать
Tronyx:
1. Разрешить php код в шаблоне.


Вот это блин круто :))). Вообще-то вся фича PHP и состоит в том, что можно вставлять код в html-файл, если ты не в курсе ;).

А теперь ты предлагаешь шаблонизатор, который релизует функциональность, реализованую в самом интерпретаторе.

Зачем?
Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 19 Апреля 2003, 10:28:36
Цитировать
nagash:
я не вижу смысла написания этого класса?
да, но я все это дорабатываю, придаю выразительности, функциональности и т.д.

Цитировать
Croaker:
А теперь ты предлагаешь шаблонизатор, который релизует функциональность, реализованую в самом интерпретаторе.
а зачем изобретать колесо? можно, конечно, парсить html и искать php-код, а затем его в eval()... а смысл? если и так работает...
Название: class Template. Зацените.
Отправлено: D1g174LM4n14c от 19 Апреля 2003, 11:10:19
Цитировать
nagash:
а вообще смысл всего этого кода если в итоге получается надо писать то же самое что и в данном случае

$patterns = array (
"%tool%",
"%header%",
"%maintext%",
"%rootfolder%",
"%spacer%")

$replacements = array (
$tool,
$header,
$maintext,
$rootfolder,
$spacer);

$tpl = str_replace($patterns, $replacements, $tpl);

не совсем так... тут ты просто заменяешь одни "переменные" другими... а в том классе, что мы обсуждаем, переменным присваеваются результаты парсинга шаблонав, а затем они (переменные) используются в других шаблонах, потом в третьих и т.д. Структура ЕСТЬ!
Название: class Template. Зацените.
Отправлено: MrGreeN от 19 Апреля 2003, 12:21:25
Разрешите вставить свои пять копеек...;)
Енто всё конечно круто, но зачем собаке пятая нога?...( без обид...)
Название: class Template. Зацените.
Отправлено: Tronyx от 19 Апреля 2003, 19:49:36
Цитировать
D1g174LM4n14c:
я же говорил, что это не библиотечный класс. Зачем делать обработку ошибок в своем же классе. Главное - внимательно писать код - тогда не нужно будет тратить время на обработку ошибок.

Если пишишь для себя то да, а если на продажу, где "за рулём" сидит НЕпрограммист... будешь дописывать свой класс? Нелегче ли сразу это сделать? :)

Цитировать
D1g174LM4n14c:
а что ты имеешь ввиду под модкльностью в данном контексте?

Если ты хочешь добавить какую-то фичу ты не лезешь в код класса, ты создаёшь файл-плагин. Посмотри как Smarty устроен (кстати пока я эту фичу видил только в нём)

Цитировать
D1g174LM4n14c:
ды, с таким же успехом можно обойтись вообще без шаблонизаторов. просто в нужных местах юзать include\\require операторы...

Ты не понял. Используется тот же класс и как в твоём случае, та же функция "output" только происходит не парсинг, а компиляция. Разницу видишь?

Цитировать
Макс:
ИМХО это противоречит самой идеологии шаблонов
Дизайнер (или html-кодер) тебе там такого php-кода напишет

Полностью согласен. Меня просили привести пример того как можно наворотить, а можно != нужно.

Цитировать
Макс:
ты имеешь ввиду сделать как в шаблонизаторе Britva-ы, где шаблонизатор использует для подстановки меток переменные из глобального пространства имен ? И таким образом не нужно делать assign.

Да. Только как это сделано у Бритвы мне не нравится, там ещё eval() с вызовом какой-то функции нужен, а посути это тот же assign(). У меня проще:
скрипт:
$QuickTemplate=new QuickTemplate(\'template.tpl\');
$var=\'Переменная\';
$QuickTemplate->PrintPage();
?>
Шаблон:
Var={$var}

Цитировать
Croaker:
Вот это блин круто )). Вообще-то вся фича PHP и состоит в том, что можно вставлять код в html-файл, если ты не в курсе

Вот это блин какой ты крутой и чертовски "умный". :D Попробуй например в шаблоне для FastTemplate(или каком-нибудь похожем) писать на PHP. Если не "заложить" эту функцию, то у тебя ничего не получится.
Название: class Template. Зацените.
Отправлено: Croaker от 20 Апреля 2003, 00:36:32
Цитировать
Tronyx:
Вот это блин какой ты крутой и чертовски "умный".  Попробуй например в шаблоне для FastTemplate(или каком-нибудь похожем) писать на PHP. Если не "заложить" эту функцию, то у тебя ничего не получится.


В FastTemplate нельзя. Потому как основной смысл написания шаблонов - отделения html от PHP. А шаблон, в котором будет использоватся PHP вставка... Весь смысл пропадает (вместе со скоростью).
Название: class Template. Зацените.
Отправлено: Tronyx от 20 Апреля 2003, 07:58:27
Цитировать
Макс:
ИМХО это противоречит самой идеологии шаблонов
Дизайнер (или html-кодер) тебе там такого php-кода напишет
------------------
Полностью согласен. Меня просили привести пример того как можно наворотить, а можно != нужно.


Цитировать
Croaker:
вместе со скоростью

Если применять компиляцию шаблонов(например как в Smarty) скорость совершенно не тереятся.
Название: class Template. Зацените.
Отправлено: Макс от 20 Апреля 2003, 12:42:51
Tronyx
Цитировать
Да. Только как это сделано у Бритвы мне не нравится, там ещё eval() с вызовом какой-то функции нужен, а посути это тот же assign(). У меня проще:
Вообще я в последенее время тоже склоняюсь к идее отказа от assign, только ИМХО разумнее шаблонизатором не переменные использовать, а какой-то массив:

// первый параметр - папка с шаблонами
// имя массива со значениями меток
$tmpl = new Template(\'./templates/dir/\', \'_vars\');
...
// установка переменных шаблона
$_vars = array(\'label1\'=>\'text 1\', \'label2\'=>\'text2\');
echo $tmpl->toHtml(); // вывод пропарсенного шаблона

Так будет хотя бы какое-то разделение пространства имен.
А то дизайнер тебе напишет в шаблоне
{$dbhost}
{$dbuser}
{$dbpass}
{$dbname}

и любой увидит параметры доступа к БД
Название: class Template. Зацените.
Отправлено: FreeSpace от 20 Апреля 2003, 14:04:22
Цитировать
Макс:
А то дизайнер тебе напишет в шаблоне


{$dbhost}
{$dbuser}
{$dbpass}
{$dbname}

и любой увидит параметры доступа к БД


[OFF]
Руки таким дизайнерам надо отрывать :)
А вообще, дизайнер и программер - одна команда! Зачем друг-другу заподлянки устраивать :) ?
[/OFF]
Название: class Template. Зацените.
Отправлено: Макс от 20 Апреля 2003, 14:52:25
FreeSpace
[off] это я просто пример привел, почему следует разделять переменные шаблонизатора от глобальных переменных скрипта [/off]
Название: class Template. Зацените.
Отправлено: Tronyx от 20 Апреля 2003, 21:31:15
Цитировать
FreeSpace:
А вообще, дизайнер и программер - одна команда!

Иногда нет, Макс правильно говорит.

Цитировать
Макс:
Вообще я в последенее время тоже склоняюсь к идее отказа от assign

:beer: А я уж думал сейчас начнётся жудкий спор, как на Xpoint :)

Цитировать
Макс:
А то дизайнер тебе напишет в шаблоне

Всё схвачено. ;) Как правило опасными для вывода могут быть несколько переменных(данные для БД, пароль админа и т.п.) Мы их засовываем в массив $private или ещё какой-нибудь и пишем:
$tpl->BlockVar("private");
или
$tpl->BlockVar(array("admin_pass", "db_host", "db_user", "db_pass"));
И эти переменные в шаблоне нельзя использовать.