Последние записи
Выводим кастомные 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>
Комментарии