Битрикс. Создание комплексного компонента. Часть 2 из 4
19.09.2018
Теги: CMS • Web-разработка • Битрикс • Инфоблок • Компонент • РазделИнфоблока • ШаблонКомпонента • ЭлементИнфоблока
Следующий простой компонент, который мы создадим, умеет выводить раздел инфоблока. А именно — показывать список подразделов текущего раздела и список элементов этого раздела. Подразделы и элементы отсортированы по коду сортировки, который задается в панели управления.
Простой компонент tokmakov:iblock.section
В браузере это выглядит примерно так:<?php /* * Файл local/components/tokmakov/iblock.section/.description.php */ if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); $arComponentDescription = array( 'NAME' => 'Раздел инфоблока', // название компонента 'DESCRIPTION' => 'Выводит список элементов раздела инфоблока', 'ICON' => '/images/icon.gif', // иконка компонента относительно папки компонента 'CACHE_PATH' => 'Y', // показывать кнопку очистки кеша 'SORT' => 20, // порядок сортировки в визуальном редакторе 'COMPLEX' => 'N', // признак комплексного компонента 'PATH' => array( // расположение компонента в визуальном редакторе 'ID' => 'other_components', // идентификатор верхнего уровеня в редакторе 'NAME' => 'Прочие компоненты', // название верхнего уровня в редакторе 'CHILD' => array( // второй уровень в визуальном редакторе 'ID' => 'other_iblock', // идентификатор второго уровня в редакторе 'NAME' => 'Информационный блок' // название второго уровня в редакторе ) ) );
<?php /* * Файл local/components/tokmakov/iblock.section/.parameters.php */ if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); // проверяем, установлен ли модуль «Информационные блоки»; если да — то подключаем его if (!CModule::IncludeModule('iblock')) { return; } /* * Получаем массив всех типов инфоблоков — для возможности выбора */ $arIBlockType = CIBlockParameters::GetIBlockTypes(); /* * Получаем массив инфоблоков — для возможности выбора; фильтруем их по * выбранному типу и по активности */ $arInfoBlocks = array(); $arFilter = array('ACTIVE' => 'Y'); // если уже выбран тип инфоблока, выбираем инфоблоки только этого типа if (!empty($arCurrentValues['IBLOCK_TYPE'])) { $arFilter['TYPE'] = $arCurrentValues['IBLOCK_TYPE']; } $rsIBlock = CIBlock::GetList( array('SORT' => 'ASC'), $arFilter ); while ($iblock = $rsIBlock->Fetch()) { $arInfoBlocks[$iblock['ID']] = '['.$iblock['ID'].'] '.$iblock['NAME']; } /* * Настройки компонента */ $arComponentParameters = array( 'GROUPS' => array( // кроме групп по умолчанию, добавляем свою группу настроек 'SEO_SETTINGS' => array( 'NAME' => 'Настройки SEO', 'SORT' => 800 ), ), 'PARAMETERS' => array( // выбор типа инфоблока 'IBLOCK_TYPE' => array( 'PARENT' => 'BASE', 'NAME' => 'Выберите тип инфоблока', 'TYPE' => 'LIST', 'VALUES' => $arIBlockType, 'REFRESH' => 'Y', ), // выбор самого инфоблока 'IBLOCK_ID' => array( 'PARENT' => 'BASE', 'NAME' => 'Выберите инфоблок', 'TYPE' => 'LIST', 'VALUES' => $arInfoBlocks, 'REFRESH' => 'Y', ), // идентификатор раздела получать из $_REQUEST["SECTION_ID"] 'SECTION_ID' => array( 'PARENT' => 'BASE', 'NAME' => 'Идентификатор раздела', 'TYPE' => 'STRING', 'DEFAULT' => '={$_REQUEST["SECTION_ID"]}', ), // символьный код раздела получать из $_REQUEST["SECTION_CODE"] 'SECTION_CODE' => array( 'PARENT' => 'BASE', 'NAME' => 'Символьный код раздела', 'TYPE' => 'STRING', 'DEFAULT' => '={$_REQUEST["SECTION_CODE"]}', ), 'ELEMENT_COUNT' => array( 'PARENT' => 'BASE', 'NAME' => 'Количество элементов на странице', 'TYPE' => 'STRING', 'DEFAULT' => '3', ), // использовать символьный код вместо ID; если отмечен этот checkbox, // в визуальном редакторе надо будет обязательно изменить SECTION_URL // и ELEMENT_URL, чтобы вместо #SECTION_ID# и #ELEMENT_ID# в шаблонах // ссылок использовались #SECTION_CODE# и #ELEMENT_CODE# 'USE_CODE_INSTEAD_ID' => array( 'PARENT' => 'URL_TEMPLATES', 'NAME' => 'Использовать символьный код вместо ID', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'N', ), // шаблон ссылки на страницу раздела 'SECTION_URL' => array( 'PARENT' => 'URL_TEMPLATES', 'NAME' => 'URL, ведущий на страницу с содержимым раздела', 'TYPE' => 'STRING', 'DEFAULT' => 'category/id/#SECTION_ID#/' ), // шаблон ссылки на страницу элемента 'ELEMENT_URL' => array( 'PARENT' => 'URL_TEMPLATES', 'NAME' => 'URL, ведущий на страницу с содержимым элемента', 'TYPE' => 'STRING', 'DEFAULT' => 'item/id/#ELEMENT_ID#/' ), // настройки SEO 'SET_PAGE_TITLE' => array( 'PARENT' => 'SEO_SETTINGS', 'NAME' => 'Устанавливать заголовок страницы', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'Y', ), 'SET_BROWSER_TITLE' => array( 'PARENT' => 'SEO_SETTINGS', 'NAME' => 'Устанавливать заголовок окна браузера', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'Y', ), 'SET_META_KEYWORDS' => array( 'PARENT' => 'SEO_SETTINGS', 'NAME' => 'Устанавливать мета-тег keywords', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'Y', ), 'SET_META_DESCRIPTION' => array( 'PARENT' => 'SEO_SETTINGS', 'NAME' => 'Устанавливать мета-тег description', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'Y', ), // включать раздел в цепочку навигации? 'ADD_SECTIONS_CHAIN' => Array( 'PARENT' => 'ADDITIONAL_SETTINGS', 'NAME' => 'Включать раздел в цепочку навигации', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'Y', ), // настройки кэширования 'CACHE_TIME' => array('DEFAULT' => 3600), 'CACHE_GROUPS' => array( 'PARENT' => 'CACHE_SETTINGS', 'NAME' => 'Учитывать права доступа', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'Y', ), ), ); // настройка постраничной навигации CIBlockParameters::AddPagerSettings( $arComponentParameters, 'Элементы', // $pager_title false, // $bDescNumbering true // $bShowAllParam ); // добавляем еще одну настройку — на случай, если раздел инфоблока не найден CIBlockParameters::Add404Settings($arComponentParameters, $arCurrentValues);
<?php /* * Файл local/components/tokmakov/iblock.section/component.php */ if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); /** @var CBitrixComponent $this */ /** @var array $arParams */ /** @var array $arResult */ /** @var string $componentPath */ /** @var string $componentName */ /** @var string $componentTemplate */ /** @global CDatabase $DB */ /** @global CUser $USER */ /** @global CMain $APPLICATION */ if (!CModule::IncludeModule('iblock')) { ShowError('Модуль «Информационные блоки» не установлен'); return; } // запрещаем сохранение в сессии номера последней страницы // при стандартной постраничной навигации CPageOption::SetOptionString('main', 'nav_page_in_session', 'N'); if (!isset($arParams['CACHE_TIME'])) { $arParams['CACHE_TIME'] = 3600; } // тип инфоблока $arParams['IBLOCK_TYPE'] = trim($arParams['IBLOCK_TYPE']); // идентификатор инфоблока $arParams['IBLOCK_ID'] = intval($arParams['IBLOCK_ID']); $notFound = false; if ($arParams['USE_CODE_INSTEAD_ID'] == 'Y') { // символьный код раздела инфоблока $arParams['SECTION_CODE'] = empty($arParams['SECTION_CODE']) ? '' : trim($arParams['SECTION_CODE']); if (empty($arParams['SECTION_CODE'])) { $notFound = true; } } else { // идентификатор раздела инфоблока $arParams['SECTION_ID'] = empty($arParams['SECTION_ID']) ? 0 : intval($arParams['SECTION_ID']); if (empty($arParams['SECTION_ID'])) { $notFound = true; } } // если получено некорректное значение идентификатора раздела или символьного // кода раздела инфоблока, показываем страницу 404 Not Found if ($notFound) { \Bitrix\Iblock\Component\Tools::process404( trim($arParams['MESSAGE_404']) ?: 'Раздел инфоблока не найден', true, $arParams['SET_STATUS_404'] === 'Y', $arParams['SHOW_404'] === 'Y', $arParams['FILE_404'] ); return; } // шаблон ссылки на страницу с содержимым раздела $arParams['SECTION_URL'] = trim($arParams['SECTION_URL']); // шаблон ссылки на страницу с содержимым элемента $arParams['ELEMENT_URL'] = trim($arParams['ELEMENT_URL']); // количество элементов на страницу $arParams['ELEMENT_COUNT'] = intval($arParams['ELEMENT_COUNT']); if ($arParams['ELEMENT_COUNT'] <= 0) { $arParams['ELEMENT_COUNT'] = 3; } // учитывать права доступа при кешировании? $arParams['CACHE_GROUPS'] = $arParams['CACHE_GROUPS']=='Y'; // показывать постраничную навигацию вверху списка элементов? $arParams['DISPLAY_TOP_PAGER'] = $arParams['DISPLAY_TOP_PAGER']=='Y'; // показывать постраничную навигацию внизу списка элементов? $arParams['DISPLAY_BOTTOM_PAGER'] = $arParams['DISPLAY_BOTTOM_PAGER']=='Y'; // поясняющий текст для постраничной навигации $arParams['PAGER_TITLE'] = trim($arParams['PAGER_TITLE']); // всегда показывать постраничную навигацию, даже если в этом нет необходимости $arParams['PAGER_SHOW_ALWAYS'] = $arParams['PAGER_SHOW_ALWAYS']=='Y'; // имя шаблона постраничной навигации $arParams['PAGER_TEMPLATE'] = trim($arParams['PAGER_TEMPLATE']); // показывать ссылку «Все элементы», с помощью которой можно показать все элементы списка? $arParams['PAGER_SHOW_ALL'] = $arParams['PAGER_SHOW_ALL']=='Y'; // получаем все параметры постраничной навигации, от которых будет зависеть кеш $arNavParams = null; $arNavigation = false; if ($arParams['DISPLAY_TOP_PAGER'] || $arParams['DISPLAY_BOTTOM_PAGER']) { $arNavParams = array( 'nPageSize' => $arParams['ELEMENT_COUNT'], // количество элементов на странице 'bShowAll' => $arParams['PAGER_SHOW_ALL'], // показывать ссылку «Все элементы»? ); $arNavigation = CDBResult::GetNavParams($arNavParams); } $cacheDependence = array($arParams['CACHE_GROUPS'] ? $USER->GetGroups() : false, $arNavigation); if ($this->StartResultCache(false, $cacheDependence)) { /* * Получаем информацию о разделе инфоблока */ // какие поля раздела инфоблока выбираем $arSelect = array( 'ID', 'NAME', 'DETAIL_PICTURE', 'DESCRIPTION', 'DESCRIPTION_TYPE' ); // условия выборки раздела инфоблока $arFilter = array( 'IBLOCK_ID' => $arParams['IBLOCK_ID'], 'IBLOCK_ACTIVE' => 'Y', 'ACTIVE' => 'Y', 'GLOBAL_ACTIVE' => 'Y', ); if (strlen($arParams['SECTION_CODE']) > 0) { // выбираем раздел по символьному коду $arFilter['=CODE'] = $arParams['SECTION_CODE']; } else { // выбираем раздел по идентификатору $arFilter['ID'] = $arParams['SECTION_ID']; } // выполняем запрос к базе данных $rsSection = CIBlockSection::GetList(array(), $arFilter, false, $arSelect); // устанавливаем шаблон пути для раздела, вместо того, // который указан в настройках информационного блока $rsSection->SetUrlTemplates('', $arParams['SECTION_URL']); $arResult = $rsSection->GetNext(); if ($arResult) { $arResult['PATH'] = array(); // если нужно добавить раздел в цепочку навигации — получаем всех родителей if ($arParams['ADD_SECTIONS_CHAIN'] == 'Y') { $rsPath = CIBlockSection::GetNavChain($arResult['IBLOCK_ID'], $arResult['ID']); $rsPath->SetUrlTemplates('', $arParams['SECTION_URL']); while ($arPath = $rsPath->GetNext()) { $arResult['PATH'][] = $arPath; } } // картинка раздела if ($arResult['DETAIL_PICTURE'] > 0) { $arResult['DETAIL_PICTURE'] = CFile::GetFileArray($arResult['DETAIL_PICTURE']); } else { $arResult['DETAIL_PICTURE'] = false; } // получаем SEO-свойства раздела $ipropValues = new \Bitrix\Iblock\InheritedProperty\SectionValues( $arParams['IBLOCK_ID'], $arResult['ID'] ); $arResult['IPROPERTY_VALUES'] = $ipropValues->getValues(); if ($arResult['DETAIL_PICTURE']) { $arResult['DETAIL_PICTURE']['ALT'] = $arResult['IPROPERTY_VALUES']['SECTION_DETAIL_PICTURE_FILE_ALT']; if ($arResult['DETAIL_PICTURE']['ALT'] == '') { $arResult['DETAIL_PICTURE']['ALT'] = $arResult['NAME']; } $arResult['DETAIL_PICTURE']['TITLE'] = $arResult['IPROPERTY_VALUES']['[SECTION_DETAIL_PICTURE_FILE_TITLE']; if ($arResult['DETAIL_PICTURE']['TITLE'] == '') { $arResult['DETAIL_PICTURE']['TITLE'] = $arResult['NAME']; } } /* * Получаем подразделы этого раздела инфоблока */ // какие поля подразделов выбираем $arSelect = array( 'ID', 'NAME', 'PICTURE', 'DESCRIPTION', 'DESCRIPTION_TYPE', 'SECTION_PAGE_URL' ); // условия выборки подразделов $arFilter = array( 'IBLOCK_ID' => $arParams['IBLOCK_ID'], // идентификатор инфоблока 'IBLOCK_ACTIVE' => 'Y', // инфоблок должен быть активен 'SECTION_ID' => $arResult['ID'], // подразделы этого раздела 'ACTIVE' => 'Y', // только активные разделы 'CHECK_PERMISSIONS' => 'Y', // проверять права доступа ); // сортировка подразделов $arSort = array( 'SORT' => 'ASC', ); // выполняем запрос к базе данных $rsSections = CIBlockSection::GetList($arSort, $arFilter, false, $arSelect); // устанавливаем шаблон пути для подразделов, вместо того, // который указан в настройках информационного блока $rsSections->SetUrlTemplates('', $arParams['SECTION_URL']); while ($arSection = $rsSections->GetNext()) { if (0 < $arSection['PICTURE']) { $arSection['PREVIEW_PICTURE'] = CFile::GetFileArray($arSection['PICTURE']); } else { $arSection['PREVIEW_PICTURE'] = false; } unset($arSection['PICTURE']); // получаем SEO-свойства очередного подраздела $ipropValues = new \Bitrix\Iblock\InheritedProperty\SectionValues( $arParams['IBLOCK_ID'], $arSection['ID'] ); $arSection['IPROPERTY_VALUES'] = $ipropValues->getValues(); if ($arSection['PREVIEW_PICTURE']) { $arSection['PREVIEW_PICTURE']['ALT'] = $arSection['IPROPERTY_VALUES']['SECTION_PICTURE_FILE_ALT']; if ($arSection['PREVIEW_PICTURE']['ALT'] == '') { $arSection['PREVIEW_PICTURE']['ALT'] = $arSection['NAME']; } $arSection['PREVIEW_PICTURE']['TITLE'] = $arSection['IPROPERTY_VALUES']['[SECTION_PICTURE_FILE_TITLE']; if ($arSection['PREVIEW_PICTURE']['TITLE'] == '') { $arSection['PREVIEW_PICTURE']['TITLE'] = $arSection['NAME']; } } $arResult['CHILD_SECTIONS'][] = $arSection; } /* * Получаем элементы этого раздела инфоблока */ // какие поля элементов выбираем $arSelect = array( 'ID', 'CODE', 'IBLOCK_ID', 'NAME', 'PREVIEW_PICTURE', 'DETAIL_PAGE_URL', 'PREVIEW_TEXT', 'PREVIEW_TEXT_TYPE', 'SHOW_COUNTER' ); // условия выборки элементов инфоблока $arFilter = array( 'IBLOCK_ID' => $arParams['IBLOCK_ID'], 'IBLOCK_ACTIVE' => 'Y', 'SECTION_ID' => $arResult['ID'], 'INCLUDE_SUBSECTIONS' => 'Y', 'ACTIVE' => 'Y', 'ACTIVE_DATE' => 'Y', 'CHECK_PERMISSIONS' => 'Y' ); // сортировка элементов $arSort = array( 'SORT' => 'ASC' ); // выполняем запрос к базе данных $rsElements = CIBlockElement::GetList($arSort, $arFilter, false, $arNavParams, $arSelect); // устанавливаем шаблоны путей для раздела и элемента, вместо тех, которые // указаны в настройках информационного блока или были установлены ранее $rsElements->SetUrlTemplates($arParams['ELEMENT_URL'], $arParams['SECTION_URL']); $arResult['ITEMS'] = array(); while ($arItem = $rsElements->GetNext()) { // получаем SEO-свойства очередного элемента $ipropValues = new \Bitrix\Iblock\InheritedProperty\ElementValues( $arItem['IBLOCK_ID'], $arItem['ID'] ); $arItem['IPROPERTY_VALUES'] = $ipropValues->getValues(); $arItem['PREVIEW_PICTURE'] = (0 < $arItem['PREVIEW_PICTURE'] ? CFile::GetFileArray($arItem['PREVIEW_PICTURE']) : false); if ($arItem['PREVIEW_PICTURE']) { $arItem['PREVIEW_PICTURE']['ALT'] = $arItem['IPROPERTY_VALUES']['ELEMENT_PREVIEW_PICTURE_FILE_ALT']; if ($arItem['PREVIEW_PICTURE']['ALT'] == '') { $arItem['PREVIEW_PICTURE']['ALT'] = $arItem['NAME']; } $arItem['PREVIEW_PICTURE']['TITLE'] = $arItem['IPROPERTY_VALUES']['ELEMENT_PREVIEW_PICTURE_FILE_TITLE']; if ($arItem['PREVIEW_PICTURE']['TITLE'] == '') { $arItem['PREVIEW_PICTURE']['TITLE'] = $arItem['NAME']; } } $arResult['ITEMS'][] = $arItem; } /* * Постраничная навигация */ $arResult['NAV_STRING'] = $rsElements->GetPageNavString( $arParams['PAGER_TITLE'], $arParams['PAGER_TEMPLATE'], $arParams['PAGER_SHOW_ALWAYS'], $this ); $this->SetResultCacheKeys( array( 'ID', 'IBLOCK_ID', 'NAME', 'PATH', 'IPROPERTY_VALUES', ) ); $this->IncludeComponentTemplate(); } else { // если раздел инфоблока не найден $this->AbortResultCache(); \Bitrix\Iblock\Component\Tools::process404( trim($arParams['MESSAGE_404']) ?: 'Раздел инфоблока не найден', true, $arParams['SET_STATUS_404'] === 'Y', $arParams['SHOW_404'] === 'Y', $arParams['FILE_404'] ); } } // кэш не затронет все действия ниже, здесь работаем уже с другим $arResult if (isset($arResult['ID'])) { if ($arParams['SET_PAGE_TITLE'] == 'Y') { // устанавливить заголовок страницы? if ($arResult['IPROPERTY_VALUES']['SECTION_PAGE_TITLE'] != '') { $APPLICATION->SetTitle($arResult['IPROPERTY_VALUES']['SECTION_PAGE_TITLE']); } else { $APPLICATION->SetTitle($arResult['NAME']); } } if ($arParams['SET_BROWSER_TITLE'] == 'Y') { // устанавить заголовок окна браузера? if ($arResult['IPROPERTY_VALUES']['SECTION_META_TITLE'] != '') { $APPLICATION->SetPageProperty('title', $arResult['IPROPERTY_VALUES']['SECTION_META_TITLE']); } else { $APPLICATION->SetPageProperty('title', $arResult['NAME']); } } // установить мета-тег keywords? if ($arParams['SET_META_KEYWORDS'] == 'Y' && $arResult['IPROPERTY_VALUES']['SECTION_META_KEYWORDS'] != '') { $APPLICATION->SetPageProperty('keywords', $arResult['IPROPERTY_VALUES']['SECTION_META_KEYWORDS']); } // установить мета-тег description? if ($arParams['SET_META_DESCRIPTION'] == 'Y' && $arResult['IPROPERTY_VALUES']['SECTION_META_DESCRIPTION'] != '') { $APPLICATION->SetPageProperty('description', $arResult['IPROPERTY_VALUES']['SECTION_META_DESCRIPTION']); } if ($arParams['ADD_SECTIONS_CHAIN'] == 'Y') { // добавить раздел в цепочку навигации? foreach ($arResult['PATH'] as $arPath) { $APPLICATION->AddChainItem($arPath['NAME'], $arPath['~SECTION_PAGE_URL']); } } }
<?php /* * Файл local/components/tokmakov/iblock.section/templates/.default/template.php */ if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); /** @var array $arParams */ /** @var array $arResult */ /** @global CMain $APPLICATION */ /** @global CUser $USER */ /** @global CDatabase $DB */ /** @var CBitrixComponentTemplate $this */ /** @var string $templateName */ /** @var string $templateFile */ /** @var string $templateFolder */ /** @var string $componentPath */ /** @var CBitrixComponent $component */ // шаблон компонента голосует против композита $this->setFrameMode(false); ?> <h1><?= $arResult['NAME']; ?></h1> <?php if (!empty($arResult['CHILD_SECTIONS'])): ?> <div id="iblock-child-sections"> <?php foreach ($arResult['CHILD_SECTIONS'] as $arSection): /* подразделы текущего раздела */ ?> <article> <a href="<?= $arSection['SECTION_PAGE_URL']; ?>"> <img src="<?= $arSection['PREVIEW_PICTURE']['SRC']; ?>" alt="<?= $arSection['PREVIEW_PICTURE']['ALT']; ?>" title="<?= $arSection['PREVIEW_PICTURE']['TITLE']; ?>" /> </a> <h2><a href="<?= $arSection['SECTION_PAGE_URL']; ?>"><?= $arSection['NAME']; ?></a></h2> <?php if (!empty($arSection['DESCRIPTION'])): ?> <p><?= $arSection['DESCRIPTION']; ?></p> <?php endif; ?> </article> <?php endforeach; ?> </div> <?php endif; ?> <div id="iblock-section-items"> <?php if ($arParams['DISPLAY_TOP_PAGER']): /* постраничная навигация вверху */ ?> <div class="pager"> <?= $arResult['NAV_STRING']; ?> </div> <?php endif; ?> <section> <?php foreach ($arResult['ITEMS'] as $arItem): ?> <article> <a href="<?= $arSection['DETAIL_PAGE_URL']; ?>"> <img src="<?= $arItem['PREVIEW_PICTURE']['SRC']; ?>" alt="<?= $arItem['PREVIEW_PICTURE']['ALT']; ?>" title="<?= $arItem['PREVIEW_PICTURE']['TITLE']; ?>" /> </a> <h3><a href="<?= $arItem['DETAIL_PAGE_URL']; ?>"><?= $arItem['NAME']; ?></a></h3> <?php if (!empty($arItem['PREVIEW_TEXT'])): ?> <p><?= $arItem['PREVIEW_TEXT']; ?></p> <?php endif; ?> <span>Количество просмотров: <?= $arItem['SHOW_COUNTER'] ? $arItem['SHOW_COUNTER'] : 0; ?></span> </article> <?php endforeach; ?> </section> <?php if ($arParams['DISPLAY_BOTTOM_PAGER']): /* постраничная навигация внизу */ ?> <div class="pager"> <?= $arResult['NAV_STRING']; ?> </div> <?php endif; ?> </div>
/*
* Файл local/components/tokmakov/iblock.section/templates/.default/style.css
*/
#iblock-child-sections {
}
#iblock-child-sections > article {
border: 1px solid #d1d1d1;
padding: 10px;
border-radius: 10px;
overflow: hidden;
margin-bottom: 15px;
background: #f5f5f5;
}
#iblock-child-sections > article > h2 {
margin: -5px 0 5px 120px !important;
}
#iblock-child-sections > article > p {
margin: 5px 0 0 120px !important;
}
#iblock-child-sections > article > a > img {
width: 100px;
height: 100px;
float: left;
}
#iblock-section-items {
margin-top: 40px;
}
#iblock-section-items > section {
}
#iblock-section-items > section > article {
border-bottom: 1px dashed #395985;
padding: 15px 0 15px 0;
overflow: hidden;
}
#iblock-section-items > section > article:first-child {
border-top: 1px dashed #395985;
}
#iblock-section-items > section > article > a > img {
width: 140px;
height: 140px;
float: left;
}
#iblock-section-items > section > article > h3 {
margin-top: 0;
}
#iblock-section-items > section > article > p {
}
#iblock-section-items > section > article > span {
display: block;
font-size: 12px;
color: #999;
}
#iblock-section-items > section > article > h3,
#iblock-section-items > section > article > p,
#iblock-section-items > section > article > span {
margin-left: 150px;
}
Пример вызова компонента:
<?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); $APPLICATION->SetTitle("Статьи о домашних животных"); ?> <?php $APPLICATION->IncludeComponent( "tokmakov:iblock.section", "", Array( "ADD_SECTIONS_CHAIN" => "Y", "CACHE_GROUPS" => "Y", "CACHE_TIME" => "3600", "CACHE_TYPE" => "A", "DISPLAY_BOTTOM_PAGER" => "Y", "DISPLAY_TOP_PAGER" => "N", "ELEMENT_COUNT" => "3", "ELEMENT_URL" => "item/id/#ELEMENT_ID#/", "IBLOCK_ID" => "5", "IBLOCK_TYPE" => "content", "MESSAGE_404" => "", "PAGER_BASE_LINK_ENABLE" => "N", "PAGER_DESC_NUMBERING" => "N", "PAGER_DESC_NUMBERING_CACHE_TIME" => "36000", "PAGER_SHOW_ALL" => "N", "PAGER_SHOW_ALWAYS" => "N", "PAGER_TEMPLATE" => ".default", "PAGER_TITLE" => "Элементы", "SECTION_CODE" => $_REQUEST["SECTION_CODE"], "SECTION_ID" => $_REQUEST["SECTION_ID"], "SECTION_URL" => "category/id/#SECTION_ID#/", "SET_BROWSER_TITLE" => "Y", "SET_META_DESCRIPTION" => "Y", "SET_META_KEYWORDS" => "Y", "SET_PAGE_TITLE" => "Y", "SET_STATUS_404" => "Y", "SHOW_404" => "N", "USE_CODE_INSTEAD_ID" => "N" ) ); ?> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
Простой компонент tokmakov:iblock.popular
Последний простой компонент, который нам потребуется для создания комплексного компонета, умеет выводить корневые разделы инфоблока и популярные элементы. Из каких разделов выбирать популярные элементы — задается в настройках. Популярность определяется по количеству просмотров того или иного элемента. В браузере это выглядит примерно так:
<?php /* * Файл local/components/tokmakov/iblock.popular/.description.php */ if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); $arComponentDescription = array( 'NAME' => 'Популярные элементы', // название компонента 'DESCRIPTION' => 'Выводит корневые разделы и популярные элементы в каждом разделе', 'ICON' => '/images/icon.gif', // иконка компонента относительно папки компонента 'CACHE_PATH' => 'Y', // показывать кнопку очистки кеша 'SORT' => 10, // порядок сортировки в визуальном редакторе 'COMPLEX' => 'N', // признак комплексного компонента 'PATH' => array( // расположение компонента в визуальном редакторе 'ID' => 'other_components', // идентификатор верхнего уровеня в редакторе 'NAME' => 'Прочие компоненты', // название верхнего уровня в редакторе 'CHILD' => array( // второй уровень в визуальном редакторе 'ID' => 'other_iblock', // идентификатор второго уровня в редакторе 'NAME' => 'Информационный блок' // название второго уровня в редакторе ) ) );
<?php /* * Файл local/components/tokmakov/iblock.popular/.parameters.php */ if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); // проверяем, установлен ли модуль «Информационные блоки»; если да — то подключаем его if (!CModule::IncludeModule('iblock')) { return; } /* * Получаем массив всех типов инфоблоков — для возможности выбора */ $arIBlockType = CIBlockParameters::GetIBlockTypes(); /* * Получаем массив инфоблоков — для возможности выбора; фильтруем их по * выбранному типу и по активности */ $arInfoBlocks = array(); $arFilter = array('ACTIVE' => 'Y'); // если уже выбран тип инфоблока, выбираем инфоблоки только этого типа if (!empty($arCurrentValues['IBLOCK_TYPE'])) { $arFilter['TYPE'] = $arCurrentValues['IBLOCK_TYPE']; } $rsIBlock = CIBlock::GetList( array('SORT' => 'ASC'), $arFilter ); while($iblock = $rsIBlock->Fetch()) { $arInfoBlocks[$iblock['ID']] = '['.$iblock['ID'].'] '.$iblock['NAME']; } /* * Получаем массив разделов инфоблока, из которых надо получать * популярные элементы — для возможности выбора */ $arInfoBlockSections = array( '-' => '[=Выберите=]', ); $arFilter = array( 'SECTION_ID' => false, // только корневые разделы 'ACTIVE' => 'Y' // только активные разделы ); // если уже выбран тип инфоблока, выбираем разделы, принадлежащие инфоблокам выбранного типа if (!empty($arCurrentValues['IBLOCK_TYPE'])) { $arFilter['IBLOCK_TYPE'] = $arCurrentValues['IBLOCK_TYPE']; } // если уже выбран инфоблок, выбираем разделы только этого инфоблока if (!empty($arCurrentValues['IBLOCK_ID'])) { $arFilter['IBLOCK_ID'] = $arCurrentValues['IBLOCK_ID']; } $result = CIBlockSection::GetList( array('SORT' => 'ASC'), $arFilter ); while ($section = $result->Fetch()) { $arInfoBlockSections[$section['ID']] = '['.$section['ID'].'] '.$section['NAME']; } /* * Настройки компонента */ $arComponentParameters = array( 'GROUPS' => array( // кроме групп по умолчанию, добавляем свою группу настроек 'SEO_SETTINGS' => array( 'NAME' => 'Настройки SEO', 'SORT' => 800 ), ), 'PARAMETERS' => array( // выбор типа инфоблока 'IBLOCK_TYPE' => array( 'PARENT' => 'BASE', 'NAME' => 'Выберите тип инфоблока', 'TYPE' => 'LIST', 'VALUES' => $arIBlockType, 'REFRESH' => 'Y', ), // выбор самого инфоблока 'IBLOCK_ID' => array( 'PARENT' => 'BASE', 'NAME' => 'Выберите инфоблок', 'TYPE' => 'LIST', 'VALUES' => $arInfoBlocks, 'REFRESH' => 'Y', ), // показывать корневые разделы инфоблока? 'ROOT_SECTIONS' => array( 'PARENT' => 'BASE', 'NAME' => 'Показывать корневые разделы', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'Y', ), // выбор разделов инфоблока, откуда будем получать популярные элементы 'POPULAR_SECTIONS' => array( 'PARENT' => 'BASE', 'NAME' => 'Выберите разделы инфоблока для выборки популярных элементов', 'TYPE' => 'LIST', 'VALUES' => $arInfoBlockSections, 'MULTIPLE'=>'Y', 'REFRESH' => 'Y', ), // максимальное количество популярных элементов в разделе 'ELEMENT_COUNT' => array( 'PARENT' => 'DASE', 'NAME' => 'Максимальное количество элементов в разделе', 'TYPE' => 'STRING', 'DEFAULT' => '3', ), // использовать символьный код вместо ID; если отмечен этот checkbox, // в визуальном редакторе надо будет обязательно изменить SECTION_URL // и ELEMENT_URL, чтобы вместо #SECTION_ID# и #ELEMENT_ID# в шаблонах // ссылок использовались #SECTION_CODE# и #ELEMENT_CODE# 'USE_CODE_INSTEAD_ID' => array( 'PARENT' => 'URL_TEMPLATES', 'NAME' => 'Использовать символьный код вместо ID', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'N', ), // шаблон ссылки на страницу раздела 'SECTION_URL' => array( 'PARENT' => 'URL_TEMPLATES', 'NAME' => 'URL, ведущий на страницу с содержимым раздела', 'TYPE' => 'STRING', 'DEFAULT' => 'category/id/#SECTION_ID#/' ), // шаблон ссылки на страницу элемента 'ELEMENT_URL' => array( 'PARENT' => 'URL_TEMPLATES', 'NAME' => 'URL, ведущий на страницу с содержимым элемента', 'TYPE' => 'STRING', 'DEFAULT' => 'item/id/#ELEMENT_ID#/' ), // настройки SEO 'SET_PAGE_TITLE' => array( 'PARENT' => 'SEO_SETTINGS', 'NAME' => 'Устанавливать заголовок страницы из названия инфоблока', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'Y', ), 'SET_BROWSER_TITLE' => array( 'PARENT' => 'SEO_SETTINGS', 'NAME' => 'Устанавливать заголовок окна браузера из названия инфоблока', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'Y', ), // настройки кэширования 'CACHE_TIME' => array('DEFAULT'=>3600), 'CACHE_GROUPS' => array( 'PARENT' => 'CACHE_SETTINGS', 'NAME' => 'Учитывать права доступа', 'TYPE' => 'CHECKBOX', 'DEFAULT' => 'Y', ), ), );
<?php /* * Файл local/components/tokmakov/iblock.popular/component.php */ if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); /** @var CBitrixComponent $this */ /** @var array $arParams */ /** @var array $arResult */ /** @var string $componentPath */ /** @var string $componentName */ /** @var string $componentTemplate */ /** @global CDatabase $DB */ /** @global CUser $USER */ /** @global CMain $APPLICATION */ if (!CModule::IncludeModule('iblock')) { ShowError('Модуль «Информационные блоки» не установлен'); return; } if (!isset($arParams['CACHE_TIME'])) { $arParams['CACHE_TIME'] = 3600; } // тип инфоблока, из которого будем получать популярные элементы $arParams['IBLOCK_TYPE'] = trim($arParams['IBLOCK_TYPE']); // инфоблок, из которого будем получать популярные элементы $arParams['IBLOCK_ID'] = intval($arParams['IBLOCK_ID']); // максимальное кол-во разделов, из которых будем получать популярные элементы $arParams['SECTION_COUNT'] = intval($arParams['SECTION_COUNT']); if ($arParams['SECTION_COUNT'] <= 0) { $arParams['SECTION_COUNT'] = 5; } // максимальное количество популярных элементов в каждом разделе $arParams['ELEMENT_COUNT'] = intval($arParams['ELEMENT_COUNT']); if($arParams['ELEMENT_COUNT'] <= 0) { $arParams['ELEMENT_COUNT'] = 3; } $arParams['SECTION_URL'] = trim($arParams['SECTION_URL']); $arParams['ELEMENT_URL'] = trim($arParams['ELEMENT_URL']); // получаем данные об инфоблоке $rsIblock = CIBlock::GetByID($arParams['IBLOCK_ID']); $arResult['IBLOCK'] = $rsIblock ->GetNext(); $arResult['POPULAR_SECTIONS'] = array(); if ($this->StartResultCache(false, ($arParams['CACHE_GROUPS']==='N'? false: $USER->GetGroups()))) { /* * Получаем корневые разделы инфоблока, если это задано в настройках */ if ($arParams['ROOT_SECTIONS'] == 'Y') { // какие поля коневых разделов инфоблока выбираем $arSelect = array( 'ID', 'NAME', 'PICTURE', 'DESCRIPTION', 'DESCRIPTION_TYPE', 'SECTION_PAGE_URL' ); // условия выборки корневых разделов инфоблока $arFilter = array( 'IBLOCK_ID' => $arParams['IBLOCK_ID'], // идентификатор инфоблока 'IBLOCK_ACTIVE' => 'Y', // инфоблок должен быть активен 'SECTION_ID' => false, // получаем корневые разделы 'ACTIVE' => 'Y', // только активные разделы 'CHECK_PERMISSIONS' => 'Y', // проверять права доступа ); // сортировка $arSort = array( 'SORT' => 'ASC', ); // выполняем запрос к базе данных $rsSections = CIBlockSection::GetList($arSort, $arFilter, false, $arSelect); // устанавливаем шаблон пути для корневых разделов, вместо того, // который указан в настройках информационного блока $rsSections->SetUrlTemplates('', $arParams['SECTION_URL']); while ($arSection = $rsSections->GetNext()) { if (0 < $arSection['PICTURE']) { $arSection['PREVIEW_PICTURE'] = CFile::GetFileArray($arSection['PICTURE']); } else { $arSection['PREVIEW_PICTURE'] = false; } unset($arSection['PICTURE']); // получаем SEO-свойства очередного раздела $ipropValues = new \Bitrix\Iblock\InheritedProperty\SectionValues( $arParams['IBLOCK_ID'], $arSection['ID'] ); $arSection['IPROPERTY_VALUES'] = $ipropValues->getValues(); if ($arSection['PREVIEW_PICTURE']) { $arSection['PREVIEW_PICTURE']['ALT'] = $arSection['IPROPERTY_VALUES']['SECTION_PICTURE_FILE_ALT']; if ($arSection['PREVIEW_PICTURE']['ALT'] == '') { $arSection['PREVIEW_PICTURE']['ALT'] = $arSection['NAME']; } $arSection['PREVIEW_PICTURE']['TITLE'] = $arSection['IPROPERTY_VALUES']['[SECTION_PICTURE_FILE_TITLE']; if ($arSection['PREVIEW_PICTURE']['TITLE'] == '') { $arSection['PREVIEW_PICTURE']['TITLE'] = $arSection['NAME']; } } $arResult['ROOT_SECTIONS'][] = $arSection; } } /* * Получаем разделы инфоблока, откуда будем получать популярные элементы */ // какие поля разделов инфоблока выбираем $arSelect = array( 'ID', 'NAME', 'SECTION_PAGE_URL' ); // условия выборки разделов инфоблока $arFilter = array( 'IBLOCK_ID' => $arParams['IBLOCK_ID'], // идентификатор инфоблока 'IBLOCK_ACTIVE' => 'Y', // ифоблок должен быть активен 'SECTION_ID' => false, // только корневые разделы 'ACTIVE' => 'Y', // только активные разделы 'CHECK_PERMISSIONS' => 'Y', // проверять права доступа ); // если в настройках указаны разделы инфоблока, из которых надо // показывать популярные элемента, то уточняем условия выборки if (!empty($arParams['POPULAR_SECTIONS'])) { $arFilter['ID'] = $arParams['POPULAR_SECTIONS']; } // сортировка $arSort = array( 'SORT' => 'ASC', ); // выполняем запрос к базе данных $rsSections = CIBlockSection::GetList($arSort, $arFilter, false, $arSelect); // устанавливаем шаблон пути для разделов, вместо того, // который указан в настройках информационного блока $rsSections->SetUrlTemplates('', $arParams['SECTION_URL']); // какие поля популярных элементов инфоблока выбираем $arSelect = array( 'ID', 'CODE', 'IBLOCK_ID', 'NAME', 'PREVIEW_PICTURE', 'DETAIL_PAGE_URL', 'PREVIEW_TEXT_TYPE', 'PREVIEW_TEXT', 'SHOW_COUNTER' ); // условия выборки популярных элементов инфоблока $arFilter = array( 'ACTIVE' => 'Y', // только активные разделы 'IBLOCK_ID' => $arParams['IBLOCK_ID'], // идентификатор инфоблока 'ACTIVE_DATE' => 'Y', // фильтр по датам активности 'INCLUDE_SUBSECTIONS' => 'Y', // включая подразделы текущего раздела 'CHECK_PERMISSIONS' => 'Y', // проверять права доступа ); // сортировка популярных элементов $arSort = array( 'SHOW_COUNTER' => 'DESC', ); /* * Перебираем в цикле разделы и для каждого получаем популярные элементы */ while ($arSection = $rsSections->GetNext()) { $arSection['ITEMS'] = array(); // выбираем элементы текущего раздела $arFilter['SECTION_ID'] = $arSection['ID']; // выполняем запрос к базе данных $rsElements = CIBlockElement::GetList( $arSort, $arFilter, false, array('nTopCount' => $arParams['ELEMENT_COUNT']), $arSelect ); // устанавливаем шаблон пути для элемента, вместо того, // который указан в настройках информационного блока $rsElements->SetUrlTemplates($arParams['ELEMENT_URL']); while($arElement = $rsElements->GetNext()) { // получаем SEO-свойства выбранного элемента $ipropValues = new Bitrix\Iblock\InheritedProperty\ElementValues( $arElement['IBLOCK_ID'], $arElement['ID'] ); $arElement['IPROPERTY_VALUES'] = $ipropValues->getValues(); if (0 < $arElement['PREVIEW_PICTURE']) { $arElement['PREVIEW_PICTURE'] = CFile::GetFileArray($arElement['PREVIEW_PICTURE']); } else { $arElement['PREVIEW_PICTURE'] = false; } if ($arElement['PREVIEW_PICTURE']) { $arElement['PREVIEW_PICTURE']['ALT'] = $arElement['IPROPERTY_VALUES']['ELEMENT_PREVIEW_PICTURE_FILE_ALT']; if ($arElement['PREVIEW_PICTURE']['ALT'] == '') { $arElement['PREVIEW_PICTURE']['ALT'] = $arElement['NAME']; } $arElement['PREVIEW_PICTURE']['TITLE'] = $arElement['IPROPERTY_VALUES']['ELEMENT_PREVIEW_PICTURE_FILE_TITLE']; if ($arElement['PREVIEW_PICTURE']['TITLE'] == '') { $arElement['PREVIEW_PICTURE']['TITLE'] = $arElement['NAME']; } } $arSection['ITEMS'][] = $arElement; } $arResult['POPULAR_SECTIONS'][] = $arSection; } $this->SetResultCacheKeys( array( 'IBLOCK', ) ); $this->IncludeComponentTemplate(); } // устанавливаем заголовок окна браузера из названия инфоблока if ($arParams['SET_BROWSER_TITLE']) { $APPLICATION->SetPageProperty('title', $arResult['IBLOCK']['NAME']); } // устанавливаем заголовок страницы из названия инфоблока if ($arParams['SET_PAGE_TITLE']) { $APPLICATION->SetTitle($arResult['IBLOCK']['NAME']); }
<?php /* * Файл local/components/tokmakov/iblock.popular/templates/.default/template.php */ if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); /** @var array $arParams */ /** @var array $arResult */ /** @global CMain $APPLICATION */ /** @global CUser $USER */ /** @global CDatabase $DB */ /** @var CBitrixComponentTemplate $this */ /** @var string $templateName */ /** @var string $templateFile */ /** @var string $templateFolder */ /** @var string $componentPath */ /** @var CBitrixComponent $component */ // шаблон компонента голосует против композита $this->setFrameMode(false); ?> <h1><?= $arResult['NAME']; ?></h1> <?php if (!empty($arResult['ROOT_SECTIONS'])): ?> <div id="iblock-root-sections"> <?php foreach ($arResult['ROOT_SECTIONS'] as $arSection): /* корневые разделы инфоблока */ ?> <article> <a href="<?= $arSection['SECTION_PAGE_URL']; ?>"> <img src="<?= $arSection['PREVIEW_PICTURE']['SRC']; ?>" alt="<?= $arSection['PREVIEW_PICTURE']['ALT']; ?>" title="<?= $arSection['PREVIEW_PICTURE']['TITLE']; ?>" /> </a> <h2><a href="<?= $arSection['SECTION_PAGE_URL']; ?>"><?= $arSection['NAME']; ?></a></h2> <?php if (!empty($arSection['DESCRIPTION'])): ?> <p><?= $arSection['DESCRIPTION']; ?></p> <?php endif; ?> </article> <?php endforeach; ?> </div> <?php endif; ?> <h2>Самое популярное</h2> <div id="iblock-popular-items"> <?php foreach ($arResult['POPULAR_SECTIONS'] as $arSection): /* популярные разделы инфоблока */ ?> <section> <h3><a href="<?= $arSection['SECTION_PAGE_URL']; ?>"><?= $arSection['NAME']; ?></a></h3> <?php foreach ($arSection['ITEMS'] as $arItem): /* популярные элементы для каждого раздела */ ?> <article> <a href="<?= $arItem['DETAIL_PAGE_URL']; ?>"> <img src="<?= $arItem['PREVIEW_PICTURE']['SRC']; ?>" alt="<?= $arItem['PREVIEW_PICTURE']['ALT']; ?>" title="<?= $arItem['PREVIEW_PICTURE']['TITLE']; ?>" /> </a> <h4><a href="<?= $arItem['DETAIL_PAGE_URL']; ?>"><?= $arItem['NAME']; ?></a></h4> <p>Просмотров: <?= $arItem['SHOW_COUNTER'] ? $arItem['SHOW_COUNTER'] : 0; ?></p> </article> <?php endforeach; ?> </section> <?php endforeach; ?> </div>
/*
* Файл local/components/tokmakov/iblock.popular/templates/.default/style.css
*/
#iblock-root-sections {
}
#iblock-root-sections > article {
border: 1px solid #d1d1d1;
padding: 10px;
border-radius: 10px;
overflow: hidden;
margin-bottom: 15px;
background: #f5f5f5;
}
#iblock-root-sections > article > h2 {
margin: -5px 0 5px 120px;
}
#iblock-root-sections > article > p {
margin: 5px 0 0 120px;
}
#iblock-root-sections > article > a > img {
width: 100px;
height: 100px;
float: left;
}
#iblock-popular-items {
}
#iblock-popular-items > section {
border: 1px solid #d1d1d1;
padding: 10px;
border-radius: 10px;
overflow: hidden;
margin-bottom: 15px;
background: #f5f5f5;
}
#iblock-popular-items > section > h3 {
margin: 0 0 7px 0;
font-size: 18px;
}
#iblock-popular-items > section > article {
float: left;
width: 24%;
box-sizing: border-box;
border: 1px solid #d1d1d1;
padding: 10px;
border-radius: 10px;
background: #fff;
margin-right: 1.33333%;
}
#iblock-popular-items > section > article:last-child {
margin-right: 0;
}
#iblock-popular-items > section > article > h4 {
margin: 5px 0 5px 0;
font-size: 14px;
min-height: 30px;
line-height: 15px;
}
#iblock-popular-items > section > article > p {
margin: 0;
font-size: 12px;
color: #999;
}
Пример вызова компонента:
<?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); $APPLICATION->SetTitle("Статьи о домашних животных"); ?> <?php $APPLICATION->IncludeComponent( "tokmakov:iblock.popular", "", Array( "CACHE_GROUPS" => "Y", "CACHE_TIME" => "3600", "CACHE_TYPE" => "A", "ELEMENT_COUNT" => "3", "ELEMENT_URL" => "item/id/#ELEMENT_ID#/", "IBLOCK_ID" => "5", "IBLOCK_TYPE" => "content", "POPULAR_SECTIONS" => array(), "ROOT_SECTIONS" => "Y", "SECTION_URL" => "category/id/#SECTION_ID#/", "SET_BROWSER_TITLE" => "Y", "SET_PAGE_TITLE" => "Y", "USE_CODE_INSTEAD_ID" => "N" ) ); ?> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
- Битрикс. Создание комплексного компонента. Часть 4 из 4
- Битрикс. Создание комплексного компонента. Часть 3 из 4
- Битрикс. Создание комплексного компонента. Часть 1 из 4
- Битрикс. Работа с инфоблоками в старом ядре
- Битрикс. Работа с инфоблоками в новом ядре
- Битрикс. Работа с шаблонами SEO
- Битрикс. Создание простого компонента. Часть 2 из 2
Поиск: CMS • Web-разработка • Битрикс • Инфоблок • Компонент • Раздел инфоблока • Шаблон компонента • Элемент инфоблока