====== Использование fetch и active_record:fetch тегов-ов в WACT-шаблонах ====== ===== Что такое fetcher-ы ===== **Fetcher**-ы используются для получения данных непосредственно из WACT-шаблонов. Два слова о том, что такое fetcher-ы. Это такие классы, которые реализуют интерфейс WactFetcher или наследники от lmbFetcher класса, которые поддерживают метод **fetch()**. Этот метод **всегда должен возвращать итератор** (это важно!). В шаблонах fetcher-ы используются для получения данных через тег [[limb3:ru:packages:wact:tags:fetch_tags:fetch_tag|]]. Другой тег [[limb3:ru:packages:wact:tags:lmb_fetch_tags:lmb_active_record_fetch_tag|]], который должен быть вам знаком по базовому туториалу и по разделу [[limb3:ru:packages:active_record|"Использование ACTIVE_RECORD""]], является аналогом тега . Класс тега наследуется от класса тега , но первый по-умолчанию использует класс lmbActiveRecordFetcher (limb/web_app/src/fetcher/lmbActiveRecordFetcher.class.php) для получения данных. То есть fetcher-ы нужны чтобы делать запросы на получение каких-либо данных прямо из шаблонов. Fetcher-ы могут содержать различные методы, которыми их можно параметрировать. Эти методы имеют вид setSomeParam($value). По-умолчанию fetcher-ы поддерживают следующие методы: * **setOrder()** - для задания сортировки * **setLimit()** - для ограничения количесва элементов в выборке * **setOffset()** - для указания отступа от начала выборки, начиная с которого нужно передавать данные в шаблон (offset). Различные fetcher-ы поддерживают другие методы для задания параметров, например, класс lmbActiveRecordFetcher поддерживает методы setRecordId(), setRecordIds, setFind(). В шаблонах для задания параметров fetcher-ов используется тег ****, каждый атрибут которого преобразуется в вызов метода вида setParamName($param_value). ===== Использование тега в WACT-шаблонах ===== ==== Вывод списка объектов ==== Пусть нам необходимо получить итератор с данными. Допустим, что мы будем использовать особый fetcher - NewsFetcher, который, допустим, возвращает список новостей. :
{$date}{$title}
Атрибут тега **using** указывает на путь до класса fetcher-а(обычно такие классы кладутся в папку src/fetcher/ проекта). Атрибут **target** указывает, куда необходимо передать данные; в нашем случае это будет тег , который занимается отображением данных. ==== Вывод единичного объекта ==== Пусть теперь нам необходимо отобразить только одну первую новость:
{$date}
{$title}
Обратите внимание на атрибут тега **first**, который говорит тегу, что нужно передать не весь список данных, а только первый полученный элементв из итератора. В атрибуте **target** мы указали идентификатор тега - это так называемый единичный контейнер данных, в отличие от тега. Если вы забудете указать **first**, тогда шаблонизатор предпримет попытку передать весь итератор (даже если в нем будет всего 1 элемент) в и будет сгенерировано исключение во время работы шаблона. см. также раздел [[data_containers|"Контейнеры данных WACT"]]. ==== Задание сортировки данных ==== Допустим, нам необходимо вывести все новости отсортировав их по заголовку. Если по-умолчанию новости сортируются по дате, есть способ изменить способ сортировки прямо из шаблона. Для этого можно использовать атрибут **order**. Это можно сделать так: [...] Или так: [...] Тег приводит к вызову метода setAttributeName($value) у fetcher-а для каждого своего атрибута. То есть NewsFetcher получит вызов метода setOrder('title=ASC'). Можно указать несколько сортировок, разделяя их запятыми: [...] Использование **order** на самом деле приводит к вызову метода sort() для итератора полученного из NewsFetcher, для последнего примера это будет $dataset->sort(array('title' => 'ASC', 'id' => 'DESC')); ==== Ограничение размера выборки ==== Иногда перед нами стоит задача вывести только некоторое количество объектов в шаблоне, например, только 3 последние новости. Для этого мы можем использовать атрибуты **offset** и **limit**: [...] Это можно сделать и так: [...] Допустим нам нужно вывести 3 новости, начиная с 3-й: [...] ===== Создание своих fetcher-ов. ===== Допустим, у нас есть задача - сделать свой fetcher для выборки объектов класса Node по своим параметрам. Приведем класс этого fetcher-а, который мы назвали NodeKidsFetcher: type = $type; } function setParentId($parent_id) { if($parent_id) $this->parent_id = $parent_id; } function setParentPath($path) { $this->path = $path; } protected function _createDataSet() { $toolkit = lmbToolkit :: instance(); if($this->path && !$this->parent_id) { if($node = Node :: findByPath('Node', $path)) $this->parent_id = $node->id; } $criteria = new lmbSQLCriteria("parent_id = " . (int)$this->parent_id); if($this->type) { $type_id = NodeType :: generateIdFor($this->type); $criteria->addAnd(new lmbSQLCriteria('type_id ='. $type_id)); } return lmbActiveRecord :: find('Node', $criteria); } } ?> Обратите внимание, что дочерние классы должны расширять защищенный метод **_createDataset()**. Это реализовано исходя из того, что родительский класс lmbFetcher содержит функционал по ограничению (offset, limit), по сортировке (order) полученного итератора и этот функционал должен быть всегда доступен клиентам fetcher-ов. Поэтому дочерние классы не перекрывают метод getDataset(). ===== Пример использование созданного нового fetcher-класса ===== Глядя на методы класса NodeKidsFetcher, можно сделать вывод, что в шаблонах мы можем использовать параметры parent_path, parent_id и type, например: Атрибут **using** указывает на класс fetcher-а, при помощи которого будут получены данные. В последнем примере, если в запросе ничего не придет, будут выбраны дочерние элементы родителя по пути /files. ===== Использование тега ===== Тег [[limb3:ru:packages:wact:tags:lmb_fetch_tags:lmb_active_record_fetch_tag|]] в основном работает аналогично тегу . Отличия заключаются в следующем: * в атрибуте using указывается не путь до fetcher-а, а путь до класса, дочернего от lmbActiveRecord * можно использовать любой find()-метод класса ActiveRecord, если указать параметр find. * можно передавать любые параметры в find()-методы при помощи тега [[limb3:ru:packages:wact:tags:lmb_fetch_tags:lmb_find_params_tag|]]. Подробнее об использовании тега [[limb3:ru:packages:wact:tags:lmb_fetch_tags:lmb_active_record_fetch_tag|]] см. в разделе [[limb3:ru:packages:active_record|"Использование ACTIVE_RECORD в шаблонах WACT"]].