Что такое YML и для чего он нужен?
YML представляет собой XML-документ, в котором описываются товары, их категории, цены, параметры и другая информация, необходимая для размещения товаров на Яндекс.Маркете. Основные элементы YML:
<categories>
— категории товаров.<offers>
— конкретные предложения товаров с их характеристиками.<shop>
— информация о магазине.
Генерация YML для Minishop2
Вариант 1: сделай сам
Сделать это можно с использованием сниппетов компонентов (дополнений) на которых это все работает: pdoTools и minishop2.
Для этого создаем ресурс с именем yml-feed, ставим опубликован, не отображать в меню, выбираем пустой шаблон. После этого идем на вкладку Настройки — тип содержимого XML, скидываем галки с Доступен для поиска и использовать html-редактор. Потом вписываем туда такую конструкцию:
<?xml version="1.0" encoding="UTF-8"?>
<yml_catalog date="[[timeServer]]" >
<shop>
<name>[[++site_name]]</name>
<company>Название компании</company>
<url>[[++site_url]]</url>
<currencies>
<currency id="RUR" rate="1"/>
</currencies>
<categories>
[[pdoResources? &parents=`2` &depth=`10` &limit=`0` &tpl=`MsCategories`]]
</categories>
<offers>
[[msProducts? &templates=`5` &limit=`0` &parents=`0` &tpl=`MsOffer` &showZeroPrice=`0`]]
</offers>
</shop>
</yml_catalog>
<?xml version="1.0" encoding="UTF-8"?>
<yml_catalog date="{'' | date: 'Y-m-d'}T{'' | date: 'H:i+03:00'}">
<shop>
<name>{$_modx->config.site_name}</name>
<company>Название компании</company>
<url>{$_modx->config.site_url}</url>
<currencies>
<currency id="RUB" rate="1"/>
</currencies>
<categories>
{'pdoResources' | snippet: [ 'parents' => 2, 'depth' => '10', 'limit' => '0', 'tpl' => 'MsCategories' ]}
</categories>
<offers>
{'msProducts' | snippet: [ 'templates' => '5', 'parents' => '0', 'tpl' => 'MsOffer', 'showZeroPrice' => 0 ]}
</offers>
</shop>
</yml_catalog>
Здесь:
[[timeServer]]
— сниппет, который забирает дату с сервера и отображать время файла, содержит следующий код:echo (date("Y-m-d H:i"));
.- Так же в вызове
pdoResources
поменяйте значениеparents
— главная категория товаров, на свое, и в вызовеmsProducts
поменяйте значение вtemplates
на свое (и там и там можно указывать несколько значений через запятую).
Настройка чанков:
Чанк MsCategories
для категорий:
<category id="[[+id]]" [[+parent:is=`2`:then=``:else=`parentId="[[+parent]]"`]]>
[[+pagetitle]]
</category>
<category id="{$id}"{if $parent != 2} parentId="{$parent}"{/if}>{$pagetitle}</category>
Здесь 2
— ID верхнего каталога. Замените его на ID вашего раздела.
Чанк MsOffer
для товаров:
<offer id="[[+id]]">
<url>[[++site_url]][[+uri]]</url>
<price>[[+price:stripString=` `]]</price>
<currencyId>RUR</currencyId>
<categoryId>[[+parent]]</categoryId>
<picture>https://site.ru[[+image]]</picture>
<delivery>true</delivery>
<model>[[+article]]</model>
<name>[[+pagetitle]]</name>
<description>[[+introtext:default=`[[+description]]`]]</description>
<vendor>[[+vendor.name]]</vendor>
</offer>
<offer id="{$id}" available="true">
<url>{$id | url : ['scheme' => 'full']}</url>
<price>{$price | replace : " " : ""}</price>
<currencyId>RUR</currencyId>
<categoryId>{$parent}</categoryId>
<picture>https://site.ru{$image}</picture>
<delivery>true</delivery>
<model>{$article}</model>
<name>{$pagetitle}</name>
<vendor>{$_pls['vendor.name']}</vendor>
<description>{$_modx->resource.introtext ?: $_modx->resource.description}</description>
</offer>
Так же может потребоваться вывести опции товаров из таблиц modx_ms2_product_options
, modx_ms2_options
, для этого можно создать сниппет, к примеру с названием printOptions
:
if(empty($tpl) || !$modx->getChunk($tpl)){
return false;
}
$sQuery = "SELECT
po.value as value,
o.caption as name
FROM
". $modx->getOption('table_prefix') ."ms2_product_options po
LEFT JOIN
". $modx->getOption('table_prefix') ."ms2_options o ON (po.key = o.key)
WHERE
po.product_id = '".$res_id."'";
$result = $modx->query($sQuery);
$res = $result->fetchAll(PDO::FETCH_ASSOC);
$output = "";
foreach($res as $v){
$output .= $modx->getChunk($tpl,$v);
}
echo $output;
Для вывода опций в файл YML, создадим чанк printOptionsTpl
:
<param name="[[+name]]">[[+value]]</param>
Далее вызовите его перед закрытием offer
:
[[!printOptions?&tpl=`printOptionsTpl`&res_id=`[[+id]]`]]
Еще часто валидатор ругается на разные символы, типа &
в названиях, описаниях, поэтому если вы столкнулись с такой ошибкой, создайте сниппет — модификатор:
<?php
$output = str_replace(
array('…', '&', '"', '>', '<', '\''),
array('...', '&', '"', '>', '<', '''),
$input);
return str_replace('&', '&', $output);
Далее примените его к нужным элементам, например: [[+pagetitle:snippet_name]]
или на феном: {$snippet_name | snippet_name}
.
Вариант 2 (сделай сам): для больших сайтов
Если товаров много, используйте PHP-скрипт для генерации YML-файла. Этот способ позволяет писать данные порциями, снижая нагрузку на сервер.
Пример генерации YML через PHP:
<?php
define('MODX_API_MODE', true);
require '/path/to/modx/index.php';
$modx->getService('error', 'error.modError');
$filename = __DIR__ . '/yml.xml';
$offset = 0;
$limit = 500;
// Создаем заголовок файла
if ($offset == 0) {
$header = '<?xml version="1.0" encoding="utf-8"?>
<yml_catalog date="' . date("Y-m-d H:i") . '">
<shop>
<name>' . $modx->getOption('site_name') . '</name>
<company>' . $modx->getOption('site_name') . '</company>
<url>' . $modx->getOption('site_url') . '</url>
<currencies><currency id="RUR" rate="1"/></currencies>
<categories>' . $modx->runSnippet('pdoResources', ['tpl' => 'MsCategories']) . '</categories>
<offers>';
file_put_contents($filename, $header);
}
// Добавляем товары порциями
$products = $modx->runSnippet('msProducts', [
'offset' => $offset,
'limit' => $limit,
'tpl' => 'MsOffer',
]);
file_put_contents($filename, $products, FILE_APPEND);
// Закрываем файл
if ($end) {
$footer = '</offers></shop></yml_catalog>';
file_put_contents($filename, $footer, FILE_APPEND);
}
?>
Для автоматического обновления настройте CRON:
0 3 * * * php /path/to/generate_yml.php
Скрипт накидал на коленке, ради образца, работоспособность не проверял!
Так же подобный скрипт с описаниями можно найти на сайте Ильи.
Готовые дополнения
Готовых компонентов знаю несколько:
- msImportExport — Импорт/экспорт документов Modx и miniShop2, может делать фиды Yandex.Market для DBS модели.
- YandexMarket2 — выгрузка предложений в XML для Яндекс Маркет и не только. Автор данного дополнения с недавних пор сделал его бесплатным + судя по описанию данный модуль поддерживает интеграцию с компонентом msOptionsPrice2 и работает с MODX 3.
- modxYMLprice — предназначен дла генерации XML прайса в формате Yandex YML.
Конкретно для генерации YML я не один не использовал (делаю их руками), кто воспользуется каким то из этих решений отпишитесь о своем опыте.
Проверка валидации и прочая полезная информация
После генерации проверьте файл через валидатор Яндекс.Вебмастер.
Так же скорее всего вам пригодиться документация:
Требования к YML-фиду;
Все элементы, входящие в offer
в произвольном типе. Форматы YML, CSV;
Поиск для интернет-магазинов на основе данного фида.
Заключение
С помощью описанных шагов можно создать YML-файл для Яндекс.Маркета в MODX Revo с MiniShop2 без дополнительных затрат. Вы можете адаптировать этот метод под свою структуру каталога и расширять функционал по мере необходимости.