Мы хотели бы поделиться опытом, как используя 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 для вашего магазина в Яндекс.Маркете.

Александр Долженков

Комментарии

Андрей

Спасибо за статью! Очень помогло, правда у вас есть небольшая ошибка, нет закрывающего тега в строке:
<?php echo $row['title']; ?

Спасибо за замечание! Обязательно поправим.
Виталий

Спасибо большое за подробный гайд. Вопрос - можно ли сделать экспорт автоматически по запуску крона?

Виталий

имеется в виду, по запуску крона, создание обновленного 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 - название вашего пользователя

Виталий

PS drush на сервере д.б. уже установлен.

Виталий

Имхо, при добавлении в фильтры поля "Термин таксономии: Название" надо снять галочку с пункта "Сделать это поле ссылкой на страницу его термина таксономии". Категории выгружаются без ссылок (насколько я правильно просмотрел образцы этих файлов, конечно)

Виталий

Еще один вопрос - если каталог многоуровневый, то как это прописывается в списке категорий? Как сделать, чтобы прописывались родительские 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; ?>

Добавить комментарий