Сталин пусть Москву защищает, а ты руль держи. Ясно?
(Корнилов Владимир Николаевич "Девочки и дамочки")
+7(910)140-50-90 (Кэп)

YML для староверов MODx Evolution

Задача: создать файл фида для сайта на MODx Evo и загрузить его в Маркет. Ну или отправить менеджеру Яндекса, который это сделает.

Впервые я столкнулся с задачей генерации фидов для контекстной рекламы Гугл и Яндекс в 2018 году. Это были огромные каталоги дистрибьюторов Schneider Electric из тысяч товаров.

Сложность вызвало формирование utm-меток, пришлось переписываться по этому поводу с Яндексом и несколько раз менять техзадание.

В данной публикации я не буду концентрировать внимание на формировании урлов товарных позиций, важнее реализация. Детали можно будет дорабатывать и допиливать как угодно.

Рассмотрю вариант формирования фида в относительно свежих версиях MODx Evolution 1.4.11 — 1.4.19, где есть сниппет DLSitemap. Мне эта штука понравилась, когда решал задачку создания умной xml-карты сайта.

  1. Сначала создаем документ yml1 с пустым шаблоном blank типа text/xml.

    Создаём новый документ типа xml с пустым шаблоном

  2. Смотрим, что у наc за каталог, какой у него уровень вложенности. В моем примере корневая папка каталога имеет id=22, структура простейшая: есть категории и товары. Далее я подскажу, что изменится, если уровней вложенности больше. Важно, что в фиде есть раздел категорий (categories) и самих товаров (offers).

    Структура каталога

  3. Создаём tv-параметр типа CheckBox со значением по умолчанию 0 и присваиваем его всем шаблонам товаров и категорий. Идея в том, что это позволит исключить любой товар или категорию из фида.

    tv-параметр типа CheckBox

    Не включать в фид

  4. Готовим чанки-шаблоны для строчек фида.

    yml-category:

    <category id="[+id+]">[+pagetitle+]</category>
    

    Для случая, когда в категорию вложены подкатегории, и уже в подкатегориях находятся товары (но тогда и код сниппета ниже нужно будет корректировать делать еще один блок фида с подкатегориями и увеличивать параметр уровня вложенности при вызове сниппета DocLister для блока offers ):

    <category id="[+id+]" parentId="[+parent+]">[+pagetitle+]</category>
    

    yml-offer (не забудьте подставить в код свой домен вместо capweb.ru):

    <offer id="[+id+]" available="true">
    	<name>[+pagetitle+]</name>
    	<url>https://capweb.ru[(base_url)][~[+id+]~]/?from=ya_market&utm_source=ya_market&utm_medium=cpc&utm_campaign=[!getparenttitle? &gid=[+id+]!]&utm_term=[+id+]</url>
    	<price>[+tv.price+]</price>
    	<currencyId>RUB</currencyId>
    	<categoryId>[+parent+]</categoryId>
    	<param name="Базовый цвет">[+tv.product_color+]</param>
    	<param name="Базовый размер">[+tv.product_size+]</param>
    	<manufacturer_warranty>true</manufacturer_warranty>
    	<delivery>true</delivery>
    	<pickup>true</pickup>
    	<store>true</store>
    	<picture>https://capweb.ru/[+tv.image+]</picture>
    	<description>[+tv.metaDescription+]</description>
    </offer>
    

    Для работы этого tpl понадобится создать и простенький сниппет getparenttitle, получающий pagetitle родительского ресурса. Я решил, что такое значение метки будет наглядным и полезным, хотя можно вместо этого использовать просто id родителя [+parent+].

    Код сниппета getparenttitle:

    <?php
    $gid = (isset($gid)) ? $gid : '24';
    $parent = $modx->getParent($gid,1,'pagetitle');
    return $parent['pagetitle'];
    

    Заметьте, в этом варианте url каждого товара имеет utm-метки, из-за чего код фида становится невалидным. Можно попробовать заменить знак амперcанда на &amp;. Можно просто удалить utm-метки из чанка-шаблона.

    Важно! Ваши tv-параметры для шаблона товаров отличаются от приведенных выше, поэтому после выполнения всех шагов данной инструкции рекомендую вернуться в этот tpl под названием yml-offer, редактировать имена tv и смотреть на конечный результат в виде исходного кода сгенерированного xml-файла. Значения параметров должны подхватываться корректно.

  5. Делаем измененную копию сниппета DLSitemap — DLSitemap1 с приведённым ниже кодом (не забудьте вставить адрес своего сайта вместо capweb.ru, свой email.

    <?php
    include_once(MODX_BASE_PATH . 'assets/lib/APIHelpers.class.php');
    
    if (!isset($params['config'])) {
        $params['config'] = 'sitemap:core';
    }
    
    /// Additional params
    
    //$params['addWhereList'] = 'c.type IN ("document") AND c.id NOT IN (3321,3065,3066,3220,33,41,31,43,3283,3293,3030,3031,38,39,23,3052,3196)';
    
    
    //$allChildren_ul = implode(',',$modx->getChildIds(32, 1));
    //$allChildren_ul_cin = ' AND c.id NOT IN ('.$allChildren_ul.')';
    //$params['addWhereList'] = $params['addWhereList'].$allChildren_ul_cin;
    
    $params['addWhereList'] = 'c.type IN ("document")'; // Это выбор документов
    $allChildren_ul = implode(',',$modx->getChildIds(22, 2)); // Каталог, уровень вложенности 2
    
    $allChildren_ul_cin = ' AND c.id IN ('.$allChildren_ul.')';
    $params['addWhereList'] = $params['addWhereList'].$allChildren_ul_cin;
    
    //////////////
    $out = $modx->runSnippet('DocLister', $params);
    
    
    /////
    $params1['parents'] = 22;
    $params1['depth'] = 0;
    $params1['tpl'] = 'yml-category';
    $params1['tvList'] = 'no-yml';
    $params1['addWhereList'] = 'c.isfolder IN ("1")'; // AND no-yml IN ("0") AND no-yml NOT IN ("1") AND tv.no-yml NOTIN ("1")
    $params1['filters']='tv:no-yml:notin:1'; // content:c.id:notin:0; notin:1 AND(tv:no-yml:0)
    $params1['sortBy']=`docid`;
    $params1['sortDir']='ASC';
    
    $categories = $modx->runSnippet('DocLister', $params1);
    
    $params2['parents'] = 22;
    $params2['depth'] = 1;
    $params2['tpl'] = 'yml-offer';
    $params2['tvList'] = 'no-yml,price,product_color,product_size,about_text,image,metaDescription';
    $params2['addWhereList'] = 'c.isfolder IN ("0")'; // AND no-yml IN ("0") AND no-yml NOT IN ("1") AND tv.no-yml NOTIN ("1")
    $params2['filters']='tv:no-yml:notin:1';
    $params2['sortBy']=`docid`;
    $params2['sortDir']='ASC';
    
    $offers = $modx->runSnippet('DocLister', $params2);
    
    if (!empty($out)) {
        $out = "<?xml version=\"1.0\" encoding=\"{$modx->config['modx_charset']}\"?>
    	<yml_catalog date=\"".date('Y-m-d H:i')."\">	
    	<shop>
            <name>[(site_name)]</name>
            <company>[(client_company_name)]</company>
            <url>https://capweb.ru</url>
            <platform>MODx</platform>
            <version>1.0</version>
            <email>capweb@mail.ru</email>
    		<local_delivery_cost>0</local_delivery_cost>
    <currencies>
    <currency id=\"RUB\" rate=\"1\"/>
    </currencies>
    <categories>
    		{$categories}</categories>
    	<offers>
    	{$offers}</offers>
    	</shop>
    </yml_catalog>";
    }
    return $out;
    
    
    
  6. Остается лишь вызвать созданный сниппет DLSitemap1 из области контента пустого документа yml1.

    Вызов сниппета DLSitemap1

Признаю, что можно было не упоминать DLSitemap всуе, а просто назвать сниппет произвольным именем.

Закомментированные и некоторые лишние строки не удалил, чтобы видно было ход мысли.

Вот и всё, и, чтобы эта статья была чуть побольше, приведу ссылку на другую публикацию: Полезные книги по маркетингу

Данный рецепт подходит и для Evolution, и для Revolution, но для Revo придется переписывать коды на язык этого движка. Sapienti sat.

Ответственный за этот не очень удобочитаемый контент — Сергей. Если что-то не получается, пишите, контакты тут.

Спасибо за внимание всем роботам и людям, да, и тебе (Вам, если требуется более официальное обращение) в том числе, дочитавшим до этой строки.

Следующая статья: Как запилить более 10 сайтов на бесплатной версии ISP Manager https://capweb.ru/kak-zapilit-bolee-10-sajtov-na-isp-manager.html

Предыдущая статья: MODx: решение проблемы 1970. Форматирование дат по-русски. https://capweb.ru/modx-01-01-1970.html

Позиции сайта ООО Дека-НН на начало 2015 года
Позиции сайта veragold.ru на декабрь 2014 г.
reative
nalytics
romotion

Оставьте Вашу контактную информацию, и мы свяжемся с Вами!

Получайте горячие новости интернет-маркетинга и вечную скидку 5%!