Битрикс. Простой горизонтальный сео-шаблонизатор для интернет-магазина
Rus
Eng
Битрикс. Простой горизонтальный сео-шаблонизатор для интернет-магазина

Выводим кастомные Title, H1, Description и произвольный Text на страницах списка товаров разделов

Зададим отдельные шаблоны замены в HL блоке. В каждой записи будет храниться название и правило замены. В названии мы закодируем тип замены и уровень срабатывания. Выглядит это примерно так

Предусмотрим следующие паттерны замены

#CURRENT_SECTION_NAME# - Название текущего уровня каталога
#FIRST_LEVEL_SECTION_NAME# - Название каталога первого уровня
#SECOND_LEVEL_SECTION_NAME# - Название каталога второго уровня
#THIRD_LEVEL_SECTION_NAME# - Название каталога третьего уровня
#BRAND_SECTION_NAME# - Название каталога четвертого уровня
#MIN_PRICE# - Минимальная цена товара в текущем разделе
#SHOP_NAME# - Название магазина ("каталог интернет-магазина Ваше название")

Получаем данные. Например в init.php в событии OnPageStart

global $SEO;

if (Loader::includeModule("highloadblock")){
	$cntIBLOCK_List = 'seoTemplates';

	$cache = new CPHPCache();
	$cache_time = 3600*12*360; //кеш на год
	$cache_id = 'seo'.$cntIBLOCK_List;
	$cache_path = 'seo';
	if ($cache_time > 0 && $cache->InitCache($cache_time, $cache_id, $cache_path))
	{
		$res = $cache->GetVars();
		if (is_array($res["seo"]) && (count($res["seo"]) > 0)){
			$SEO = $res["seo"];
		}
		$SEO['CACHE']='true';

	}
	if (!is_array($SEO))
	{
		$SEO['CACHE']='false';

		$hlblock = HL\HighloadBlockTable::getById(4)->fetch();

		$entity = HL\HighloadBlockTable::compileEntity($hlblock);
		$entity_data_class = $entity->getDataClass();

		$data = $entity_data_class::getList(array(
			"select" => array("*"),
			"order" => array("ID" => "DESC"),
			//"filter" => array("UF_FIELD_1"=>"Значение 1","UF_FIELD_2"=>'Значение 2',"UF_FIELD_3"=>'Значение 3') //Фильтрация выборки
		));

		while($arData = $data->Fetch()){
			$SEO['TEMPLATES'][$arData['UF_TITLE']] = $arData;
		}

		//////////// end cache /////////
		if ($cache_time > 0)
		{
			$cache->StartDataCache($cache_time, $cache_id, $cache_path);
			$cache->EndDataCache(array("seo"=>$SEO));
		}
	}
}

По условию задачи наш шаблонизатор должен действовать только на страницах со списком товаров. Для этого ищем шаблон вашего компонента catalog.section в котором считаем, что у нас уже есть массив похожих данных:

Array
(
    [PATH] => Array
        (
            [0] => Array
                (
                    [ID] => 261
                    [~ID] => 261
                    [IBLOCK_ID] => 15
                    [~IBLOCK_ID] => 15
                    [IBLOCK_SECTION_ID] => 
                    [~IBLOCK_SECTION_ID] => 
                    [NAME] => Груза и джиги
                    [~NAME] => Груза и джиги
                    [DEPTH_LEVEL] => 1
                    [~DEPTH_LEVEL] => 1
                    [IPROPERTY_VALUES] => Array
                        (
                            [ELEMENT_META_TITLE] => TITLE
                            [SECTION_META_TITLE] => TITLE
                            [ELEMENT_META_DESCRIPTION] => DESCRIPTION
                            [SECTION_META_DESCRIPTION] => DESCRIPTION
                            [SECTION_PAGE_TITLE] => TITLE
                            [ELEMENT_META_KEYWORDS] => KEYWORDS
                        )

                )

            [1] => Array
                (
                    [ID] => 262
                    [~ID] => 262
                    [IBLOCK_ID] => 15
                    [~IBLOCK_ID] => 15
                    [IBLOCK_SECTION_ID] => 261
                    [~IBLOCK_SECTION_ID] => 261
                    [NAME] => Аксессуары и оснастка
                    [~NAME] => Аксессуары и оснастка
                    [DEPTH_LEVEL] => 2
                    [~DEPTH_LEVEL] => 2
                    [IPROPERTY_VALUES] => Array
                        (
                            [ELEMENT_META_TITLE] => TITLE
                            [SECTION_META_TITLE] => TITLE
                            [ELEMENT_META_DESCRIPTION] => DESCRIPTION
                            [SECTION_META_DESCRIPTION] => DESCRIPTION
                            [SECTION_PAGE_TITLE] => TITLE
                            [ELEMENT_META_KEYWORDS] => KEYWORDS
                        )

                )

            [2] => Array
                (
                    [ID] => 2238
                    [~ID] => 2238
                    [IBLOCK_ID] => 15
                    [~IBLOCK_ID] => 15
                    [IBLOCK_SECTION_ID] => 262
                    [~IBLOCK_SECTION_ID] => 262
                    [NAME] => Strike Pro
                    [~NAME] => Strike Pro
                    [DEPTH_LEVEL] => 3
                    [~DEPTH_LEVEL] => 3
                    [IPROPERTY_VALUES] => Array
                        (
                            [ELEMENT_META_TITLE] => TITLE
                            [SECTION_META_TITLE] => TITLE
                            [ELEMENT_META_DESCRIPTION] => DESCRIPTION
                            [SECTION_META_DESCRIPTION] => DESCRIPTION
                            [SECTION_PAGE_TITLE] => TITLE
                            [ELEMENT_META_KEYWORDS] => KEYWORDS
                        )

                )

        )

)

Добавляем или редактируем файл component_epilog.php

global $SEO,$cacheName;

$key = array_key_last($arResult['PATH']);

$cacheName = 'SEO'.$arResult['PATH'][$key]['IBLOCK_SECTION_ID'];
$arSEO = getFromCache($cacheName);

if($cacheName){
	$frame = new \Bitrix\Main\Page\FrameHelper('sectionSEO'.$cacheName);
	$frame->begin();

	if(!$arSEO){
		$arData = [
			'DEPTH' => $arResult['PATH'][$key]['DEPTH_LEVEL'],
			'CURRENT_SECTION_NAME' => $arResult['PATH'][$key]['NAME'],
			'FIRST_LEVEL_SECTION_NAME' => $arResult['PATH'][0]['NAME'],
			'SECOND_LEVEL_SECTION_NAME' => $arResult['PATH'][1]['NAME'],
			'THIRD_LEVEL_SECTION_NAME' => $arResult['PATH'][2]['NAME'],
			'BRAND_SECTION_NAME' => $arResult['PATH'][3]['NAME'],
			'MIN_PRICE' => getMinPriceInSections(['IBLOCK_SECTION_ID'=>$arResult['PATH'][$key]['IBLOCK_SECTION_ID'],'PRICE_GROUP'=>1]),
			'SHOP_NAME' => 'каталог интернет-магазина Ваше название',
			//Сюда получаем значения доп. свойств текущего раздела
			//Ведь по условию, заданные здесь правила более приоритетны
			'CURRENT_SECTION_CUSTOM_PROPS' => getSectionProps(['IBLOCK_ID'=>$arResult['PATH'][$key]['IBLOCK_ID'],'ID'=>$arResult['PATH'][$key]['ID']]),
		];

		$text = $SEO['TEMPLATES']['Text_'.$arData['DEPTH'].'_level']['UF_VALUE'];
		if($text){
			$arData['RESULT']['TEXT'] = patternReplace($arData,$text);
		}

		$h1 = $SEO['TEMPLATES']['H1_'.$arData['DEPTH'].'_level']['UF_VALUE'];
		if($h1 && !$arData['CURRENT_SECTION_CUSTOM_PROPS']['UF_H1']){
			$arData['RESULT']['H1'] = patternReplace($arData,$h1);
		}

		$description = $SEO['TEMPLATES']['Description_'.$arData['DEPTH'].'_level']['UF_VALUE'];
		if($description && !$arData['CURRENT_SECTION_CUSTOM_PROPS']['UF_DESC']){
			$arData['RESULT']['DESCRIPTION'] = patternReplace($arData,$description);
		}

		$title = $SEO['TEMPLATES']['Title_'.$arData['DEPTH'].'_level']['UF_VALUE'];
		if($title && !$arData['CURRENT_SECTION_CUSTOM_PROPS']['UF_TITLE']){
			$arData['RESULT']['TITLE'] = patternReplace($arData,$title);
		}

		setToCache($cacheName,$arData);

		$arSEO['BODY'] = $arData;
	}

	if(!empty($arSEO['BODY']['RESULT'])){
		foreach ($arSEO['BODY']['RESULT'] as $key => $value){
			switch ($key) {
				case 'TITLE':
					$APPLICATION->SetPageProperty('Tit', $value);
					break;
				case 'H1':
					$APPLICATION->SetPageProperty('H1', $value);
					break;
				case 'DESCRIPTION':
					$APPLICATION->SetPageProperty("desc", $value);
					break;
				case 'TEXT':
					global $sectionText;
					if(!$sectionText){
						$APPLICATION->SetPageProperty("text", $value);
					}
					break;
			}
		}
	}

	$frame->end();
}

В init.php добавляем

/* Дополнительные функции */
require($_SERVER['DOCUMENT_ROOT'].'/local/libs/init/functions.php');

Листинг файла functions.php

/* Получаем последний ключ массив */
if (! function_exists("array_key_last")) {
    function array_key_last($array) {
        if (!is_array($array) || empty($array)) {
            return NULL;
        }

        return array_keys($array)[count($array)-1];
    }
}

/* Получаем минимальную цену товаров в разделе */
if (! function_exists("getMinPriceInSections")) {
    function getMinPriceInSections($arrData) {
        $minPriceSection = false;
        $priceGroup = $arrData['PRICE_GROUP'];

        $arItems = \CIBlockElement::GetList(["CATALOG_PRICE_{$priceGroup}" => "ASC,NULL"], ["SECTION_ID" => $arrData['IBLOCK_SECTION_ID'], "ACTIVE" => "Y", 'INCLUDE_SUBSECTIONS' => 'Y']);
        $item = $arItems->Fetch();

        if (!empty($item)) {
            //Цена с валютой
            $minPriceSection = \CCurrencyLang::CurrencyFormat((int) $item["CATALOG_PRICE_{$priceGroup}"], $item["CATALOG_CURRENCY_{$priceGroup}"], true);

            //Просто цена без валюты
            //$minPriceSection = (int) $item["CATALOG_PRICE_{$priceGroup}"];
        }

        return $minPriceSection;
    }
}

/* Функция замены */
if (! function_exists("patternReplace")) {
    function patternReplace($arrData,$mask) {

        foreach($arrData as $key => $value){
            if(strpos($mask, $key) !== false){//Исключаем из замены массивы и символы ~
                //Заменяем все возможные паттерны
                $mask = preg_replace('~\#'.$key.'\#~', $value, $mask);
            }

        }

        return $mask;
    }
}

/* Получаем данные из кеша */
if (! function_exists("getFromCache")) {
    function getFromCache($name) {
        CModule::IncludeModule("iblock");

        $cache = new CPHPCache();
        $cache_time = 3600*12; //кеш на сутки
        $cache_id = 'customCache'.$name;
        $cache_path = 'customCache';

        $customCache = false;

        if ($cache_time > 0 && $cache->InitCache($cache_time, $cache_id, $cache_path))
        {
            $res = $cache->GetVars();
            if (is_array($res["customCache"]) && (count($res["customCache"]) > 0)){
                $customCache = $res["customCache"];
            }
            $customCache['CACHE']='true';
        }

        return $customCache;
    }
}

/* Заносим данные в кеш */
if (! function_exists("setToCache")) {
    function setToCache($name, $data) {
        CModule::IncludeModule("iblock");

        $cache = new CPHPCache();
        $cache_time = 3600*12; //кеш на сутки
        $cache_id = 'customCache'.$name;
        $cache_path = 'customCache';

        $customCache['CACHE'] = 'false';
        $customCache['BODY'] = $data;

        //////////// end cache /////////
        if ($cache_time > 0)
        {
            $cache->StartDataCache($cache_time, $cache_id, $cache_path);
            $cache->EndDataCache(array("customCache"=>$customCache));
        }

        return $customCache;
    }
}

/* Получаем доп. свойства раздела */
if (! function_exists("getSectionProps")) {
    function getSectionProps($data) {
        $return = false;

        $dbSection = CIBlockSection::GetList(Array(), array(
            "IBLOCK_ID" => $data['IBLOCK_ID'],
            "ID" => $data['ID']
        ), false ,Array("UF_H1","UF_TITLE","UF_DESC"));

        if($arSection = $dbSection->GetNext()){
            if($arSection['UF_H1']){
                $return['UF_H1'] = $arSection['UF_H1'];
            }
            if($arSection['UF_TITLE']){
                $return['UF_TITLE'] = $arSection['UF_TITLE'];
            }
            if($arSection['UF_DESC']){
                $return['UF_DESC'] = $arSection['UF_DESC'];
            }

        }

        return $return;
    }
}

/* Получаем правильный H1 */
if(!function_exists('aSH1')){
    function aSH1(){
        global $APPLICATION;
        if(!$APPLICATION->GetPageProperty("H1")){
            return $APPLICATION->GetTitle(false);
        } else {
            $h1 = $APPLICATION->GetPageProperty("H1");
            if(!$h1 || $h1==false || $h1=='false')
            {
                return '';
            } elseif(strlen($h1)<=0){
                return $APPLICATION->GetTitle(false);
            } else {
                return $h1;
            }
        }
    }
}

/* Получаем правильный Title */
if(!function_exists('aSTitle')){
    function aSTitle(){
        global $APPLICATION;
        if(!$APPLICATION->GetPageProperty("Tit")){
            //return $APPLICATION->GetTitle(false);
            return $APPLICATION->GetTitle('Title');
        } else {
            $aSTitle = $APPLICATION->GetPageProperty("Tit");
            if(!$aSTitle || $aSTitle==false || $aSTitle=='false')
            {
                return '';
            } elseif(strlen($aSTitle)<=0){
                //return $APPLICATION->GetTitle(false);
                return $APPLICATION->GetTitle('Title');
            } else {
                return $aSTitle;
            }
        }
    }
}

/* Получаем правильный Text */
if(!function_exists('aSText')){
    function aSText(){
        global $APPLICATION;
        if(!$APPLICATION->GetPageProperty("text")){
            //return $APPLICATION->GetTitle(false);
            return $APPLICATION->GetTitle('Title');
        } else {
            $aSTitle = $APPLICATION->GetPageProperty("text");
            if(!$aSTitle || $aSTitle==false || $aSTitle=='false')
            {
                return '';
            } elseif(strlen($aSTitle)<=0){
                //return $APPLICATION->GetTitle(false);
                return $APPLICATION->GetTitle('Title');
            } else {
                return $aSTitle;
            }
        }
    }
}

/* Получаем правильный Description */
if(!function_exists('aSDescription')){
    function aSDescription(){
        global $APPLICATION;
        if(!$APPLICATION->GetPageProperty("desc")){
            //return $APPLICATION->GetTitle(false);
            return $APPLICATION->GetTitle('description');
        } else {
            $aSTitle = $APPLICATION->GetPageProperty("desc");
            if(!$aSTitle || $aSTitle==false || $aSTitle=='false')
            {
                return '';
            } elseif(strlen($aSTitle)<=0){
                //return $APPLICATION->GetTitle(false);
                return $APPLICATION->GetTitle('description');
            } else {
                return $aSTitle;
            }
        }
    }
}

В файле header.php меняем вызов title c

<title><?$APPLICATION->ShowTitle()?></title>

на

<title><?$APPLICATION->AddBufferContent('aSTitle');?></title>

Выводим правильный description

<meta name="description" content="<?$APPLICATION->AddBufferContent('aSDescription');?>" />

И отключаем вывод description в файле bitrix\modules\main\classes\general\main.php в функции ShowHead (~843 стр.)

//$this->ShowMeta("description", false, $bXhtmlStyle);

Заменяем вывод h1 на

<h1><?$APPLICATION->AddBufferContent('aSH1');?></h1>

Так же выводим текст в нужном нам месте

global $sectionText;
$sectionText = $arSection["UF_TEXT"];

$APPLICATION->SetPageProperty("text", $arSection["UF_TEXT"]);
<div class="description_collapse_text"><?$APPLICATION->AddBufferContent('aSText');?></div>

Комментарии

Комментариев еще нет, Вы можете стать первым кто его оставит

Оставьте комментарий

На сайте используется система премодерирования комментариев, поэтому ваше сообщение будет опубликовано лишь после одобрения модератором

Вы отвечаете на комментарий пользователя

Отправить

ОБРАТНАЯ СВЯЗЬ

Напишите мне

Вы разрабатываете новый сервис, вносите доработки в существующий и хотите лучше чем у конкурентов? Вы обратились по адресу. Предлагаю вам комплексную разработку сайтов студийного уровня. У меня вы можете заказать дизайн, верстку, програмированние, разработку нетрадиционного функционала, реализацию связи между CMS, CRM и Data Analitics, а так же все остальное касаемое сайтов, кроме продвижения.

Обращайтесь, я всегда проконсультирую по всем вопросам и помогу подобрать наиболее эффективное решение для Вашего бизнеса. Я занимаюсь созданием сайтов в Новосибирске и в других регионах России, также работаю со странами СНГ. Вы останетесь довольны нашим сотрудничеством

Во время отправки произошла ошибка, пожалуйста попробуйте еще раз через некоторое время
Сообщение отправлено успешно

Телефоны

+7(993) 007-18-96

Email

info@tichiy.ru

Адрес

Россия, г. Москва

Отправляя форму Вы автоматически подтверждаете, что ознакомились и принимаете Политику конфиденциальности сайта

Написать мне
Отправить
Отправляя форму Вы автоматически подтверждаете, что ознакомились и принимаете Политику конфиденциальности сайта
Отправка успешна!
Thank you for your feedback. I will answer you within the next working hours
Отправка не удалась
Во время отправки запроса произошла ошибка. Пожалуйста, подождите и попробуйте снова через некоторое время или свяжитесь со мной