Инструменты пользователя

Инструменты сайта


limb3:ru:packages:wact:using_decorators_for_iterators

Декорирование данных в WACT-шаблонах.

Под декорированием мы подразумеваем применение шаблона декоратор (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> и <iterator:decorate>

При помощи тегов <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> тега.

Обсуждение

Ваш комментарий. Вики-синтаксис разрешён:
   ____   _  __   ____  _   __  ____ 
  /  _/  / |/ /  / __/ | | / / / __ \
 _/ /   /    /  _\ \   | |/ / / /_/ /
/___/  /_/|_/  /___/   |___/  \____/
 
limb3/ru/packages/wact/using_decorators_for_iterators.txt · Последние изменения: 2010/11/10 10:02 (внешнее изменение)