dervan |
|
---|---|
Мы с Dayver'ом представляем результаты практического применения XTemplate с IF'ами - из опыта работы Dayver'а по выносу HTML из админки.
Предлагаем для тестирования доработанный XTemplate: xtemplate.class.php_57.zip Просьба к medar'у - посмотреть внесённые изменения, может будут какие замечания. Существенных изменений не вносилось, все исправления - простые. 1. Использование переменных bool приводило к ошибке. Пример. Переменная в коде PHP: $is_test = false;Условие в шаблоне: <!-- IF !{PHP.is_test} -->not is_test<!-- ENDIF -->В результате - ошибка: Parse error: syntax error, unexpected ')' in mysite.com/system/xtemplate.class.php(781) : eval()'d code on line 1 Причина - в XTemplate не было поддержки bool, они не нужны в шаблонах. Это мы поправили, тут вроде обсуждать нечего - bool в условиях использоваться будут. 2. Исходя из практики, кроме короткого варианта с IF нужен ещё и вариант с ELSE. Такой вариант добавлен, сейчас в шаблоне возможны такие условия: <!-- IF <'if' statement> -->['then' content]<!-- ENDIF --> <!-- IF <'if' statement> -->['then' content]<!-- ELSE -->['else' content]<!-- ENDIF --> Реализация получилась простой - в коде medar'а исправлено 2 строки, и добавлена одна необязательная (в стиле уже сделанного им кода). Немного усложнился regex, но в целом применение такой конструкции должно давать выигрыш во времени обработки. Примеры из этого топика. # medar :<!-- IF strpos({PAGE_TITLE}, "жуй") --> {PAGE_TITLE|str_replace('жуй', '', %s)} ц-ц-ц как нехорошо <!-- ENDIF --> <!-- IF !strpos({PAGE_TITLE}, "жуй") --> {PAGE_TITLE} <!-- ENDIF --> # dervan :<!-- IF {PHP.usr.id} < 1 --> вы - гость <!-- ENDIF --> <!-- IF {PHP.usr.id} >= 1 --> вы - зарегистрированный посетитель <!-- ENDIF --> В каждом из этих примеров парсится 2 условия IF, т.е. regex обрабатывается 2 раза. Кроме того, в 1-м примере в условиях IF дважды вызывается функцища strpos(), а во 2-м примере - дважды парсится тег {PHP.usr.id}. Если переписать эти примеры с ELSE, они будут работать быстрее, хотя regex для реализации ELSE чуть сложнее. <!-- IF strpos({PAGE_TITLE}, "жуй") --> {PAGE_TITLE|str_replace('жуй', '', %s)} ц-ц-ц как нехорошо <!-- ELSE --> {PAGE_TITLE} <!-- ENDIF --> <!-- IF {PHP.usr.id} < 1 --> вы - гость <!-- ELSE --> вы - зарегистрированный посетитель <!-- ENDIF --> В шаблоне для админки, который переделал Dayver, подобных конструкций - подавляющее большинство, поэтому исходя из практики выгоднее использовать вариант с ELSE. Предлагаем оставить в XTemplate вариант с поддержкой ELSE. 3. Проблема из-за копирования глобальных переменных методом scan_globals(), в результате чего в шаблоне не видны глобальные переменные, присвоенные после создания объекта XTemplate. На практике это создаёт большие сложности. Пример. Эту переменную $lincif_conf можно использовать в шаблоне: $lincif_conf = sed_auth('admin', 'a', 'A'); $t = new XTemplate(sed_skinfile('admin.inc', false, true));А эту переменную $lincif_conf использовать в шаблоне невозможно: $t = new XTemplate(sed_skinfile('admin.inc', false, true)); $lincif_conf = sed_auth('admin', 'a', 'A'); Для решения проблемы удалось легко реализовать то, о чём говорил medar: # medar : Надо будет решить эту проблему по-другому - вообще отказаться от scan_globals(), а при парсинге тэгов {PHP.xxx} обращаться непосредственно к $GLOBALS. Из метода scan_globals() убрано копирование $GLOBALS: public function scan_globals () { if ($this->force_globals && ini_get('auto_globals_jit') == true) { $tmp = $_SERVER; $tmp = $_ENV; $tmp = $_REQUEST; unset($tmp); } } А в методе parse() присваивается указатель: $this->vars['PHP'] =& $GLOBALS;и уничтожается перед выходом из parse(). Т.е. $GLOBALS теперь не копируется, и в то же время нет опасности уничтожения $GLOBALS через указатель $this->vars['PHP'] - этот указатель теперь не существует вне метода parse(). Возникавшая из-за работы через указатель напрямую с $GLOBALS накладка, которая проявлялась в копировании в пустые строки умолчательных значений, определённых define(), в методе parse() была исправлена. Сообщение об этой накладке: # dervan : К тому же есть нюансы при работе метода parse(). Например, такой код в конце system/header.php, плюс тег {PHP.TEST_DEFINE} в header.tpl: Из метода get_vars_value() аналогичный код был удалён - пустую строку, которая пойдёт на проверку в IF, не надо подменять умолчательным значением. Остальной код в parse() был внимательно изучен, других накладок из-за работы через указатель напрямую с $GLOBALS не обнаружено. Предлагаем оставить в XTemplate этот вариант без копирования $GLOBALS. |