Blitz::getStruct - как получить переменные, зная контекст?

Groove

Новичок
Blitz::getStruct - как получить переменные, зная контекст?

День добрый всем.
Вопрос скорее к fisher, но задам его публично, вдруг кто то изобрел красивое решение.
В php_templates есть такая классная штука как "tmpl_structure": передаешь ей контекст и она дает тебе все переменные, существующие в этом контексте.
Ниже поясню, что имел в виду.

Есть такой код:
PHP:
$tpl = tmpl_open('php_templates.tpl');
$s = tmpl_structure($tpl, '/item', TMPL_TAG, TMPL_SHORT);
print '<pre>';
print_r($s);
print '--------------------------';

$Template = new Blitz('blitz.tpl');
print_r($Template->getStruct('/item'));
print '--------------------------';
print '</pre>';
И два шаблона для него:
php_templates.tpl
PHP:
<tmpl:item>
    <h1>{ARTICLE_NAME}</h1>
    {article_text}
    {hard_calculate_field}
</tmpl:item>
blitz.tpl
PHP:
{{ BEGIN item }}
    <h1>{{ $ARTICLE_NAME }}</h1>
    {{ $article_text }}
    {{ $hard_calculate_field }} 
{{ END }}
получим результат:
PHP:
Array
(
    [0] => article_name
    [1] => article_text
    [2] => hard_calculate_field
)

--------------------------
Array
(
    [0] => /item/
    [1] => /item/article_name
    [2] => /item/article_text
    [3] => /item/hard_calculate_field
)

--------------------------

А теперь немного о том, для чего мне это нужно:
создаем файл "php_templates.php"
PHP:
<?
class Article_View_Item{

    public $props = array();

    function __construct($fields = array()){
        $this->props = $fields;
    }

    protected function __get($name){
        $getter='get__'.$name;
        if (method_exists($this, $getter)){
            return $this->$getter();
        }
        return (isset($this->props[$name])) ? $this->props[$name] : null;
    }

    /**
     * Очень сложно вычисляемое поле, которое не обязательно дергать везде
     *
     * @return unknown
     */
    function get__hard_calculate_field(){
        return md5(md5(md5(microtime(true))));
    }

}
//получили из БД список статей
$rows = array();
for($i=1; $i<5; $i++){
    $row = array(
        'article_name' => 'Новость '.$i,
        'article_text' => 'Текст новости '.$i,
    );
    $rows[$i] = new Article_View_Item($row);
}

$tpl = tmpl_open('php_templates.tpl');
$item_scructure = tmpl_structure($tpl, '/item', TMPL_TAG, TMPL_SHORT);
foreach ($rows as $row) {
	tmpl_context($tpl,'/item');
	tmpl_iterate($tpl,'/item');
	foreach ($item_scructure as $field) {
	   tmpl_set($tpl,$field,$row->$field);
	}
}
print tmpl_parse($tpl);
print '<br />--------------------------<br />';

?>
Соотвественно, если это в этот View подадим на входе шаблон БЕЗ сложно вычисляемого поля, то метод вычисления вызываться не будет
PHP:
<tmpl:item>
    <h1>{ARTICLE_NAME}</h1>
    {article_text}
</tmpl:item>
В Блитце такого эффекта я смог добиться только при помощи пользовательских методов, из-за отсутствия нативного аналога "tmpl_structure".

PHP:
<?
class Article_View_Item extends Blitz{
    //поля из
    public $props = array();

    function loadData($fields = array()){
        $this->props = $fields;
    }

    function registerField($field){
        $this->props[$field] = null;
    }

    protected function __get($name){
        $getter='get__'.$name;
        if (method_exists($this, $getter)){
            return $this->$getter();
        }
        return (isset($this->props[$name])) ? $this->props[$name] : null;
    }

    public function  __call($method, $params)
    {
        if (true == method_exists($this, 'get__'.$method)) {
            return call_user_func_array(array(&$this, 'get__'.$method), $params);
        }
        return $this->$method;
    }

    /**
     * Очень сложно вычисляемое поле, которое не обязательно дергать везде
     *
     * @return unknown
     */
    function get__hard_calculate_field(){
        return md5(md5(md5(microtime(true))));
    }

    function toArray(){
        return $this->props;
    }

}
//получили из БД список статей
$rows = array();
for($i=1; $i<5; $i++){
    $row = array(
    'article_name' => 'Новость '.$i,
    'article_text' => 'Текст новости '.$i,
    );
    $item = new Article_View_Item();
    $item->loadData($row);
    $rows[$i] = $item;
}

$Template = new Article_View_Item('blitz.tpl');
foreach ($rows as $row) {
    $Template->block('/item',$row->toArray());
}
echo $Template->parse();


?>
Шаблон, соответственно, стал таким:
PHP:
{{ BEGIN item }}
    <h1>{{ $article_name }}</h1>
    {{ $article_text }}
    {{ hard_calculate_field() }}
{{ END }}
Количество кода заметно увеличилось по сравнению с использованием php_templates.
Вызов через префикс "get__" оставил для возможности переключения шаблонизатора .

Может быть я просто не понял парадигмы этого шаблонизатора? Просветите, пожалуйста!
 

fisher

накатила суть
вопросы фишеру лучше задавать напрямую фишеру по емейлу или в личку, форум я читаю редко. getStruct не имеет аргументов и выдаёт всю структуру шаблона. собственно если потом это обработать и выдернуть нужную структуру - я так понимаю, что задача будет решена.
 

pilot911

Новичок
Блиц хорош, но как показала практика, лучше использовать чистый пхп, который сделает доступным математику в IF/ELSE

жаль, что математики пока нет в Блице
 

fisher

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

fixxxer

К.О.
Партнер клуба
А зачем математика в template engine сложнее first/last/even/odd? Это ж очень редко надо - можно и во вьюхе флажок поставить - и шаблон читаемее будет.

Хотя в принципе возможно было бы разумно добавить if callback() / unless callback(). Но это будет переключение контекста постоянное в zend vm, если этим злоупотреблять, тормозаааа же.
 
Сверху