ФорумПрограммированиеПыхнуть хотите?Готовые решения → Мой нативный шаблонизатор STemp 2.0

Мой нативный шаблонизатор STemp 2.0

  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 11 сентября 2009 г. 3:37, спустя 2 минуты 51 секунду

    ахуеть ты ответил!
    Сапожник без сапог
  • AndryG

    Сообщения: 237 Репутация: N Группа: Адекваты

    Spritz 11 сентября 2009 г. 5:05, спустя 1 час 27 минут 34 секунды


    Если могут понадобиться какие-то значения, разработчик должен знать о том, что они понадобятся, уже в контроллере.

    По Вашему и правильней будет.


    Я бы указал типы результатов … зачем зря читателя напрягать (а ещё лучше пример возвр. значений)

    Не понял к чему это.

    Я о том, что Вы вызываете "внешние" методы. И читатель не знает, какого вида результат он возвращает. Язык не типизирован. Приходится уже потом догадываться, что же там нам вернули и в каком виде. Помогите читателю … покажите, с какими данными в переменных он двигается дальше по коду.


    Почему в контроллере решаем, что будет подключать шаблонизатор ?
    И в итоге почти все контроллеры почти всегда стартуют из index.tpl.php
    Смешиваем логики C и V. Или нет?

    Нет. В контроллере решаем, что подключать. В index.tpl.php только подключаем. Где там контроллеры?

    Вроде как идентично.
    Вы в контроллере принимаете ДВА решения "КОГО показать, В ЧЁМ показать". Необычно.


    Потенциальная дыра.

    "не должно" - плохо так думать в вопросах защиты.

    Про часы и параметры … по умолчанию ставят, обычно, наиболее часто используемый вариант.


    Расширил бы до возможности принимать ассоц. массивы [name] => value.

    Если я правильно понял, чтобы каждый элемент массива становился отдельной переменной? А как быть, если нужно передать именно массив?))

    http://pyha.ru/forum/topic/3393.msg69508#msg69508 второй метод.

    Не уловил, в чем тут игра со спичками.

    Спички в том, что Вы оперируете HTML-кодом ДО шаблона. Я считаю, что в MVC ему место только в V … точнее в шаблоне, который этот V обрабатывает.


    По-умолчанию, все переменные обрабатываются перед отдачей.

    А я предлагаю фильтровать не на выходе из шаблона, а на входе в шаблон.
    Выше уже описано почему.

    "Всё настраивается".
    Пистолет … у него настраивается направление вылета пули … по умолчанию как обычно. А если админ дурак и настроил вылет в противоположную сторону - его право.
    Удобно! Хочешь застрелится - только настройки поменяй. Не надо напрягаться, тащить пистоль к виску.
    И какова цена ошибки?
    Вот и Ваши настройки … раз ошибитесь … и до одного места все ваши 99 аккуратных шаблонов. Для хака хватает одного дырявого.



    Спустя 259 сек.

    хз, что за get_block такой. мой класс весь на виду, шаблоны и тестовые данные в архиве.
    у тебя я вижу в исходниках один охуенный assign — извини, это плохой код. ничего больше не надо.


    Давайте включим мозги.
    Тема "Нативный шаблонизатор".
    Название метода "get_block($block_name)"
    Спор идет о выводе подключаемых блоков.
    Логично предположить, что эта функция возвращает код, который сформирован по шаблону с именем $block_name.

    "Плохой код …" … похоже на подростка в период полового созревания. От меня, наверное, ожидают: "Посмотри на свой _escape" ? :)

  • artoodetoo

    Сообщения: 5139 Репутация: N Группа: в ухо

    Spritz 11 сентября 2009 г. 5:53, спустя 48 минут 13 секунд

    нет, батенька, я от вас ничего не ожидаю. у меня дети в периоде полового созревания, так что я смотрю на вас филоофски, без напряга.
    ιιlllιlllι унц-унц
  • sap

    Сообщения: 2701 Репутация: N Группа: Кто попало

    Spritz 11 сентября 2009 г. 12:15, спустя 6 часов 22 минуты 5 секунд

    Кстати, Адворд, я вот сделал страничку для своего шаблонизатора: http://s-a-p.in/stemp/
    Не подскажешь, как бы я мог такое сделать на вордпрессе, который ты так восхваляешь?)
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 11 сентября 2009 г. 23:47, спустя 11 часов 32 минуты 6 секунд

    sap, а что ты там такого сложного сделал? Это легко решается на вордпрессе
    adw/0
  • Lirck

    Сообщения: 1658 Репутация: N Группа: Джедаи

    Spritz 12 сентября 2009 г. 0:26, спустя 38 минут 23 секунды

    :D
  • sap

    Сообщения: 2701 Репутация: N Группа: Кто попало

    Spritz 13 сентября 2009 г. 4:39, спустя 1 день 4 часа 13 минут


    sap, а что ты там такого сложного сделал? Это легко решается на вордпрессе

    Неужели?) Почему тогда мануал php.net не на вордпрессе?)
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 13 сентября 2009 г. 7:39, спустя 2 часа 59 минут 25 секунд

    sap, сам то понимаешь что сказал?
    adw/0
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 13 сентября 2009 г. 7:39, спустя 41 секунду

    adw0rd, он фанат php.net ))))))
    Сапожник без сапог
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 13 сентября 2009 г. 7:41, спустя 1 минуту 45 секунд


    adw0rd, он фанат php.net ))))))
    чеж тогда его херню не юзает пхп.нет? невзаимная любовь)
    adw/0
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 13 сентября 2009 г. 7:53, спустя 12 минут 16 секунд

    adw0rd, точно, то он и бурый такой всегда)
    Сапожник без сапог
  • AndryG

    Сообщения: 237 Репутация: N Группа: Адекваты

    Spritz 15 сентября 2009 г. 11:01, спустя 2 дня 3 часа 7 минут


    AndryG, как выглядит то! DEFENCE!!!

    http://ru2.php.net/manual/en/function.array-walk-recursive.php

    …..

    <?php
    $arr = array(
    'branc_a' => array (11,12,13),
    'branc_b' => array (21,22,23)
    );

    function call_back(&$v,&$k){
     $k = 'change_'.$k;
     $v = 'change_'.$v;
     echo "\n $k => $v";
    }
    echo "<PRE>\n Изначальный массив:".print_r($arr,true)."\n\n array_walk_recursive: \n";
    array_walk_recursive($arr,'call_back');

    echo "\n\n мой метод assign:";
    $v = new v_www();
    $v->assign('arr',$arr);
    echo "\n".print_r($v->tpl_var_for_pyha(),true);
    exit();

     Изначальный массив:Array
    (
       [branc_a] => Array
           (
               [0] => 11
               [1] => 12
               [2] => 13
           )

       [branc_b] => Array
           (
               [0] => 21
               [1] => 22
               [2] => 23
           )

    )


    array_walk_recursive:

    change_0 => change_11
    change_1 => change_12
    change_2 => change_13
    change_0 => change_21
    change_1 => change_22
    change_2 => change_23

    мой метод assign:
    Array
    (
       [arr] => Array
           (
               [branc_a] => Array
                   (
                       [0] => change_11
                       [1] => change_12
                       [2] => change_13
                   )

               [branc_b] => Array
                   (
                       [0] => change_21
                       [1] => change_22
                       [2] => change_23
                   )

           )

    )

    В справке пишут: "Никакой ключ, соответствующий значению типа array, не будет передан в функцию."
    В справке пишут: " Если требуется, чтобы функция funcname изменила значения в массиве, определите первый параметр funcname как ссылку. "
    Получается, что с array_walk_recursive я теряю первоначальное дерево и возможность "прорабатывать" ключи массива.
    Спустя 192 сек.
    Прогнал :) Уже тут увидел, что прогнал с деревом.

    Но невозможность изменять ключи мне всё одно фигня получается.
  • artoodetoo

    Сообщения: 5139 Репутация: N Группа: в ухо

    Spritz 15 сентября 2009 г. 11:51, спустя 49 минут 53 секунды

    а зачем тебе менять ключи? ты их тоже выводишь?
    ιιlllιlllι унц-унц
  • AndryG

    Сообщения: 237 Репутация: N Группа: Адекваты

    Spritz 15 сентября 2009 г. 23:11, спустя 11 часов 19 минут 55 секунд

    Конечно.
    Для примера …
    Модель возвращает массив [id] => [value]. Делаем ссылки. [id] уходит в href, [value] в текст ссылки.

    И я не буду надеяться на то, что id - это только число.
    Вполне возможны и НЕ суррогатные ключи, а какой-нить натуральный текстовый.
  • alexxx

    Сообщения: 11 Репутация: N Группа: Кто попало

    Spritz 17 ноября 2009 г. 4:14, спустя 62 дня 6 часов 3 минуты

    Вот тут http://pyha.ru/forum/topic/554.105 поднимал вопрос  по поводу перехвата ошибок Parse error … в нативном шаблонизаторе
    В случае если в самом шаблоне допущена синтакс. ошибка выполнение прерывается и вываливается ошибка Parse error …
    если все остальные ошибки можно перехватить так:

    <?php
    class MyException extends Exception {
      public function __construct($message, $errorLevel = 0, $errorFile = '', $errorLine = 0) {
         parent::__construct($message, $errorLevel);
         $this->file = $errorFile;
         $this->line = $errorLine;
      }
    }
    set_error_handler(create_function('$c, $m, $f, $l', 'throw new MyException($m, $c, $f, $l);'), E_ALL);
    try
    {
       include "echo.php";
    }
    catch (MyException $e) {echo $e->getCode();}
    ?>


    то для Parse error данный способ не подходит

    Первоночально функция display имела практически такой же вид

    	public function display($template)
    {
    $this->template = $this->path.$template;

    if (!file_exists($this->template))
    throw new STempDisplayException('Template file '.$template.' not exitst');

           header("Content-type: text/html; charset=".$this->params['charset']);

    require($this->template);

    if ($this->params['exit_after_display'])
    exit;
    }


    за исключением некоторых мелочей так вместо require использовал include

    однако всеже было желание найти способ отлавливать все ошибки которые могут возникнуть при разборе и выполнении шаблона в итоге пришел к такому

    	public function display($template)
    {
    if(!$template) die('Шаблон не задан!');
    $this->_template_ = "{$this->_path_}$template.tpl";
    if(!file_exists($this->_template_)) die("Шаблона $this->_template_ не существует!");
    //$this->_template_ = preg_replace("#global[^\?;]+#si", "", file_get_contents($this->_template_));

    $this->_template_ = file_get_contents($this->_template_);
    ob_start();
    $result = @eval("?>{$this->_template_}").ob_get_clean();
    if(!$result)
    {
    $exceptionFunction = create_function('$a', 'throw new ParseException($a);');
    ob_start();
    *** $result = eval("?>{$this->_template_}").ob_get_clean();
    preg_replace("#<b>Parse error</b>:.*?on line.*?<b>(.*)</b><br />#ei", "\$exceptionFunction('Ошибка в шаблоне '.\$template.'.tpl строка $1');", $result);
    }
    return $result;
    }


    include заменил на @eval именно с собакой чтобы в буфер не кидалось сообщение об ошибке

    тогда если наступает ошибка Parse error переменная $result = null; проверяем и если так то в строке *** получаем сообщение об ошибке
    и в следующей строке парсим его при этом видно что если это ошибка типа Parse error то бросается исключение иначе исключение в этом месте не бросается
    а бросается способом описанным выше.

    далее для отрисовки шаблона используем такой вызов

    		try{echo $this->template->display($document->template);}
    catch (MyException  $e) {echo $e->getLine();}
    catch (ParseException $e) {echo $e->getMessage();}


    таким образом перехватывая все ошибки и выводя на экран или в лог

    Плюсы от замены include на eval
    1 возможность перехватить ошибку Parser error
    2 шаблоны перед исполнением можно редактировать например через preg_replace
    что позволит запретить использование дерективы global и соответственно несанкцианированного доступа к данным
    или например замены md5(); на $this->md5(); (md5 так для примера а вообще нужно по шаблону заменять все стандартные
    функции php и далее добавляя в класс шаблонизатора нужные методы можно разрешить использование только нужных нам функций)
    3 также смело можно использовать <?= …?> вместо <?php echo …?>


    Минус в том что Fatal error не получается поймать.

    все это просто размышления о том как сделать использование нативных шаблонов более безопасным
    чтобы скачивая такой шаблон можно было не боясь запускать без предварительных проверок.

Пожалуйста, авторизуйтесь, чтобы написать комментарий!