Уникальная СЕО информация для каждого торгового предложения в каталоге 1С-Битрикс

Просмотров: 2862

Задача: реализовать уникальную мета-информацию для каждого SKU в каталоге. У каждого ТП должны быть свои: заголовок h1, ключевые слова, описание страницы, заголовок окна браузера и канонический адрес.

Это продолжение заметки Уникальный URL для торговых предложений.

Смена заголовка h1 при выборе SKU

Для начала реализуем смену заголовка товара для пользователя. Чтобы при выборе конкретного SKU в h1 подставлялось название предложения, вместо названия основного товара.

Модифицируем функцию переключения SKU selectOfferProp: function () до вот такого вида.

selectOfferProp: function () {
	var i = 0,
		strTreeValue = '',
		arTreeItem = [],
		rowItems = null,
		target = BX.proxy_context,
		smallCardItem;

	if (target && target.hasAttribute('data-treevalue')) {
		if (BX.hasClass(target, 'selected'))
			return;

		if (typeof document.activeElement === 'object') {
			document.activeElement.blur();
		}

		// start CUSTOM
		var skuId = this.offers[this.offerNum]['ID'];
		// end CUSTOM

		strTreeValue = target.getAttribute('data-treevalue');
		arTreeItem = strTreeValue.split('_');
		this.searchOfferPropIndex(arTreeItem[0], arTreeItem[1]);

		rowItems = BX.findChildren(target.parentNode, {
			tagName: 'li'
		}, false);

		if (rowItems && rowItems.length) {
			for (i = 0; i < rowItems.length; i++) {
				BX.removeClass(rowItems[i], 'selected');
			}
			// start CUSTOM
			var currentUrl = window.location.href;
			var newUrl = currentUrl.replace('?offer=' + skuId, '');
			window.history.replaceState(null, null, newUrl);
			// end CUSTOM
		}

		BX.addClass(target, 'selected');

		// start CUSTOM
		var skuId = this.offers[this.offerNum]['ID'];
		var newUrl = window.location.pathname + '?offer=' + skuId;
		window.history.pushState('', '', newUrl);

		// console.log(JSON.stringify(this.offers))
		// Смена h1
		document.getElementById("pagetitle").innerHTML = this.offers[this.offerNum]['NAME'];
		// end CUSTOM

		if (this.smallCardNodes.panel) {
			smallCardItem = this.smallCardNodes.panel.querySelector('[data-treevalue="' + strTreeValue + '"]');
			if (smallCardItem) {
				rowItems = this.smallCardNodes.panel.querySelectorAll('[data-sku-line="' + smallCardItem.getAttribute('data-sku-line') + '"]');
				for (i = 0; i < rowItems.length; i++) {
					rowItems[i].style.display = 'none';
				}

				smallCardItem.style.display = '';
			}
		}

		if (
			this.isFacebookConversionCustomizeProductEventEnabled &&
			BX.Type.isArrayFilled(this.offers) &&
			BX.Type.isObject(this.offers[this.offerNum])
		) {
			BX.ajax.runAction(
				'sale.facebookconversion.customizeProduct', {
					data: {
						offerId: this.offers[this.offerNum]['ID']
					}
				}
			);
		}
	}
},

Относительно первой заметки здесь изменения:

  • Вместо подмены ссылки, на SKU, вида ССЫЛКА_НА_ТОВАР/ID-SKU/ сделали ССЫЛКА_НА_ТОВАР/?offer=ID-SKU
  • С помощью innerHTML заменяем содержимое тега h1, зная его id. В типовом магазине этот id=pagetitle

Меняем SEO параметры страницы при переходе по прямой ссылке на SKU

Теперь нужно подменять всю нужную информацию, при прямом переходе по ссылке торгового предложения. При этом, нужно оставить функционал штатной установки мета-информации, если открыт основной товар или у товара нет SKU.

В element.php комплексного шаблона компонента, до вывода bitrix:catalog.element, вносим вот такое условие:

if (empty($_REQUEST['offer'])) {
    $arParams['SET_TITLE'] = $arParams['SET_TITLE'];
    $arParams['SET_BROWSER_TITLE'] = $arParams['SET_BROWSER_TITLE'];
    $arParams['SET_META_KEYWORDS'] = $arParams['SET_META_KEYWORDS'];
    $arParams['SET_META_DESCRIPTION'] = $arParams['SET_META_DESCRIPTION'];
    //$arParams['SET_CANONICAL_URL'] = $arParams['SET_CANONICAL_URL'];
} else {
    $arParams['SET_TITLE'] = 'N';
    $arParams['SET_BROWSER_TITLE'] = 'N';
    $arParams['SET_META_KEYWORDS'] = 'N';
    $arParams['SET_META_DESCRIPTION'] = 'N';
    // $arParams['SET_CANONICAL_URL'] = 'N';
}

В component_epilog.php шаблона детальной карточки добавляем:

if (isset($templateData['JS_OBJ'])) {
    ?>
    <script>
        BX.ready(BX.defer(function () {
            if (!!window.) {
                window..allowViewedCount(true);
            }
        }));
    </script>
    <?php
    // select target offer
    $request = Bitrix\Main\Application::getInstance()->getContext()->getRequest();
    $offerNum = false;
    $offerId = (int)$this->request->get('OFFER_ID');
    $offerCode = $this->request->get('OFFER_CODE');
    if (!empty($_REQUEST['offer'])) {
        $offerNum = array_search($_REQUEST['offer'], $templateData['OFFER_IDS']);
        $dbOfferData = CIBlockElement::GetList(
            false,
            array(
                '=ID' => $_REQUEST['offer']
            ),
            false,
            array(
                'nTopCount' => 1
            ),
            array(
                'NAME',
                'IBLOCK_ID',
                'CANONICAL_PAGE_URL'
            )
        )->GetNext();
        $dbOfferSeoProps = new \Bitrix\Iblock\InheritedProperty\ElementValues(
            $dbOfferData['IBLOCK_ID'], // ID инфоблока с ТП
            $_REQUEST['offer'] // ID элемента
        );
        $arOfferSeoProps = $dbOfferSeoProps->getValues();
        $APPLICATION->SetTitle($dbOfferData['NAME']);
        $APPLICATION->SetPageProperty("title", $arOfferSeoProps['ELEMENT_META_TITLE']);
        $APPLICATION->SetPageProperty("keywords", $arOfferSeoProps['ELEMENT_META_KEYWORDS']);
        $APPLICATION->SetPageProperty("description", $arOfferSeoProps['ELEMENT_META_DESCRIPTION']);
        $APPLICATION->SetPageProperty("canonical", $dbOfferData['CANONICAL_PAGE_URL']);
    } else {
        $offerNum = 0;
    }
    ?>
    <script>
        BX.ready(function () {
            if (!!window.) {
                window..setOffer();
            }
        });
    </script>
    <?php
}
  • С помощью CIBlockElement::GetList получили название и канонический URL выбранного ТП
  • С помощью Bitrix\Iblock\InheritedProperty\ElementValues получили SEO параметры этого ТП
  • C помощью $APPLICATION->SetPageProperty установили все нужные SEO параметры для страницы и заголовок h1.
  • Использовали window..setOffer(⁠); для выбора предложения из GET параметра

В настройках инфоблока торговых предложений устанавливаем настройки для URL (включая канонический).

Уникальная СЕО информация для каждого торгового предложения в каталоге 1С-Битрикс

Видео: СЕО информация для каждого торгового предложения

Полная версия видео на моем Boosty канале

Михаил Базаров 29.04.2023
Для компонента bitrix:catalog.element в element.php, не забудте установить параметры
Код
 
"SET_TITLE" => $arParams['SET_TITLE'],
"SET_BROWSER_TITLE" => $arParams['SET_BROWSER_TITLE'],
"SET_META_KEYWORDS" => $arParams['SET_META_KEYWORDS'],
"SET_META_DESCRIPTION" => $arParams['SET_META_DESCRIPTION'],
Алексей 29.09.2023
Михаил, добрый день.
Подскажите пожалуйста, все работает отлично, все SEO данные срабатывают, тег H1 - корректен (соответствует торговому предложению), НО при открытии скопированной ссылки с торговым предложением в новом окне (у "Друга") данные  выводятся по умолчанию (SEO данные верные), а не те , которые должны быть (((
Как передать данные с нужными свойствами ТП при открытии ссылки в новом окне?  Все СЕО данные верные, а контент с ценой, соответствующий данному ТП не тот, не передается почему то.
Заранее спасибо за ответ.
Михаил Базаров 29.09.2023
Точно ни чего не упущено по заметке и видео?
Вот тут приложен шаблон, с учетом этих работ.
https://bazarow.ru/video/video2023/braynycp20-04/
Вот так работает:
https://bxstore.ru/catalog/iphone/apple_iphone_14_pro/?offer=1556
Все сделано по этой заметке
Гость 29.09.2023
Вроде все правильно...  Буду разбираться... по твоему шаблону.
Скажи пожалуйста как в принципе передается информация конкретного ТП в URL +(?offer=)  в новом окне?
Как передаются SEO данные вроде ясно, а вот сами данные конкретного ТП ?
Нужна ли 404.php как в первом видео без СЕО  для этого?

Блог-note: заметки разработчика

Изменить размер картинок на лету в битрикс

Встала задачка: на собственном сайте, уменьшить размер превьюшек картинок у анонсов раздела дизайн. Само собой, перезали...

Установить остатки товара на складе из доступных остатков.

Задача, заполнить остатки товаров, в 1С-Битрикс, из параметра "Доступное количество".

Создание локальных уведомлений для приложения на Apache Cordova

Задача состоит в том, чтобы реализовать возможность локальных уведомлений в приложении на Apache Cordova без использован...

Правильное подключение стилей и скриптов в Битрикс

Есть несколько способов подключения файлов стилей и скриптов, при верстке шаблонов в системе управления 1С-Битрикс. Если...

Вывести товары из того же раздела в карточке товара

Немножко топорный, но все же вполне действенный способ по выводу внутри подробной карточки товара, элементов того же раз...

Добавить свойство в административную форму заказа

Задача, кастомизировать административную форму заказа: добавить свойство заказа в шапку формы, в виде картинки. На сайте...

Фильтрация разделов каталога с помощью умного фильтра

Задача: В каталоге выводится умный фильтр, нужно сделать так чтобы он применялся не только к товарам но и к компоненту &...

Получить все товары из всех заказов пользователя. История купленных товаров.

Задача: нужно создать раздел, в персональном разделе пользователя, с историей всех купленных товаров. Не путать с истори...

Cordova, ввод в input под диктовку. Голосовой поиск в мобильном приложении.

Итак, задачка: реализовать голосовой поиск в мобильном приложении на Cordova. По сути, нам нужно захватить речь с микроф...