Мы хотели бы поделиться опытом, как используя views и views_data_export сделать выгрузку yml в Yandex.Market на Drupal 7.
Концепция состоит в том, чтобы, используя views, получить нужные данные и далее собрать все в шаблонах для views_data_export. Такой вариант подходит для выгрузки данных из нод, таксономии, entity и продуктов commerce.
Для начала рекомендуем узнать по подробнее о формате yml в официальной документации.
Наш пример мы будем рассматривать на нодах, а категории представлены терминами таксономии. Нам потребуется два views'а, первый это вспомогательный, предоставит нам категории, а второй данные товаров.
Views yml_categories
Первым мы сделаем views категорий. Он будет передавать готовую структуру категорий в наш основной views. Потребуется views с типом данных "термин таксономии". Создание страницы и блока выключим и перейдем к настройки views'a и полей. Добавим отображение "Data export".
Изменим формат на XML, остальные настройки формата оставим как есть. В фильтры добавим словарь категорий. Добавим вывод полей "имя" и "ID термина". Эти поля мы будем выводить в шаблоне и формировать структуру формата yml.
Укажем путь, по которому будем получать наш файл yml, а также настроим права доступа, чтобы только администратор сайта мог получить выгрузку. Будем выводить весь набор наших товаров, установив отображение всех элементов.
Для категорий нам нужно добиться простой конструкции вида:
<categories>
<category id="id_категории">название_категории</category>
...
</categories>
views-data-export-xml-header--yml-categories.tpl.php
<categories>
В header открываем родительский тег <categories>
. Это обязательное поле в yml.
views-data-export-xml-body--yml-categories.tpl.php
<?php foreach ($themed_rows as $count => $row): ?>
<category id="<?php echo $row['tid'] ?>">
<?php echo $row['name'] ?>
</category>
<?php endforeach; ?>
$themed_row
- это массив готовых данных из views'а. Массив пропустим через цикл, чтобы обернуть каждую категорию в тег. За id возьмем tid таксономии, а наименование поместим внутрь тега.
views-data-export-xml-footer--yml-categories.tpl.php
</categories>
Закроем тег </categories>
, тем самым закончим работать с yml_categories.
Views yml
Теперь нам потребуется views для нод (содержимое). Так же как и для категорий мы будем использовать отображение "Data export".
Формат изменим на XML. Добавим фильтр по типу нашего товара или ноды, в нашем случае это "дверь". Если вы используете мультиязычность на своем сайте, то можете добавить фильтр языка. Настройку полей произведем чуть позже.
Укажем путь для экспорта yml, а также настроим права доступа. Будем выводить весь набор наших товаров.
В столбце "дополнительно" нас интересует только один параметр "настройка запроса". Включим перезапись SQl, чтобы views не проверял node_access.
В формате yml есть обязательные и необязательные поля. Чтобы валидатор пропустил наш файл, нам нужно добавить все обязательные поля. Создадим структуру yml в шаблонах к нашему views'у. Нам потребуется перекрыть header
, body
и footer
. На потребуется перекрыть шаблоны для views_data_export: views-data-export-xml-header.tpl.php
, views-data-export-xml-body.tpl.php
и views-data-export-xml-footer.tpl.php
. Переименуем их так, чтобы шаблоны работали только для конкретного views'a, указав имя вашего --yml
(views-data-export-xml-body--yml.tpl.php
).
views-data-export-xml-header--yml.tpl.php
<?php print '<?xml version="1.0" encoding="UTF-8" ?>'; ?>
<!DOCTYPE yml_catalog SYSTEM "shops.dtd">
<yml_catalog date="<?php echo date('Y-m-d h:i'); ?>">
<shop>
<name><?php echo variable_get('site_name', 'Drupal'); ?></name>
<company><?php echo variable_get('site_name', 'Drupal'); ?></company>
<url><?php echo $GLOBALS['base_url']; ?></url>
<currencies><currency id="RUR" rate="1"/></currencies>
<?php print views_embed_view('yml_categories', 'views_data_export_1'); ?>
<offers>
Разберем подробнее код выше. Чтобы вам было ясно зачем мы используем поля. Подробнее можно ознакомиться с полями в официальной документации. Первые две строки это обязательны для yml. yml_catalog
содержит параметр date
, который через функцию date('Y-m-d h:i')
передает время создания файла. В тег shop
размещаем все настройки нашего магазина.
- name
- company
- url
- currencies
- categories
- offers
В name
, company
, url
выведем название сайта и адрес через variable_get
. currencies
содержит информацию о валюте. Строка views_embed_view('yml_categories', 'views_data_export_1')
мы подставляем наш views категорий (yml_categories
- имя views'а категорий, views_data_export_1
- имя отображения категорий).
views-data-export-xml-body--yml.tpl.php
<?php foreach ($themed_rows as $count => $row): ?>
<offer id="<?php echo $row['nid']; ?>" available="true">
<url><?php echo $row['path']; ?></url>
<price><?php echo $row['field_price_from']; ?></price>
<currencyId>RUR</currencyId>
<categoryId><?php echo $row['field_category']; ?></categoryId>
<?php if (!empty($row['field_main_img'])): ?>
<picture>
<?php $matches = array();
if (!empty($row['field_main_img']) && preg_match('/src="(.*\.(jpg|png|jpeg))"/', $row['field_main_img'], $matches)) {
echo $matches[1];
} ?>
</picture>
<?php endif; ?>
<name><?php echo $row['title']; ?></name>
<description><?php echo htmlspecialchars($row['body']); ?></description>
<country_of_origin>Россия</country_of_origin>
<?php if (!empty($row['field_door_material'])) :?>
<param name="Материал"><?php echo $row['field_door_material']; ?></param>
<?php endif; ?>
<?php if (!empty($row['field_door_collection'])) :?>
<param name="Коллекция"><?php echo $row['field_door_collection']; ?></param>
<?php endif; ?>
<?php if (!empty($row['field_door_color'])) {
$color_arr = explode('|', $row['field_door_color']);
foreach ($color_arr as $color) {
echo '<param name="Цвет">' . $color . '</param>';
}
} ?>
</offer>
<?php endforeach; ?>
В этом шаблоне мы выводим поля views'а в теги. Все поля мы получаем из массива $row
. Для списка ниже, добавим во views соответствующие поля.
- offer - этоn тег обязательный параметр
id
, в него мы добавимnid
- url - добавим url из поля
path
- price - нужно вывести поле содержащие цену вашего товара (
field_price_from
) - currencyId - добавим индекс валюты (RUR)
- categoryId - нужно указать поле таксономии отвечающие за категорю (
field_category
) - name - наименование товара или же заголовок ноды (
title
) - picture - добавим поле картинки с проверкой регулярным выражением (
field_main_img
) - description - описание ноды ли товара (
body
) - country_of_origin - страна производидель
- param - необязательное поля для yml. В него добавляем различные характеристики товара, такие как вес, размер и т.д.
Необязательные поля, такие как <picture>
, мы обернули в if для проверки существования переменой в массиве $row
.<picture>
необязательно, но Яндекс.Маркет рекомендует его добавлять. Разберем <param name="">
по подробней. В атрибут name
добавляем название характеристики, именно это название будет отображаться в маркете. В нашем примере поле field_door_color
множественное и поэтому выводим его через цикл добавляя все его значения. <param>
следует наполнять в соответствии с вашим набором характеристик товара.
views-data-export-xml-footer--yml.tpl.php
В шаблоне footer мы закрываем теги offers
, shop
и yml_catalog
</offers>
</shop>
</yml_catalog>
Итог
Собрав views'ы и шаблоны, перейдя по адресу /yml
, вы сможете сделать выгрузку yml для вашего магазина в Яндекс.Маркете.
Комментарии
Спасибо большое за подробный гайд. Вопрос - можно ли сделать экспорт автоматически по запуску крона?
имеется в виду, по запуску крона, создание обновленного yml-файла на сервере в корне сайта
Решение вопроса с сохранением на сервере и автоматизацией:
1. делаем (заменяя параметры, где надо, на свои значения) и подключаем модуль: https://www.drupal.org/project/views_data_export/issues/1875456#comment…. Модуль позволяет прописать место дефолтного сохранения на сервере.
2. настраиваем в менеджере задач (на стороне сервера) еще одну задачу на выполнение - прописываем команду:
cd /home/USER/public_html && /usr/bin/env PATH=/home/USER/.composer/vendor/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin COLUMNS=72 ../vendor/bin/drush -u 1 --uri=https://mysite.ru --quiet views-data-export yml views_data_export_1 yml_export.xml
USER - название вашего пользователя
Имхо, при добавлении в фильтры поля "Термин таксономии: Название" надо снять галочку с пункта "Сделать это поле ссылкой на страницу его термина таксономии". Категории выгружаются без ссылок (насколько я правильно просмотрел образцы этих файлов, конечно)
Еще один вопрос - если каталог многоуровневый, то как это прописывается в списке категорий? Как сделать, чтобы прописывались родительские id?
По поводу добавления parentId, если каталог имеет не плоскую структуру (присутвует вложенность категорий) вопрос решается след образом:
1. в связях добавляем "Термин таксономии: Родительский термин" (снимем галочку в настройках с пункта "Эта связь обязательна")
2. В полях добавляем еще один "Термин таксономии: ID термина", но в настройках выбираем "Связь -> Родитель"
3. корректируем views-data-export-xml-body--yml-categories.tpl.php на следующий вид:
<?php foreach ($themed_rows as $count => $row): ?>
" parentId="<?php echo $row['tid_1'] ?>">
<?php echo $row['name'] ?>
<?php endforeach; ?>
Вроде все.
Боюсь, в п.3 ввел в заблуждение. Полностью views-data-export-xml-body--yml-categories.tpl.php будет выглядеть так:
<?php foreach ($themed_rows as $count => $row): ?>
" parentId="<?php echo $row['tid_1'] ?>"><?php echo $row['name'] ?>
<?php endforeach; ?>
Картинка товара отсутствует в выгрузке yml. Не проходит условие if !empty. Какие настройки поля должны быть во views?
PS. Картинок на товарах от 1 до 5
Как минимум так же повторить переопределние вьюса,
но я думаю есть более удобные варианты
Добрый вечер!
Подскажите пожалуйста, как мне переопределить шаблон представлений, для view data export. Как бы я не менял имя новых файлов, в папке с шаблонами модуля, не могу добиться разного вывода данных. Drupal упорно читает дефолтные файлы шаблона.
Большое спасибо за подробную статью. Только почему то в xml некоторые предложения по 3-4 раза повторяются. Подскажите?
Спасибо за статью! Очень помогло, правда у вас есть небольшая ошибка, нет закрывающего тега в строке:
<?php echo $row['title']; ?