Bitrix. Simple horizontal seo template engine for online store
Rus
Eng
Битрикс. Простой горизонтальный сео-шаблонизатор для интернет-магазина

All English-language materials have been translated fully automatically using the Google service

Display custom Title, H1, Description and arbitrary Text on the product list pages of the sections

Let's set separate replacement patterns in the HL block. Each entry will contain a title and a replacement rule. In the name, we will encode the type of replacement and the level of triggering. It looks like this

Consider the following replacement patterns

# CURRENT_SECTION_NAME # - The name of the current directory level
# FIRST_LEVEL_SECTION_NAME # - Name of the first level directory
# SECOND_LEVEL_SECTION_NAME # - The name of the second level directory
# THIRD_LEVEL_SECTION_NAME # - Name of the third level directory
# BRAND_SECTION_NAME # - The name of the fourth level directory
# MIN_PRICE # - The minimum price of an item in the current section
# SHOP_NAME # - The name of the store ("catalog of the online store your name")

Getting data. For example in init.php in the OnPageStart

event
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));
		}
	}
}

By the condition of the problem, our template engine should only work on pages with a list of products. To do this, we are looking for a template for your component catalog.section in which we believe that we already have an array of similar data:

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
                        )

                )
        )

)

Add or edit the file 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' => 'online store catalog Your name',
			// Here we get additional values. properties of the current section
			// After all, by condition, the rules set here have a higher priority
			'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();
}

In init.php add

require($_SERVER['DOCUMENT_ROOT'].'/local/libs/init/functions.php');

Listing of the file functions.php

/ * Get the last key array * /
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];
    }
}

/ * Get the minimum price of goods in the section * /
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)) {
            // Price with currency
            $minPriceSection = \CCurrencyLang::CurrencyFormat((int) $item["CATALOG_PRICE_{$priceGroup}"], $item["CATALOG_CURRENCY_{$priceGroup}"], true);

            // Just a price without currency
            //$minPriceSection = (int) $item["CATALOG_PRICE_{$priceGroup}"];
        }

        return $minPriceSection;
    }
}

/ * Replace function * /
if (! function_exists("patternReplace")) {
    function patternReplace($arrData,$mask) {

        foreach($arrData as $key => $value){
            if(strpos($mask, $key) !== false){// Exclude arrays and symbols from replacement ~
                // Replace all possible patterns
                $mask = preg_replace('~\#'.$key.'\#~', $value, $mask);
            }

        }

        return $mask;
    }
}

/ * Get data from cache * /
if (! function_exists("getFromCache")) {
    function getFromCache($name) {
        CModule::IncludeModule("iblock");

        $cache = new CPHPCache();
        $cache_time = 3600*12; // cache for a day
        $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;
    }
}

/ * Put the data into the cache * /
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;
    }
}

/ * Get additional. section properties * /
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;
    }
}

/ * Get the correct 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;
            }
        }
    }
}

/ * Get the correct 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;
            }
        }
    }
}

/ * Get the correct 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;
            }
        }
    }
}

/ * Get the correct 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;
            }
        }
    }
}

In the header.php file, change the call to title c

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

to

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

Displaying the correct description

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

And disable the description output in the file bitrix \ modules \ main \ classes \ general \ main.php in the ShowHead function (~ 843 pages .)

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

Replace h1 output with

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

We also display the text in the place we need

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

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

Comments

There are no comments yet, you can be the first to leave it

Leave a comment

The site uses a comment pre-moderation system, so your message will be published only after approval by the moderator

You are replying to a user's comment

Send

FEEDBACK

Email me

Are you developing a new service, making improvements to the existing one and want to be better than your competitors? You have come to the right place. I offer you a comprehensive studio-level website development. From me you can order design, layout, programming, development of non-traditional functionality, implementation of communication between CMS, CRM and Data Analitics, as well as everything else related to sites, except for promotion.

Contact, I will always advise on all questions and help you find the most effective solution for your business. I am engaged in the creation of sites in Novosibirsk and in other regions of Russia, I also work with the CIS countries. You will be satisfied with our cooperation

An error occurred while sending, please try again after a while
Message sent successfully

Phones

+7(993) 007-18-96

Email

info@tichiy.ru

Address

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

By submitting the form, you automatically confirm that you have read and accept the Privacy Policy site

Contact with me
Send message
By submitting the form, you automatically confirm that you have read and accept Privacy policy of site
Sending successful!
Thank you for contacting :) I will contact you as soon as possible
Sending failed
An error occurred while sending the request. Please wait and try again after a while or call my phone number