пример реализации "абстракции от шаблонизатора"

whirlwind

TDD infected, paranoid
> У меня еще вопрос для архитекторов?

Код из боевого проекта. Состав страницы (блоки) задаются через админку. В коде они суются в композитный контроллер (просто по очереди выполняет run(input,output) для каждого)

PHP:
    protected function _prepareComposite(PageSysInfo $page){
        $map = MetaData::createObject("System.Map.Page2Controller");
        $map->filterBy("master",$page);
        $loader = new BulkLoader($map);
        $loader->attachEssence(
            MetaData::createObject("System.Reference.ControllerSysInfo"));
        $loader->sort("sortorder");
        $loader->fetch();
        while ( $loader->next() ){
            $component = $loader->get("ControllerSysInfo");
            $map = $loader->get("Page2Controller");
            $this->addController($map->get("controller"),
                MetaData::createObject($component->get("metaid")),
                $map->get("prefix"),$map->getId());
        }
        $this->attachListener(System::getInstance()->getTemplateResolver());
        $this->attachListener(System::getInstance()->getPermissionResolver());
        $this->attachListener(System::getInstance()->getPresetParamResolver());
    }
в прямолинейном варианте три блока выглядят как

PHP:
$in = ... create input driver
$out = ... create output driver
$newsCtrl = new NewsController();
$newsCtrl->run($in,$out);
$pollCtrl = new LastPollController();
$pollCtrl->run($in,$out);
$weatherCtrl = new WeatherCtrl();
$weatherCtrl->run($in,$out);
в чем проблема? данные, с которыми они работают не связаны непосредственно
 

Alexandre

PHPПенсионер
whirlwind
значить каждый блок собирается стоками
Код:
$pollCtrl = new LastPollController(); 
$pollCtrl->run($in,$out);
а потом вызываем общий контроллер вывода?
механика понятна, не совсем понятно как это работает при многошаблонной системе, особено в примере Sender
у меня есть
- подготовленные шаблоны для блоков Голосования, Новостей, Погоды
- общий шаблон

- контроллер шаблона
- драйвер обработки данных

хотелось бы понять динамику процесса а не иерархию классов?

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

теперь у нас XML - мы опять мы получаем HTML код шаблона для каждого модуля, а что далее?
как будем формировать окончательный вариант шаблона?

надо строить опять xml состоящий из HTML блоков промежуточного кода?
на какой ступене иерархии это разруливается??? По какому принципу выбирается XML/Array ?

и достаточно ли поменять одну строчку кода, как было сказанно ранее, чтоб можно было перейти от смарти к XSLT
(при наличии шаблонов естественно)
 

StUV

Rotaredom
Alexandre
можно универсализировать интерфейс шаблонизатора
сделать универсальный шаблон нельзя ;)

под каждый шаблонизатор нужно делать свою версию шаблона в любом случае, а написать прослойку (драйвер, шлюз, etc...) - это не проблема

соответственно, при наличии драйвера и всех нужных версий шаблонов - да, можно заменить шаблонизатор изменив одну строчку =)
 

whirlwind

TDD infected, paranoid
> теперь у нас XML
Лично я с XML не возился, но думаю что примерно так - нужно получить один большой XML. Если вернуться к интерфейсу, в драйверах ввода/вывода есть понятие префиксов. Это то, что позволяет автоматически разделять "переменные с одинаковыми именами" для разных контроллеров и работать нескольким контроллерам одновременно как на ввод так и на вывод. Эти префиксы можно заюзать для отделения одной ветки от другой в XML.

PS. На примере, для смарти префиксы складываются так

news_id
poll_id

то для XML будет так

<news>
<id></id>
</news>
<poll>
<id></id>
</poll>

etc
 

HraKK

Мудак
Команда форума
У меня чуть по другому.
Есть сущность
new Content($templateEngine::getEngine());
которой передается каким движком будет обрабатыватся содержимое контента.
Внутри контента может быть как уже XML, как HTML со Smarty и тд. Я лишь говорю чем обработать.
 

Alexandre

PHPПенсионер
но думаю что примерно так - нужно получить один большой XML
Так один большой XML, или несколько XSLT преобразований??

мне лично не понятна динамика преобразований.
можно универсализировать интерфейс шаблонизатора
сделать универсальный шаблон нельзя
а кто говорит что можно?
под каждый шаблонизатор нужно делать свою версию шаблона
Это и есть обертка, если не лень, то читай топик с начала. Кроме обертки мы еще пишем драйвер. Хочу заметить, и StUV тоже это заметил (если я правильно понял его фразу), что необходимо по мимо обертки шаблонизатора, для каждого шаблонизатора писать еще и драйвер. Нужен некий стандарт представления данных для вывода для использования его разными шаблонизаторами.
Когда мы выводим одну таблицу - я не вижу проблем. Но если у меня портал, который вызывает кучу блоков и водит кучу разнородной информации, тот тут у нас вылазиет куча разных ньюансов, при использовании разных типов шаблонизаторов.

-~{}~ 06.07.07 18:08:

У меня чуть по другому.
Есть сущность
new Content($templateEngine::getEngine());
я так понимаю $cnt= new Content($templateEngine::getEngine('smarty'));
$outArray = $db->Exec("select * from price");
$cnt->add('out', $outArray);
$t->display($cnt);

А если у меня данные необходимы для XML Engine?
код какой?
$cnt= new Content($templateEngine::getEngine('xml'));
$outArray = $db->Exec("select * from price");
$cnt->add('out', $outArray);
$t->display($cnt);

во втором примере - $outArray должен быть преобразован в XML

Как ты разруливаешь - в каком виде подготавливать данные?
Реализация класса контента в зависимости от типа данных?
или Реализация класса в зависимости от типа $templateEngine?

И еще - а что, если некоторые данные у нас хранятся уже в XML, то для реализации твоей схемы, мы
будем их трансформировать в аррай, а аррай сногва в DOM??
$Dom = $data->GetXml(someSource);
$outArray = $xml::ToArray($Dom);
$cnt->add('out', $outArray);

Как формировать вывод, если у нас осуществляется вывод блоками?
 

HraKK

Мудак
Команда форума
Немного не так. Это упрощенная схема.
$cnt= new Content($templateEngine::getEngine('xml'));
$outArray = $db->Exec("select * from price");
$cnt->add('XML'); -< Сюда передаем ужже готовый к разруливанию XML;
echo $cnt->fetch();


Реализация класса контента в зависимости от типа данных?
Даже не совсем, Content получает в себя обработчик $templateEngine::getEngine('xml') который и разруливает как надо. А сам Content одинаков.

И еще - а что, если некоторые данные у нас хранятся уже в XML, то для реализации твоей схемы, мы
будем их трансформировать в аррай, а аррай сногва в DOM??
Нет в тупую отдадим контенту с указанием движка - XML

-~{}~ 06.07.07 18:40:

Как формировать вывод, если у нас осуществляется вывод блоками?
Content это и есть блок.
 

whirlwind

TDD infected, paranoid
> Так один большой XML, или несколько XSLT преобразований??

При чем здесь XSLT вообще? Драйвер выдает данные в понятном шаблонизатору виде. Шаблон обрабатывается тем шаблонизатором над которым драйвер.

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

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

diamond_krnl

pure-php
push шаблоны и pull шаблоны нельзя абстрагировать, это абсолютно разные подходы.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Интересно, как бы вы делали обертку на шаблоны, по которым строится FUD furum :)
Как я понял навскидку, там по общим шаблонам контроллера, описывающим и логику вывода, и бизнес-логику, из "исходных" компонентов собирается смесь PHP+HTML, которая уже и работает :)
И работает, естесно, быстрей всего - сложная система, но эффективная, на мой взгляд.
 

Franzusow

Новичок
да принцип в общем прост. сосдается интерфаце который включает все самые важные функции Темплате-Сыстем. Не надо смотрет как другие делают, так как етот Принцип относится к Паттерн.
PHP:
inrerface TemplateAdapter{
public function SetTemplateDir($path){};
public function set($name,$value){};
public function out($name,$value){};
// i drugie neotemlimye funkzii
}
для того чтоб подключит новую Темплате-Сыстем нужно простео переписать Interface emplateAdapter

class Adapter_Smarty extends Smarty implements     TemplateAdapter {
//и погнал все функзийи подстраиват, что собственно не какого осебеного Труда не состовляет. 
почти весь код будет состоять из того, что ты фактически Смарти функции переименовываеш.}
Kak Adapter_Template в основном скрипте вызыватся будет, не имеет особого значения, хотя метода faktory которую HraKK упямянул считается стандартным решением .
А в общем такие настройки лутше не в основном Qуеллкоде держать а в
.ini или других настройках к Проэкту.
PHP:
class SupeTemplate implements TemplateAdapter{
$adapter;
public function __construct(){
//otkryvaem konfig-file, smotrim kakaja Template dlja projekta vystavlena
$this->adapter=new Adapter_XXX;
} 
public function set($name,$value){
 return $this->adapter->set($name,$value);
}
//i tak dalee so vsemi funkzijami (ili __call perepisat')
}
все, тепер можно толко с классом SuperTemplate работать не вникая какие Темплаты задействованы.
 

Franzusow

Новичок
все, частично изменил.
Я тут с вами по русски скоро заговорю :)
 

Lews

Новичок
Интересно, когда появится тема в стиле "абстракция от абстракции smth" или "абстрация от пхп".. :)
 

Фанат

oncle terrible
Команда форума
сплошь и рядом.
есть люди, которые пишут рисователи HTML
($table->setProperty("width","100","mesaure=percent"))
есть - которые составляют SQL запросы подобным образом.
и про них мне очень хорошую статейку из джоэла подкинули:
http://local.joelonsoftware.com/mediawiki/index.php/Не_дайте_Астронавтам_Архитектуры_вас_запугать
рекомендую всем участникам дискуссии
 

HraKK

Мудак
Команда форума
*****
ORM модель очень удобная вещи, и архитектуру не разносит как на дрожах от нее. Имхо. А так - очень верная статья.
 

WP

^_^
Объекты и абстракция это конечно хорошо, но очень важно не забывать про реальный мир. Я недавно отлаживал несложный проект магазина на WAFramework... при всем опыте мне потребовалось много времени т.к. там всё было глубоко заООПлено и перемешано с PEAR... матюгал много часов разработчиков и их родственников. У них используется Smarty но тоже "абстрактно", т.е. написано как будто абстрактно но ни одного другого мыслимого шаблонизатора туда вставить не получится.
Куча рекурсивных вызовов, DataObject'ов и т.д... при ошибке в бд вылетает call to undefined function т.к. вместо объекта метод другого объекта вернул объект PEAR_Error.
И к каждому объекту отправляются события....
Это всё глючит и тормозит. А судя по коду над проектом работало несколько человек не один месяц. Вот и делайте выводы... значит 3 человека по два месяца это уже 6000$ как минимум улетело в пустоту.
ORM тоже вещь ПО СУТИ неплохая, в тех случаях когда например есть огромная динамическая форма поиска с кучей критериев и чтоб не писать каждый раз мини-ORM можно воспользоваться существующей. Но меня убивает когда статические запросы генерируют с помощью ORM, т.е. чья структура не зависит от внешних факторов.
Господа, думайте перед тем как писать слова "class" и "new".
 

HraKK

Мудак
Команда форума
Просто мне намного легче реализовывать сущтность новости например как
//insert
$orm->reset();
$orm->setFields('id'=>'null,'name'=>$name);
$orm->insert();
//select
$orm->setLimit =$limit;
$newsArray = $orm->select();
//delete
$orm->setClause('id',$id);
$orm->delete();


И этот код будет универсальный для всех обьектов, юзеры новости и тд. И если у меня меняется таблица достаточно только в конструкторе дополнить или изменить название полей. Все.

чья структура не зависит от внешних факторов.
Что именно вы подразумиваете под этими факторами?

-~{}~ 07.07.07 21:02:

И еще у меня есть один фактор хитренкий который помогает практически избежать потери времени на составление запроса)
 

WP

^_^
> Что именно вы подразумиваете под этими факторами?
Например настройки переданные из формы поиска.
 
Сверху