Под декорированием мы подразумеваем применение шаблона декоратор (Decorator или Wrapper) для данных, которые мы получили из какого-то источника данных.
Напомним, что шаблон Decorator используется в тех случах, когда нужно к классу добавить поведение, незаметно для его клиентов и не изменяя самого класса.
Разбирем небольшой пример, где мы будем использовать декоратор итератора. Например, у нас есть объект навигации (Navigation), наследник lmbActiveRecord, содержащий поле с адресом страницы page_url. При выводе навигации на странице нам необходимо подсвечивать текущую страницу. Здесь можно применить декоратор (хотя есть и другие способы это реализовать).
Создадим класс HighLightDatasetDecorator:
lmb_require('limb/net/src/lmbUri.class.php'); lmb_require('limb/datasource/src/lmbPagedDatasetDecorator.class.php'); class HighLightDatasetDecorator extends lmbPagedDatasetDecorator { protected $path_field = 'url'; function setPathField($path_field) { $this->path_field = $path_field; } function current() { $record = parent :: current(); $this->_assignHighlight($record); return $record; } protected function _assignHighlight($record) { $path = $record->get($this->path_field); if(!$path) return; $compare = $this->_compareRequestUriWithRecordUri(new lmbUri($path)); if($compare === false || $compare < 0) return; $record->set('hightlight', 1); } protected function _compareRequestUriWithRecordUri($record_uri) { if($record_uri->getHost()) return -1; $uri = lmbToolkit :: instance()->getRequest()->getUri(); return $uri->comparePath($record_uri); } } ?>
Этот класс можно параметрировать при помощи метода setPathField(). HighLightDatasetDecorator сравнивает url-ы (вернее пути) при помощи метода comparePath класса lmbUri() и при необходимости ставит в запись поле 'hightlight' со значением 1. Чуть ниже мы покажем, как это можно использовать в шаблоне.
Базовые классы для декоторов итераторов можно найти в пакете DATASOURCE.
При помощи тегов <fetch:decorate> можно применять декораторы прямо в шаблоне, например:
<active_record:fetch class_path='src/model/Navigation' target='navigation'> <fetch:decorate using='src/dataset/HighLightDatasetDecorator' path_field='page_url'/> </active_record:fetch> <list:list id='navigation'> <list:item> <core:optional for='hightlight'>{$page_title}</core:optional> <core:default for='hightlight'><a href='{$page_url}'>{$page_title}</a></core:default> <br/> </list:item> </list:list>
Атрибут тега using указывает на класс декоратора, который будет применен к списку объектов класса Navigation.
Тег <fetch:decorate> работает таким образом, что он вызывает метод setParamName($param_value) для всех агрументов тега, кроме using. В нашем случае, это приведет к вызову метода setPathField('page_url') и наш объект класса HighLightDatasetDecorator сможет использовать именно поле page_url из объектов Navigation для сравнения.
Тег <iterator:decorate> работает аналогично тегу <fetch:decorate>, с тем отличием, что он применяется внутри <iterator:transfer> тега.
Обсуждение