В 10 уроке мы сделаем компонент для 2-х колоночного списка на главной странице:
Выводится этот блок следующей разметкой из макета:
<h4 class="indent-1">our Capabilities:</h4>
<p class="lead">Praesent vestibulum molestie lacus. Aenean nonummy hendrerit mauris. Phasellus porta. Fusce suscipit varius mi. Cum sociis natoque penatibus et magnis dis parturien.</p>
<div class="lists">
<div class="span4 left-0">
<ul class="list">
<li><a href="#">Praesent vestibulum molestie lacus aenean</a></li>
<li><a href="#">nonummy hendrerit mauris</a></li>
<li><a href="#">Phasellus porta fusce suscipit varius mi</a></li>
<li><a href="#">Cum sociis natoque penatibus et magnis dis</a></li>
</ul>
</div>
<div class="span4">
<ul class="list">
<li><a href="#">Praesent vestibulum molestie lacus aenean</a></li>
<li><a href="#">nonummy hendrerit mauris</a></li>
<li><a href="#">Phasellus porta fusce suscipit varius mi</a></li>
<li><a href="#">Cum sociis natoque penatibus et magnis dis</a></li>
</ul>
</div>
</div>
<a href="#" class="link">More Info</a>
Обратим внимание на то, что при уменьшении ширины колонки располагаются одна над другой, т.е. логически правая колонка списка - продолжение левой:
Раздел "Our Capabilities" расположен на 3 уровне структуры сайта (если судить по главному меню) и его содержимое не представлено на макетах, поэтому мы не знаем что за элементы представлены в списке:
- элементы инфоблока
- разделы инфоблока
- разделы сайта
- разделы 1й страницы (например со ссылками-якорями на конкретные места)
Обычно в таких случаях имеет смысл оставить статическую вёрстку (возможно вынеся её во включаемую область, дабы защитить от неквалифицированных редакторов), однако мы в целях обучения сделаем 2 компонента.
2-х колоночный список элементов инфоблока
Возьмём наш любимый компонент bitrix:news.list и шаблон .default скопируем в шаблон сайта, переименовав в 2_columns.
Разделение списка на 2 части осуществит код:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
// Пролог
$d = ceil(count($arResult["ITEMS"])/2);
// Делим число элементов списка на 2 и округляем в большую сторону.
$i = 0;
// Обнуляем счётчик
?>
<ul><?foreach($arResult["ITEMS"] as $arItem):?>
<!-- Начинаем цикл перебора элементов. Открыли список -->
<?if( $i > 0 && $i%$d == 0):?></ul><ul><?endif;?>
<!-- Проверяем положение счётчика. Как только счётчик дойдёт до середины списка (определена выше) закрываем список и открываем новый -->
<li><?echo $arItem["NAME"]?></li>
<!-- Выводим элемент списка -->
<?$i++;?>
<!-- Увеличиваем счётчик на 1. После этого можно будет цикл завершить и окончательно закрыть список -->
<?endforeach;?>
</ul>
ceil используется для округления в большую сторону, т.е. если список нечётный, то в первом/левом столбце будет на 1 элемент больше. Если нужно получить больше элементов во втором столбце - округлите результат деления в меньшую сторону с помощью floor.
Так же обращаем внимание, что делитель можно вынести в параметры и заменить на другое число. Тогда количество столбцов изменится. Мы не делаем этого потому, что у нас есть жёсткая привязка к ширине столбца в вёрстке этих блоков - 3 таких блока просто не вместятся в сетку!
Создадим 4 параметра (в .parameters,php), для задания элементов, которые может быть полезным вывести в рамках компонента, а не оставлять статическими:
- Заголовок блока
- Вводный текст
- Текст ссылки "More" после блока
- Адрес ссылки "More" после блока
1 и 2 параметры будем проверять на заполненность, и если они пусты, не будем выводить пустую разметку.
3 и 4 параметр следует проверять оба на пустоту для вывода ссылки:
<?if (!empty($arParams["2_COL_MORE_LINK"]) && !empty($arParams["2_COL_MORE_NAME"])):?>
Не забудем про языковые фразы для всех 4 параметров.
Итоговый шаблон компонента будет выглядеть:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
$d = ceil(count($arResult["ITEMS"])/2);
$i = 0;
?>
<?if (!empty($arParams["2_COL_TITLE"])):?><h4 class="indent-1"><?=$arParams['2_COL_TITLE']?>:</h4><?endif?>
<?if (!empty($arParams["2_COL_INTRO_TEXT"])):?><p class="lead"><?=$arParams['2_COL_INTRO_TEXT']?></p><?endif?>
<div class="lists">
<div class="span4 left-0">
<ul class="list"><?foreach($arResult["ITEMS"] as $arItem):?>
<?
$this->AddEditAction($arItem['ID'], $arItem['EDIT_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_EDIT"));
$this->AddDeleteAction($arItem['ID'], $arItem['DELETE_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_DELETE"), array("CONFIRM" => GetMessage('CT_BNL_ELEMENT_DELETE_CONFIRM')));
?>
<?if( $i > 0 && $i%$d == 0):?></ul></div><div class="span4"><ul class="list"><?endif;?>
<li id="<?=$this->GetEditAreaId($arItem['ID']);?>"><a href="<?echo $arItem["DETAIL_PAGE_URL"]?>"><?echo $arItem["NAME"]?></a></li>
<?$i++;?>
<?endforeach;?></ul>
</div>
</div>
<?if (!empty($arParams["2_COL_MORE_LINK"]) && !empty($arParams["2_COL_MORE_NAME"])):?><a href="<?=$arParams['2_COL_MORE_LINK']?>" class="link"><?=$arParams['2_COL_MORE_NAME']?></a><?endif?>
Осталось только вызвать компонент на главной странице
<?$APPLICATION->IncludeComponent("bitrix:news.list", "2_columns", array(
"IBLOCK_TYPE" => "-",
"IBLOCK_ID" => "NEWS",
"NEWS_COUNT" => "20",
"SORT_BY1" => "ACTIVE_FROM",
"SORT_ORDER1" => "DESC",
"SORT_BY2" => "SORT",
"SORT_ORDER2" => "ASC",
"FILTER_NAME" => "",
"FIELD_CODE" => array(
0 => "",
1 => "",
),
"PROPERTY_CODE" => array(
0 => "",
1 => "",
),
"CHECK_DATES" => "Y",
"DETAIL_URL" => "",
"AJAX_MODE" => "N",
"AJAX_OPTION_JUMP" => "N",
"AJAX_OPTION_STYLE" => "Y",
"AJAX_OPTION_HISTORY" => "N",
"CACHE_TYPE" => "A",
"CACHE_TIME" => "36000000",
"CACHE_FILTER" => "N",
"CACHE_GROUPS" => "Y",
"PREVIEW_TRUNCATE_LEN" => "",
"ACTIVE_DATE_FORMAT" => "d.m.Y",
"SET_TITLE" => "Y",
"SET_STATUS_404" => "N",
"INCLUDE_IBLOCK_INTO_CHAIN" => "Y",
"ADD_SECTIONS_CHAIN" => "Y",
"HIDE_LINK_WHEN_NO_DETAIL" => "N",
"PARENT_SECTION" => "",
"PARENT_SECTION_CODE" => "",
"INCLUDE_SUBSECTIONS" => "Y",
"DISPLAY_TOP_PAGER" => "N",
"DISPLAY_BOTTOM_PAGER" => "Y",
"PAGER_TITLE" => "Новости",
"PAGER_SHOW_ALWAYS" => "Y",
"PAGER_TEMPLATE" => "",
"PAGER_DESC_NUMBERING" => "N",
"PAGER_DESC_NUMBERING_CACHE_TIME" => "36000",
"PAGER_SHOW_ALL" => "Y",
"2_COL_TITLE" => "Наши Новости",
"2_COL_INTRO_TEXT" => "В данном двухколоночном списке представлены возможности данного шаблона компонента, которые вы можете штатно использовать без дополнительных доработок. Для демонстрации используется инфоблок новостей, поскольку нет оснований для создания ещё одного инфоблока.",
"2_COL_MORE_NAME" => "Ещё",
"2_COL_MORE_LINK" => "/about/news/",
"AJAX_OPTION_ADDITIONAL" => ""
),
false
);?>
Фактически, мы реализовали вывод блока двухколоночного списка элементов инфоблока! С помощью старого доброго new.list.
2-х колоночный список разделов инфоблока
Возьмём компонент bitrix:catalog.section.list и скопируем шаблон компонента .default в шаблон сайта, переименовав в 2_columns.
Обратим внимание, что данный компонент умеет выводить несколько уровней разделов инфоблока и даже сохранять их иерархическую структуру.
К сожалению, нельзя эффективно разработать шаблон в условиях общей задачи без конкретизации условий (когда может 2-3 и более уровней вложенности и нет понимания у как будут расположены друг относительно друга разделы) так, чтобы это ещё и выглядело красиво.
В связи с этим, мы сведём задачу к более простой и будем отображать все разделы на одном уровне вне зависимости от их реального положения, оставив возможность в настройках компонента задать уровень вложенности:
В этом случае шаблон компонента будет практически идентичен шаблону компонента списка новостей (отличие лишь в переборе массива по ключу $arResult["SECTIONS"] вместо $arResult["ITEMS"]).
Аналогично предыдущей части вводятся и параметры компонента (не забудьте про их языковые файлы) в .parameters.php.
Добавим лишь небольшую фишку из дефолтного компонента списка разделов:
<?if($arParams["COUNT_ELEMENTS"]):?> (<?=$arSection["ELEMENT_CNT"]?>)<?endif;?>
Этот код выведет после названия раздела инфоблока число находящихся в нём элементов (при условии, что в параметрах компонента разрешён вывод этой информации):
Тогда полный код шаблона будет выглядеть следующим образом:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
$d = ceil(count($arResult["SECTIONS"])/2);
$i = 0;
?>
<?if (!empty($arParams["2_COL_TITLE"])):?><h4 class="indent-1"><?=$arParams['2_COL_TITLE']?>:</h4><?endif?>
<?if (!empty($arParams["2_COL_INTRO_TEXT"])):?><p class="lead"><?=$arParams['2_COL_INTRO_TEXT']?></p><?endif?>
<div class="lists">
<div class="span4 left-0">
<ul class="list"><?foreach($arResult["SECTIONS"] as $arSection):?>
<?
$this->AddEditAction($arSection['ID'], $arSection['EDIT_LINK'], CIBlock::GetArrayByID($arSection["IBLOCK_ID"], "ELEMENT_EDIT"));
$this->AddDeleteAction($arSection['ID'], $arSection['DELETE_LINK'], CIBlock::GetArrayByID($arSection["IBLOCK_ID"], "ELEMENT_DELETE"), array("CONFIRM" => GetMessage('CT_BNL_ELEMENT_DELETE_CONFIRM')));
?>
<?if( $i > 0 && $i%$d == 0):?></ul></div><div class="span4"><ul class="list"><?endif;?>
<li id="<?=$this->GetEditAreaId($arSection['ID']);?>"><a href="<?=$arSection["SECTION_PAGE_URL"]?>"><?echo $arSection["NAME"]?><?if($arParams["COUNT_ELEMENTS"]):?> (<?=$arSection["ELEMENT_CNT"]?>)<?endif;?></a></li>
<?$i++;?>
<?endforeach;?></ul>
</div>
</div>
<?if (!empty($arParams["2_COL_MORE_LINK"]) && !empty($arParams["2_COL_MORE_NAME"])):?><a href="<?=$arParams['2_COL_MORE_LINK']?>" class="link"><?=$arParams['2_COL_MORE_NAME']?></a><?endif?>
И останется только вызвать компонент на главной странице:
<?$APPLICATION->IncludeComponent("bitrix:catalog.section.list", "2_columns", array(
"IBLOCK_TYPE" => "-",
"IBLOCK_ID" => "3",
"SECTION_ID" => $_REQUEST["SECTION_ID"],
"SECTION_CODE" => "",
"COUNT_ELEMENTS" => "Y",
"TOP_DEPTH" => "3",
"SECTION_FIELDS" => array(
0 => "",
1 => "",
),
"SECTION_USER_FIELDS" => array(
0 => "",
1 => "",
),
"SECTION_URL" => "",
"CACHE_TYPE" => "A",
"CACHE_TIME" => "36000000",
"CACHE_GROUPS" => "Y",
"ADD_SECTIONS_CHAIN" => "Y",
"2_COL_TITLE" => "Наши Возможности",
"2_COL_INTRO_TEXT" => "В данном двухколоночном списке представлены возможности данного шаблона, которые вы можете штатно использовать без дополнительных доработок. В отличие от компонента представленного выше, это компонент вывода разделов инфоблока.",
"2_COL_MORE_NAME" => "Ещё",
"2_COL_MORE_LINK" => "#"
), false
);?>
Обратите внимание, что этот компонент, в отличие от компонента списка новостей не умеет работать с символьным кодом инфоблока!!! Необходимо указать ID! Это важно, если вы переносите код с проекта на проект и там разная нумерация инфоблоков!
В демо-материалах к данному уроку вы увидите на главной странице оба этих компонента.
Так же обратите внимание, что в целях демонстрации возможностей этих компонентов мы обновили набор демо-данных для инфоблока новостей (там появились новые элементы и разделы), так что если вы произвели импорт в предыдущих уроках - просто повторите процесс для инфоблока с кодом NEWS (у нас его ID=3).
На этом мы завершаем интеграцию компонентов главной страницы. Оставшийся контент проще разместить в виде статической вёрстки, чем разрабатывать сколько-нибудь универсальный шаблон.
Одном из последующих уроков мы создадим шаблоны страниц, которые позволят создавать заготовки с контентом, для упрощения создания такой страницы контент-редактором.
Демо-материалы и результаты урока, как всегда размещены в нашем репозитории на