В данной статье мы поговорим о внедрении микроразметки Schema.Org (с помощью модуля) в самое популярное платное типовое решение Маркета 1С-Битрикс среди интернет-магазинов (по состоянию на 23 июля) - Крутойшоп от АСПРО ( http://marketplace.1c-bitrix.ru/solutions/aspro.kshop/).
Внедрение производилось на версию магазина 1.0.28.
Внедрение проходило практически сразу после того как мне довелось внедрить микроразметку в TopShop, так что есть с чем сравнивать.
Во-первых, я хотел бы высказать своё личное впечатление от данного типового решения. CCatalogMeasure::getList и CIBlockElement::GetList в ШАБЛОНЕ компонента - это по-моему мнению зло если и не абсолютное, то уж очень к оному близкое.
Во-вторых, важно понимать, что несмотря на то что лично мне решение показалось чудовищной кашей, но тот громадный функционал, которое оно предоставляет пользователю (и то огромное количество позитивных отзывов и платных установок, что мы видим в маркете) явно говорит нам о том насколько решение востребовано.
Поэтому отбросим в сторону снобизм, закатаем рукава и займёмся своей задачей - микроразметкой.
Начнём с того, что есть 2 вида задач микроразметки:
- Статические (1 раз положили компонент на страницу или в шаблон, настроили, заполнив параметры компонента, наслуждаемся)
- Динамические (компонент должен использоваться в динамически формирующихся страницах, включая те, которые ещё не созданы, например новости и товары. Компонент должен принимать на вход данные из других компонентов/шаблонов и корректно их выводить. Должны обрабатываться ситуации, если каких-то данных нет)
Очевидно, что реализация статической микроразметки проще, поэтому мы начнём с неё, а потом полученные знания будем использоват ьв том числе в динамической микроразметке.
Статическая микроразметка
Адрес организации и Хлебные крошки
Наиболее подходящее место для размещение статической микроразметки - одна из включаемых областей шаблона. Так разместив 1 раз компоненты мы отобразим их на всём сайте.
Идеально подойдёт включаемая область с копирайтом в подвале сайта:
Включаем режим правки в публичной части, наводим курсор мыши на область, видим появление конктекстного меню как на скриншоте выше, нажимаем кнопку "редактировать как html".
Адрес файла включаемой области (для опытных пользователей) - /include/copyright.php
В открывшееся окно разделено на 2 части: левую рабочую область и правую панель компонентов. В Правой области в списке компонентов выбираем пункт "Компоненты Кофе-Дизайн", внутри "schema.org" и в открывшемся списке выбираем нужные нам компоненты Адреса и Хлебных Крошек. Перетаскиваем мышью компоненты из правой области компонентов в левую рабочую:
При двойном нажатии на компоненте откроется диалог редактирования параметров, в котором нам необходимо будет настроить оба компонента:
Для заполнения параметров компонента воспользуемся документацией (обратим внимание на выделенные красными значками пункты - они обязательны для заполнения):
- Спецификация и документация для Адреса (заполняем все поля, какие сочтём нужным. Кашу маслом не испортишь, как не испортишь сайт микроразметкой)
- Документация для Хлебных крошек (ничего особенного, компонент выводит данные автоматически, нужно лишь проверить правильность формирования цепочки, которая генерируется на основе файловой структуры и данных от компонентов на странице).
После настройки компонентов добавляем галочку "Не отображать на сайте":
Она добавит компоненту параметр:
"SHOW" => "Y",
Это универсальный параметр, имеющийся у всех компонентом модуля "Микроразметка Schema.org". Значение Y говорит компоненту, что параметр не следует показывать обычным пользователям, но отдавать поисковым системам. Это позволяет вписать компонент в любой сайт без изменения его внешнего вида.
Микроразметка Адреса и Хлебных крошек готова.
Динамическая микроразметка
Как уже было сказано выше, динамическая микроразметка формируется автоматически на основании данных, передаваемых другими компонентами, это значит, что нам придётся поработать с исходным кодом шаблонов компонентов.
Схема действий всегда будет одинаковой:
- Берём пустую страницу (например создаём её в административной разделе) и открываем в визуальном редакторе;
- Размещаем на странице компонент микроразметки (аналогично тому как выше сделано для Адреса);
- Заполняем те параметры, которые в дальнейшем будут нами использоваться в динамическом компоненте, статическими заглушками (например #NAME# для параметра с названием товара, #PRICE# для цены и т.д.);
-
Переключаемся в режим исходного кода для получения кода вызова компонента с нашими заглушками (см скриншот ниже);
- Находим шаблон компонента, отвечающего за вывод в публичной части той сущности, которую мы хотим разметить (например, детальной страницы товара), копируем его (иначе наша правка может быть затёрта при обновлении решения) и открываем копию для редактирования в режиме php;
- Выбираем место для вставки вызова нашего компонента;
- Используя отладочный код (выводится незаметно для пользователей, так что не забываем в отладчике убирать
display:none
, а после завершения работ убрать отладку):
<div style="display:none;">
<? echo "<pre>"; print_r($arResult); echo "</pre>";?>
</div>
Выводим массив с данными компонента. Выбираем те ключи, которые содержат интересующие нас данные (например, название товара или его цену); - Заменяем заглушку (#NAME#, #PRICE# и т.д.) на переменные с данными, использующимися шаблоном.
Товары и Цены
Зайдём в детальную страницу товара и в режиме редактирования нажимаем на стрелочку рядом с шестерёнкой, вызывающей параметры компонента над областью товара: получаем список компонентов, среди которых мы видим компоненты Каталога и Элемента Каталога Детально, это даёт нам понять, что в решении используется комплексный компонент каталога (внутри которого уже вызываются компоненты списка элементов каталога, детальной, фильтра и т.п.).
Рекомендуется скопировать шаблон перед внесением в него правок. Для этого скопируйте шаблон комплексного компонента "Каталог" (шаблон элемент каталога детально скопируется вместе с ним). Иначе комплексный компонент не будет знать о вашем кастомном компоненте детальной.
В нашем случае путь в шаблону компонента Элемент Каталога Детально будет выглядеть /bitrix/templates/aspro_kshop/components/bitrix/catalog.element/main_ito_15/
- Зелёным - название шаблона сайта
- Оранжевый - название компонента (Элемент каталога Детально)
- Синий - название шаблона компонента
В процессе изучения решения было выявлено несколько видов товаров:
- 1 товар с 1 ценой и валютой
- 1 товар с несколькими товарными предложениями (в поле PRICE основного товара стоит минимальная цена одного из товарных предложений, валюта основного товара указана)
- 1 товар с несколькими товарными предложениями (в поле PRICE основного товара стоит НЕ минимальная цена одного из товарных предложений, валюта основного товара НЕ указана)
При этом у товара есть такой массив данных (в свойствах), как MINIMUM_PRICE. Валюты товарных предложений указаны всегда.
Наличие товара и товарных предложений рассчитывается по следующей формуле:
- 1 товар "в наличии", если его остаток больше 0.
- 1 товар "в наличии", если сумма его товарных предложений больше 0.
- 1 товара "нет на складе", если его остаток 0, и сумма остатков его товарных предложений равна 0.
- Товарное предложение "в наличии", если его остаток больше 0.
- Товарного предложения "нет на складе", если его остаток 0.
Способы оплаты всегда фиксированы.
Рейтинг может быть, а может отсутствовать. Однако в массиве хранятся только суммарная оценка и количество голосов! Это означает, что среднюю оценку всегда необходимо вычислять (делить сумму баллов на число голосов).
К сожалению, это означает, что нам необходимо провести небольшую обработку данных. Для этого мы воспользуемся файлом /bitrix/templates/aspro_kshop/components/bitrix/catalog.element/main_ito_15/result_modifier.php шаблона компонента. Код, который в него будет помещён элементарен для разработчика (заранее извиняюсь перед бывалыми за мой code-style), однако боюсь даже с моими пояснениями будет абсолютно бесполезен для "не программистов". Прошу прощения. Вы можете воспользоваться моей наработкой "как есть", но не забудьте сперва сделать резервную копию!
Добавим в конце:
<?// Schema.Org START
$SchemaOrgRATINGVALUE = $arResult['PROPERTIES']['vote_sum']['VALUE']/$arResult['PROPERTIES']['vote_count']['VALUE'];
$arResult["SchemaOrg"]["RATINGVALUE"] = $SchemaOrgRATINGVALUE;
$totalCount = CKShop::GetTotalCount($arResult);
if ($totalCount=="0"){
$SchemaOrgITEMAVAILABILITY = "OutOfStock";
}
else {
$SchemaOrgITEMAVAILABILITY = "InStock";
}
$arResult["SchemaOrg"]["ITEMAVAILABILITY"] = $SchemaOrgITEMAVAILABILITY ;
if (!empty($arResult['OFFERS'])) {
$arResult["SchemaOrg"]["AGGREGATEOFFER"] = "Y";
$arResult["SchemaOrg"]["LOWPRICE"] = $arResult["PROPERTIES"]["MINIMUM_PRICE"]["VALUE"];
foreach($arResult["OFFERS"] as $key => $offer)
{
$arResult["SchemaOrg"]["AGGREGATEOFFER_PRICE"][$key] = $offer["CATALOG_PRICE_1"];
$arResult["SchemaOrg"]["AGGREGATEOFFER_PRICECURRENCY"][$key] = $arResult["OFFERS"][$key]["CATALOG_CURRENCY_1"];
}
if (empty($arResult['CATALOG_CURRENCY_1']))
{
$arResult["SchemaOrg"]["PRICECURRENCY"] = $arResult["OFFERS"][$key]["CATALOG_CURRENCY_1"];
}
else
{
$arResult["SchemaOrg"]["PRICECURRENCY"] = $arResult["CATALOG_CURRENCY_1"];
}
}
else {
$arResult["SchemaOrg"]["AGGREGATEOFFER"] = "N";
$arResult["SchemaOrg"]["PRICE"] = $arResult['CATALOG_PRICE_1'];
}
// Schema.Org END
?>
Тогда в шаблоне компонента /bitrix/templates/aspro_kshop/components/bitrix/catalog.element/main_ito_15/template.php в конце достаточно будет добавить вызов компонента:
<?$APPLICATION->IncludeComponent( "coffeediz:schema.org.Product",
"",
Array(
"COMPONENT_TEMPLATE" => ".default",
"SHOW" => "Y",
"AGGREGATEOFFER" => $arResult["SchemaOrg"]["AGGREGATEOFFER"],
"NAME" => $arResult['NAME'],
"DESCRIPTION" => $arResult['DETAIL_TEXT'],
"LOWPRICE" => $arResult["SchemaOrg"]["LOWPRICE"],
"AGGREGATEOFFER_PRICE" => $arResult["SchemaOrg"]["AGGREGATEOFFER_PRICE"],
"AGGREGATEOFFER_PRICECURRENCY" => $arResult["SchemaOrg"]["AGGREGATEOFFER_PRICECURRENCY"],
"PRICE" => $arResult["SchemaOrg"]["PRICE"],
"PRICECURRENCY" => $arResult["SchemaOrg"]["PRICECURRENCY"],
"ITEMAVAILABILITY" => $arResult["SchemaOrg"]["ITEMAVAILABILITY"],
"ITEMCONDITION" => "NewCondition",
"PAYMENTMETHOD" => array("VISA", "MasterCard", "ByBankTransferInAdvance", "Cash", "COD"),
"PARAM_RATING_SHOW" => "Y",
"RATING_SHOW" => "Y",
"RATINGVALUE" => $arResult["SchemaOrg"]["RATINGVALUE"],
"RAITINGCOUNT" => $arResult['PROPERTIES']['vote_count']['VALUE'],
"REVIEWCOUNT" => "",
"BESTRATING" => "5",
"WORSTRATING" => "1"
),
false,
array('HIDE_ICONS' => 'Y')
);?>
Изображения (товаров)
В отличие от предыдущего разобранного нами решения TopShop здесь все изображения уже собраны в 1 массив $arImages и мы можем пройти по нему в цикле, выбрав все картинки для микроразметки:
<?foreach($arImages as $i => $arImage){
$APPLICATION->IncludeComponent(
"coffeediz:schema.org.ImageObject",
"",
Array(
"COMPONENT_TEMPLATE" => ".default",
"SHOW" => "Y",
"CONTENTURL" => $arImage["BIG"]["src"],
"NAME" => $arImage["TITLE"],
"CAPTION" => $arImage["TITLE"],
"DESCRIPTION" => $arImage["DESCRIPTION"],
"HEIGHT" => $arImage["BIG"]["heigh"],
"WIDTH" => $arImage["BIG"]["width"],
"TRUMBNAIL_CONTENTURL" => $arImage["SMALL"]["src"],
"ITEMPROP" => "",
"REPRESENTATIVEOFPAGE" => "True",
"PARAM_RATING_SHOW" => "N"
),
false,
array('HIDE_ICONS' => 'Y')
);
}
?>
Заметьте, мы использовали практически все поля микроразметки, включая миниатюту! Уверен, Яндекс и Google будут довольны.
Новости и Статьи
Материалы этих 2 типом использую один и тот же компонент, но расположены в разных разделах:
-
/info/articles/
- /company/news/
Как мы видим, для вывода новостей/статей используется комплексный компонент "Новости", а для детальной страницы "Новость Детально". Скопируем комплексный компонент (по аналогии с комплексным компонентом каталога в предыдущем разделе).
Перейдём к редактированию шаблона компонента новости детально:
В нашем случае это будет файл /bitrix/templates/aspro_kshop/components/bitrix/news.detail/main_template/template.php
Добавим в конце шаблона вызов компонента микроразметки "Статья", поставив для всех интересующих нас параметров переменные, содержащие нужные нам данные (по аналогии с товаром, используя отладочный вывод массива данных):
<?$APPLICATION->IncludeComponent( "coffeediz:schema.org.Article",
"",
Array(
"COMPONENT_TEMPLATE" => ".default",
"SHOW" => "Y",
"TYPE" => "",
"LEARNING_RESOURCE_TYPE" => "",
"NAME" => $arResult['NAME'],
"ARTICLEBODY" => $arResult['DETAIL_TEXT'],
"ABOUT" => $arResult['PREVIEW_TEXT'],
"GENRE" => "",
"ARTICLE_SECTION" => array(""),
"KEYWORDS" => array(""),
"IN_LANGUAGE" => "ru",
"DATA_PUBLISHED" => "",
"AUTHOR_TYPE" => "",
"IMAGEURL" => $arResult['DETAIL_PICTURE']['SRC'],
"PARAM_RATING_SHOW" => "N",
"IMAGE_NAME" => $arResult['DETAIL_PICTURE']['TITLE'],
"IMAGE_CAPTION" => $arResult['DETAIL_PICTURE']['TITLE'],
"IMAGE_DESCRIPTION" => $arResult['DETAIL_PICTURE']['TITLE'],
"IMAGE_HEIGHT" => $arResult['DETAIL_PICTURE']['HEIGHT'],
"IMAGE_WIDTH" => $arResult['DETAIL_PICTURE']['WIDTH'],
"IMAGE_TRUMBNAIL_CONTENTURL" => ""
)
);?>
Обратите внимание, в отличие от решения TopShop мы не выводим ДАТУ публикации. Это очень важное свойство (его наличие требуется для НОВОСТЕЙ, хотя и не обязательно для статей). Однако, к сожалению, дата уже выводится в публичной части и нам пришлось бы переформировать её запись в result_modifier.php, что добавило бы сложности и работы.
Заключение
В данной статей было описано полное внедрение универсальных типов микроразметки Schema.Org в типовое решение "Крутойшоп" от АСПРО 5 видов:
- Хлебные крошки (Data-Vocabulary.org/Breadcrumb), только для Google
- Адрес организации и контакты (schema.org/Organization), для Google и Яндекс
- Изображения товаров (schema.org/ImageObject), для Яндекс.Картинок и Google.Изображений
- Статьи (schema.org/Article), в первую очередь для Яндекса. Для Статей и Новостей.
- Товары с товарными предложениями, ценами и рейтингом (schema.org/Product), для Google и Яндекс (но с учётом того, что если вы выгружаете YML для Яндекс.Маркета, то он получит приоритет перед микроразметкой!)
Теперь на любой странице сайта могут встречаться от 2 до 4 типов микроразметки одновременной в зависимости от её контента. Это значительно увеличит шансы на красивый и привлекательный сниппет в поисковой выдаче для сайта!