- PVSM.RU - https://www.pvsm.ru -
Уважаемый читатель, данная статья является по сути своей продолжением статьи «Как сверстать веб-страницу. Часть 2 — Bootstrap» [1] и здесь мы отойдём от собственно вёрстки, занявшись интеграцией HTML шаблона в CMS 1С-Битрикс.
В предыдущей части читатель Mirantus [2] сверстал шаблон Corporate Blue [3] от студии Pcklaboratory с помощью Bootstrap 3 [4].
Для данной статьи мы воспользуемся одним из форков репозитория на GitHub [5], приведённого в конце предыдущей статьи, поскольку в нём были исправлены некоторые баги.
Шаблон сайта с точки зрения 1С-Битрикс – это папка с набором определённых файлов внутри, поэтому шаблон может быть создан как через файловую структуру (инструментами 1С-Битрикс, по FTP или SSH), так и с помощью раздела.
Если смотреть на шаблон через административный раздел 1С-Битрикс (Настройки>>Настройки продукта>>Сайты>>Шаблоны Сайтов), то мы увидим шаблон целиком, header.php будет отделён от footer.php с помощью тега #WORK_AREA#.
Мы легко можем выделить на странице контент, который будем помещать в рабочую область (т.е. он будет уникальным для каждой страницы):
Таким образом мы можем распределить код index.html из исходного статического шаблона по трём файлам:
<!DOCTYPE html>
<html>
<head>
<title>Whitesquare</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/styles.css" rel="stylesheet">
<link href="http://fonts.googleapis.com/css?family=Oswald:400,300" rel="stylesheet">
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper container">
<header>
<form name="search" action="#" method="get" class="form-inline form-search pull-right">
<div class="input-group">
<label class="sr-only" for="searchInput">Search</label>
<input class="form-control" id="searchInput" type="text" name="search" placeholder="Search">
<div class="input-group-btn">
<button type="submit" class="btn btn-primary">GO</button>
</div>
</div>
</form>
<a href="/"><img src="images/logo.png" alt="Whitesquare logo"></a>
</header>
<nav class="navbar navbar-default">
<ul class="nav navbar-nav">
<li><a href="/home/">Home</a></li>
<li class="active"><a href="/about/">About us</a></li>
<li><a href="/services/">Services</a></li>
<li><a href="/partners/">Partners</a></li>
<li><a href="/customers/">Customers</a></li>
<li><a href="/projects/">Projects</a></li>
<li><a href="/careers/">Careers</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav>
<div class="heading">
<h1>About us</h1>
</div>
<div class="row">
<aside class="col-md-7">
<ul class="list-group submenu">
<li class="list-group-item active">Lorem ipsum</li>
<li class="list-group-item"><a href="/donec/">Donec tincidunt laoreet</a></li>
<li class="list-group-item"><a href="/vestibulum/">Vestibulum elit</a></li>
<li class="list-group-item"><a href="/etiam/">Etiam pharetra</a></li>
<li class="list-group-item"><a href="/phasellus/">Phasellus placerat</a></li>
<li class="list-group-item"><a href="/cras/">Cras et nisi vitae odio</a></li>
</ul>
<div class="panel panel-primary">
<div class="panel-heading">Our offices</div>
<div class="panel-body">
<img src="images/map.png" class="img-responsive" alt="Our offices">
</div>
</div>
</aside>
<section class="col-md-17">
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");?>
<div class="jumbotron">
<blockquote>
<p>
“Quisque in enim velit, at dignissim est. nulla ul corper, dolor ac pellentesque
placerat, justo tellus gravida erat, vel porttitor libero erat.”
</p>
<small>John Doe, Lorem Ipsum</small>
</blockquote>
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean non neque ac sem accumsan rhoncus ut
ut turpis. In hac habitasse platea dictumst. Proin eget nisi erat, et feugiat arcu. Duis semper
porttitor lectus, ac pharetra erat imperdiet nec. Morbi interdum felis nulla. Aenean eros orci,
pellentesque sed egestas vitae, auctor aliquam nisi. Nulla nec libero eget sem rutrum iaculis.
Quisque in enim velit, at dignissim est. Nulla ullamcorper, dolor ac pellentesque placerat, justo
tellus gravida erat, vel porttitor libero erat condimentum metus. Donec sodales aliquam orci id
suscipit. Proin sed risus sit amet massa ultrices laoreet quis a erat. Aliquam et metus id erat
vulputate egestas. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus
mus.
</p>
<p>
Donec vel nisl nibh. Aenean quam tortor, tempus sit amet mattis dapibus, egestas tempor dui. Duis
vestibulum imperdiet risus pretium pretium. Nunc vitae porta ligula. Vestibulum sit amet nulla quam.
Aenean lacinia, ante vitae sodales sagittis, leo felis bibendum neque, mattis sagittis neque urna
vel magna. Sed at sem vitae lorem blandit feugiat.
</p>
<p>
Donec vel orci purus, ut ornare orci. Aenean rutrum pellentesque quam. Quisque gravida adipiscing
augue, eget commodo augue egestas varius. Integer volutpat, tellus porta tincidunt sodales, lacus
est tempus odio, fringilla blandit tortor lectus ut sem. Pellentesque nec sem lacus, sit amet
consequat neque. Etiam varius urna quis arcu cursus in consectetur dui tincidunt. Quisque arcu orci,
lacinia eget pretium vel, iaculis pellentesque nibh. Etiam cursus lacus eget neque viverra
vestibulum. Aliquam erat volutpat. Duis pulvinar tellus ut urna facilisis mollis. Maecenas ac
pharetra dui. Pellentesque neque ante, luctus eget congue eget, rhoncus vel mauris. Duis nisi magna,
aliquet a convallis non, venenatis at nisl. Nunc at quam eu magna malesuada dignissim. Duis bibendum
iaculis felis, eu venenatis risus sodales non. In ligula mi, faucibus eu tristique sed, vulputate
rutrum dolor.
</p>
<div class="row">
<div class="col-md-12">
<img src="images/about-1.png" alt="" class="thumbnail">
</div>
<div class="col-md-12">
<img src="images/about-2.png" alt="" class="thumbnail">
</div>
</div>
<h2>Our team</h2>
<div class="team">
<div class="row">
<div class="col col-md-4">
<img src="images/team/Doe.jpg" alt="John Doe" class="thumbnail">
<div class="caption">
<h3>John Doe</h3>
<p>ceo</p>
</div>
</div>
<div class="col col-md-4 col-md-offset-1">
<img src="images/team/Pittsley.jpg" alt="Saundra Pittsley" class="thumbnail">
<div class="caption">
<h3>Saundra Pittsley</h3>
<p>team leader</p>
</div>
</div>
<div class="col col-md-4 col-md-offset-1">
<img src="images/team/Simser.jpg" alt="Julio Simser" class="thumbnail">
<div class="caption">
<h3>Julio Simser</h3>
<p>senior developer</p>
</div>
</div>
<div class="col col-md-4 col-md-offset-1">
<img src="images/team/Venuti.jpg" alt="Margery Venuti" class="thumbnail">
<div class="caption">
<h3>Margery Venuti</h3>
<p>senior developer</p>
</div>
</div>
<div class="col col-md-4 col-md-offset-1">
<img src="images/team/Tondrea.jpg" alt="Fernando Tondrea" class="thumbnail">
<div class="caption">
<h3>Fernando Tondrea</h3>
<p>developer</p>
</div>
</div>
</div>
<div class="row">
<div class="col col-md-4">
<img src="images/team/Nobriga.jpg" alt="Ericka Nobriga" class="thumbnail">
<div class="caption">
<h3>Ericka Nobriga</h3>
<p>art director</p>
</div>
</div>
<div class="col col-md-4 col-md-offset-1">
<img src="images/team/Rousselle.jpg" alt="Cody Rousselle" class="thumbnail">
<div class="caption">
<h3>Cody Rousselle</h3>
<p>senior ui designer</p>
</div>
</div>
<div class="col col-md-4 col-md-offset-1">
<img src="images/team/Wollman.jpg" alt="Erik Wollman" class="thumbnail">
<div class="caption">
<h3>Erik Wollman</h3>
<p>senior ui designer</p>
</div>
</div>
<div class="col col-md-4 col-md-offset-1">
<img src="images/team/Shoff.jpg" alt="Dona Shoff" class="thumbnail">
<div class="caption">
<h3>Dona Shoff</h3>
<p>ux designer</p>
</div>
</div>
<div class="col col-md-4 col-md-offset-1">
<img src="images/team/Brunton.jpg" alt="Darryl Brunton" class="thumbnail">
<div class="caption">
<h3>Darryl Brunton</h3>
<p>ui designer</p>
</div>
</div>
</div>
</div>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>
</section>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-md-8 twitter">
<h3>Twitter feed</h3>
<time datetime="2012-10-23"><a href="#">23 oct</a></time>
<p>
In ultricies pellentesque massa a porta. Aliquam ipsum enim, hendrerit ut porta nec, ullamcorper et nulla. In eget mi dui, sit amet scelerisque nunc. Aenean aug
</p>
</div>
<div class="col-md-4 sitemap">
<h3>Sitemap</h3>
<div class="row">
<div class="col-md-12">
<a href="/home/">Home</a>
<a href="/about/">About</a>
<a href="/services/">Services</a>
</div>
<div class="col-md-12">
<a href="/partners/">Partners</a>
<a href="/customers/">Support</a>
<a href="/contact/">Contact</a>
</div>
</div>
</div>
<div class="col-md-4 social">
<h3>Social networks</h3>
<a href="http://twitter.com/" class="social-icon twitter"></a>
<a href="http://facebook.com/" class="social-icon facebook"></a>
<a href="http://plus.google.com/" class="social-icon google-plus"></a>
<a href="http://vimeo.com/" class="social-icon-small vimeo"></a>
<a href="http://youtube.com/" class="social-icon-small youtube"></a>
<a href="http://flickr.com/" class="social-icon-small flickr"></a>
<a href="http://instagram.com/" class="social-icon-small instagram"></a>
<a href="/rss/" class="social-icon-small rss"></a>
</div>
<div class="col-md-8 footer-logo">
<a href="/"><img src="images/footer-logo.png" alt="Whitesquare logo"></a>
<p>
Copyright © 2012 Whitesquare. A
<a href="http://pcklab.com">pcklab</a> creation
</p>
</div>
</div>
</div>
</footer>
</body>
</html>
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
IncludeTemplateLangFile(__FILE__);?>
<title><? $APPLICATION->ShowTitle(false); ?></title>
<h1><?$APPLICATION->ShowTitle()?></h1>
Как видите используютcя разные параметры для вызова одной отложенной функции, чтобы можно было задать разные значения для заголовка браузера и заголовка видимой части страницы, если это потребуется SEO специалистам.
<?$APPLICATION->ShowMeta("keywords")?>
<?$APPLICATION->ShowMeta("description")?>
<link href="<?=SITE_TEMPLATE_PATH?>/css/styles.css" rel="stylesheet">
…
<a href="/"><img src="<?=SITE_TEMPLATE_PATH?>/images/logo.png" alt="Whitesquare logo"></a>
…
<img src="<?=SITE_TEMPLATE_PATH?>/images/map.png" class="img-responsive" alt="Our offices">
…
<a href="/"><img src="<?=SITE_TEMPLATE_PATH?>/images/footer-logo.png" alt="Whitesquare logo"></a>
Аналогичным образом мы можем использовать SITE_TEMPLATE_PATH и в index.php, однако следует помнить о том, что при смене шаблона в настройках сайта, применяемого к странице, изменится и этот путь!
<?
$APPLICATION->ShowHead();
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH.'/css/styles.css');
$APPLICATION->SetAdditionalCSS('http://fonts.googleapis.com/css?family=Oswald:400,300');
?>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
Фактически мы создали статичный HTML каркас с минимальным набором элементов 1С-Битрикс, который уже работает.
Дальнейшая наша задача – перевод отдельных функциональных блоков на работу с компонентами 1С-Битрикс.
В рамках данной статьи мы остановимся только на процессе интеграции вёрстки со стандартными компонентами 1С-Битрикс. Мы не будем создавать свои компоненты и не будем кастомизировать типовые.
Мы создадим отдельную страницу (например, 1.php) на которой будем размещать по 1 компоненту для упрощения работы средствами 1С-Битрикс.
Иногда для дальнейшей работы больше подходит один из шаблонов компонента, поставляемых вместе с системой. Тогда имеет смысл посмотреть каждый из них в работе. Это можно сделать в визуальном редакторе по нажатию на кнопку шестерёнки:
Компонент включаемой области позволяет вложить внутрь себя любой текст, HTML или php код, а так же другие компоненты и вывести этот контент для определённой страницы, раздела или везде, где вызывается включаемая область.
Для всех указанных выше объектов мы считаем рациональным использование включаемой области с целью вынести эти блоки из шаблона. Т.е. для их редактирования по прежнему необходимо будет владеть минимумом познаний в HTML.
Профессионалы могут возразить, что для блока с кнопками соц сетей следовало бы сделать свой компонент, однако нам это кажется не рациональным. Проще загнать этот блок за 10 минут во включаемую область и отредактировать при необходимости, ведь адрес сообщества Facebook не меняется каждый день!
Все эти области будут выводиться на всём сайте, поэтому создадим в шаблоне новую папку include, где будем складывать файлы включаемых областей:
Код вызова компонента включаемой области будет выглядеть в этом случае так:
<?$APPLICATION->IncludeComponent(
"bitrix:main.include",
"",
Array(
"AREA_FILE_SHOW" => "file",
"PATH" => SITE_TEMPLATE_PATH."/include/bottom-logo.php",
"EDIT_TEMPLATE" => ""
),
false
);?>
Внутри файла включаемой области просто помещаем кусок HTML кода:
<a href="/"><img src="<?=SITE_TEMPLATE_PATH?>/images/footer-logo.png" alt="Whitesquare logo"></a>
Мы не будем в данной статье рассматривать вопрос интеграции Twitter Ленты, поскольку самое простое решение – положить виджет твиттера во включаемую область, аналогично описанным выше решениям.
Так же в Marketplace 1С-Битрикс хватает компонентов, выводящих твиттер ленту, которыми вы так же можете воспользоваться.
Мы воспользовались компонентом bitrix:search.form и скопировали suggest шаблон компонента в шаблон сайта.
HTML код шаблона компонента находится в файле /bitrix/templates/whitesquare-bootstrap/components/bitrix/search.form/top/template.php
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<div class="search-form">
<form action="<?=$arResult["FORM_ACTION"]?>">
<?$APPLICATION->IncludeComponent(
"bitrix:search.suggest.input",
"",
array(
"NAME" => "q",
"VALUE" => "",
"INPUT_SIZE" => 15,
"DROPDOWN_SIZE" => 10,
),
$component, array("HIDE_ICONS" => "Y")
);?> <input name="s" type="submit" value="<?=GetMessage("BSF_T_SEARCH_BUTTON");?>" />
</form>
</div>
Как видим, у нас не простой, а комплексный компонент (т.е. компонент в состав которого входят другие компоненты). В данном случае это сама форма в которую производится ввод поискового запроса.
Скопируем её шаблон в шаблон сайта.
К сожалению, это не очень красиво – в публичке мы используем 1 компонент, а шаблонов у нас 2. Воспользуемся обычной схемой для комплексных компонентов:
<?$APPLICATION->IncludeComponent(
"bitrix:search.suggest.input",
"top",
array(
"NAME" => "q",
"VALUE" => "",
"INPUT_SIZE" => 15,
"DROPDOWN_SIZE" => 10,
),
$component, array("HIDE_ICONS" => "Y")
);?>
Итак, мы видим, что в отличие от цельного блока поиска в вёрстке в архитектуре 1С-Битрикс наша форма будет состоять из 2 вложенных шаблонов (комплексного и простого) компонентов.
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<form name="search" action="<?=$arResult["FORM_ACTION"]?>" method="get" class="form-inline form-search pull-right">
<div class="input-group">
<?$APPLICATION->IncludeComponent(
"bitrix:search.suggest.input",
"top",
array(
"NAME" => "q",
"VALUE" => "",
"INPUT_SIZE" => 15,
"DROPDOWN_SIZE" => 10,
),
$component, array("HIDE_ICONS" => "Y")
);?><div class="input-group-btn"><input name="s" class="btn btn-primary" type="submit" value="<?=GetMessage("BSF_T_SEARCH_BUTTON");?>" /></div>
</div>
</form>
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
CJSCore::Init(array("ajax"));
?>
<script type="text/javascript">
if (!window.oObject || typeof oObject != "object")
window.oObject = {};
window.<?= $arResult["ID"]?>_CheckThis = document.<?= $arResult["ID"]?>_CheckThis = function(oObj)
{
try
{
if(SuggestLoaded)
{
if (typeof window.oObject[oObj.id] != 'object')
window.oObject[oObj.id] = new JsSuggest(oObj, '<?echo $arResult["ADDITIONAL_VALUES"]?>');
return;
}
else
{
setTimeout(<?echo $arResult["ID"]?>_CheckThis(oObj), 10);
}
}
catch(e)
{
setTimeout(<?echo $arResult["ID"]?>_CheckThis(oObj), 10);
}
}
</script>
<IFRAME style="width:0px; height:0px; border: 0px;" src="javascript:''" name="<?echo $arResult["ID"]?>_div_frame" id="<?echo $arResult["ID"]?>_div_frame"></IFRAME>
<label class="sr-only" for="searchInput">Search</label>
<input class="form-control" id="searchInput" type="text" name="search" placeholder="<?=GetMessage("BSF_T_SEARCH_FORM");?>" <?if($arParams["INPUT_SIZE"] > 0):?> size="<?echo $arParams["INPUT_SIZE"]?>"<?endif?> value="<?echo $arParams["VALUE"]?>" autocomplete="off" onfocus="<?echo $arResult["ID"]?>_CheckThis(this);" />
<?$MESS ['BSF_T_SEARCH_FORM'] = "Запрос";?>
<?$MESS ['BSF_T_SEARCH_FORM'] = "Search";?>
<?$MESS ['BSF_T_SEARCH_BUTTON'] = "ИСКАТЬ";?>
<?$MESS ['BSF_T_SEARCH_BUTTON'] = "GO";?>
На наш взгляд русские версии очень «корявые», однако мы создали их лишь для демонстрации механизма языковых файлов. При желании в них можно разместить английский текст или оставить пустыми.
Теперь осталось лишь разместить код вызов компонента вместо вёрстки в шаблоне:
<form name="search" action="#" method="get" class="form-inline form-search pull-right">
<div class="input-group">
<label class="sr-only" for="searchInput">Search</label>
<input class="form-control" id="searchInput" type="text" name="search" placeholder="Search">
<div class="input-group-btn">
<button type="submit" class="btn btn-primary">GO</button>
</div>
</div>
</form>
Для упрощения работы над сайтом перед началом работы над каждым меню мы будем создавать файл меню с актуальным контентом для упрощения работы.
<?
$aMenuLinks = Array(
Array(
"Home",
"/",
Array(),
Array(),
""
),
Array(
"About us",
"/about/",
Array(),
Array(),
""
),
Array(
"Services",
"",
Array(),
Array(),
""
),
Array(
"Partners",
"",
Array(),
Array(),
""
),
Array(
"Customers",
"",
Array(),
Array(),
""
),
Array(
"Projects",
"",
Array(),
Array(),
""
),
Array(
"Careers",
"",
Array(),
Array(),
""
),
Array(
"Contact",
"",
Array(),
Array(),
""
)
);
?>
Для создания верхнего меню воспользуемся компонентом bitrix:menu. Скопируем шаблон .default этого компонента в шаблон нашего сайта под именем top. Он практически не содержит ничего лишнего, поэтому мы легко адаптируем его под нашу вёрстку:
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?if (!empty($arResult)):?>
<nav class="navbar navbar-default">
<ul class="nav navbar-nav">
<?
foreach($arResult as $arItem):
if($arParams["MAX_LEVEL"] == 1 && $arItem["DEPTH_LEVEL"] > 1)
continue;
?>
<?if($arItem["SELECTED"]):?>
<li class="active"><a href=""LINK"]?>">"TEXT"]?></a></li>
<?else:?>
<li><a href=""LINK"]?>">"TEXT"]?></a></li>
<?endif?>
<?endforeach?>
</ul>
</nav>
<?endif?>
Теперь заменим блок верхнего меню в шаблоне на вызов компонента меню:
<?$APPLICATION->IncludeComponent("bitrix:menu", "top", Array(
"ROOT_MENU_TYPE" => "top",
"MENU_CACHE_TYPE" => "A",
"MENU_CACHE_TIME" => "3600",
"MENU_CACHE_USE_GROUPS" => "Y",
"MENU_CACHE_GET_VARS" => "",
"MAX_LEVEL" => "1",
"CHILD_MENU_TYPE" => "left",
"USE_EXT" => "N",
"DELAY" => "N",
"ALLOW_MULTI_SELECT" => "N",
),
false
);?>
Аналогично верхнему меню возьмём за основу компонент компонентом bitrix:menu. Скопируем шаблон .default этого компонента в шаблон нашего сайта под именем left.
После правки шаблона получим:
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?if (!empty($arResult)):?>
<ul class="list-group submenu">
<?
foreach($arResult as $arItem):
if($arParams["MAX_LEVEL"] == 1 && $arItem["DEPTH_LEVEL"] > 1)
continue;
?>
<?if($arItem["SELECTED"]):?>
<li class="list-group-item active">"TEXT"]?></li>
<?else:?>
<li class="list-group-item"><a href=""LINK"]?>">"TEXT"]?></a></li>
<?endif?>
<?endforeach?>
</ul>
<?endif?>
Заменим блок левого меню в шаблоне вызовом компонента:
<?$APPLICATION->IncludeComponent("bitrix:menu", "left", Array(
"ROOT_MENU_TYPE" => "left",
"MENU_CACHE_TYPE" => "A",
"MENU_CACHE_TIME" => "3600",
"MENU_CACHE_USE_GROUPS" => "Y",
"MENU_CACHE_GET_VARS" => "",
"MAX_LEVEL" => "1",
"CHILD_MENU_TYPE" => "left",
"USE_EXT" => "N",
"DELAY" => "N",
"ALLOW_MULTI_SELECT" => "N",
),
false
);?>
Пользуясь тем, что в 1С-Битрикс меню наследуется мы можем положить файлы левого меню .left.menu.php во все разделы, где они нужны с разным содержимым, а в корне, например, вовсе убрать. Вёрстка не пострадает, а меню будет отображаться лишь там, где это необходимо.
Нижнее меню (в разделе SiteMap) отображается в 2 колонки. Можно конечно сделать универсальный компонент меню в шаблоне которого пункты будут делиться по столбцам (автоматически, либо по наличию какого-либо параметра, установленного для пунктов в режиме расширенного редактирования меню).
Однако, мы понимаем, что подвал – не самая часто редактируемая часть и нет смысла тратить значительные усилия на его разработку.
Поэтому мы пойдём по простому пути (за который любители идеального кода, вероятно, нас проклянут) – мы создадим 2 меню: bottomL и bottomR.
Несмотря на то, что меню будет 2 шаблон мы для них будем использовать 1.
Вновь возьмём за основу компонент компонентом bitrix:menu. Скопируем шаблон .default этого компонента в шаблон нашего сайта под именем bottom.
Шаблон:
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?if (!empty($arResult)):?>
<div class="col-md-12">
<?
foreach($arResult as $arItem):
if($arParams["MAX_LEVEL"] == 1 && $arItem["DEPTH_LEVEL"] > 1)
continue;
?>
<a href=""LINK"]?>">"TEXT"]?></a>
<?endforeach?>
</div>
<?endif?>
Честно говоря без демо контента не понятно какую функцию оный сайдбар выполняет. Рискнём предположить, что всё-таки в нём показывается не картинка (уж больно несовременно), а полноценная карта Google. Наверное она маловата, чтобы располагать на ней элементы управления, так что она будет манималистичной.
Если же я не прав, то пожалуй один из самых простых способов реализации сайдбара – включаемая область, о которых мы уже говорили.
Возьмём компонент bitrix:map.google.view и скопируем шаблон .default в шаблон сайта, переименовав в sidebar-map.
Мы весь сайдбар сделаем частью компонента, включая заголовок. А значит, чтобы упростить работу редакторов необходимо вынести текст заголовка в параметры компонента.
Создадим в шаблоне компонента файл .parameters.php следующего содержания:
<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$arTemplateParameters = array(
"SIDEBAR_MAP_NAME" => Array(
"NAME" => GetMessage("SIDEBAR_MAP_NAME"),
"TYPE" => "HTML",
"DEFAULT" => "Our offices",
),
);
?>
<?$MESS ['SIDEBAR_MAP_NAME'] = "Название карты";?>
<?$MESS ['SIDEBAR_MAP_NAME'] = "Sidebar Map Name";?>
Шаблон компонента в таком случае модифицируется совсем незначительно (поместим карту внутрь сайдбара и добавим заголовок):
<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$arTransParams = array(
'INIT_MAP_TYPE' => $arParams['INIT_MAP_TYPE'],
'INIT_MAP_LON' => $arResult['POSITION']['google_lon'],
'INIT_MAP_LAT' => $arResult['POSITION']['google_lat'],
'INIT_MAP_SCALE' => $arResult['POSITION']['google_scale'],
'MAP_WIDTH' => $arParams['MAP_WIDTH'],
'MAP_HEIGHT' => $arParams['MAP_HEIGHT'],
'CONTROLS' => $arParams['CONTROLS'],
'OPTIONS' => $arParams['OPTIONS'],
'MAP_ID' => $arParams['MAP_ID'],
);
if ($arParams['DEV_MODE'] == 'Y')
{
$arTransParams['DEV_MODE'] = 'Y';
if ($arParams['WAIT_FOR_EVENT'])
$arTransParams['WAIT_FOR_EVENT'] = $arParams['WAIT_FOR_EVENT'];
}
?>
<div class="panel panel-primary">
<div class="panel-heading"><?=$arParams['SIDEBAR_MAP_NAME']?></div>
<div class="panel-body">
<div class="bx-yandex-view-layout">
<div class="bx-yandex-view-map">
<?
//echo '<pre>'; print_r($arResult['POSITION']); echo '</pre>';
$APPLICATION->IncludeComponent('bitrix:map.google.system', '.default', $arTransParams, false, array('HIDE_ICONS' => 'Y'));
?>
</div>
</div>
<?if (is_array($arResult['POSITION']['PLACEMARKS']) && ($cnt = count($arResult['POSITION']['PLACEMARKS']))):?>
<script type="text/javascript">
function BX_SetPlacemarks_<?echo $arParams['MAP_ID']?>()
{
<?
for($i = 0; $i < $cnt; $i++):
?>
BX_GMapAddPlacemark(<?echo CUtil::PhpToJsObject($arResult['POSITION']['PLACEMARKS'][$i])?>, '<?echo $arParams['MAP_ID']?>');
<?
endfor;
?>
}
function BXShowMap_<?echo $arParams['MAP_ID']?>() {BXWaitForMap_view('<?echo $arParams['MAP_ID']?>');}
BX.ready(BXShowMap_<?echo $arParams['MAP_ID']?>);
</script>
</div>
</div>
<?endif;?>
Теперь можно поместить вызов компонента сайдбара в шаблон сайта (если он должен выводиться на всём сайте, а лишь в определённых разделах, то достаточно обернуть его во включаемую область):
<?$APPLICATION->IncludeComponent("bitrix:map.google.view", "sidebar-map", array(
"INIT_MAP_TYPE" => "ROADMAP",
"MAP_DATA" => "a:4:{s:10:"google_lat";d:55.7383;s:10:"google_lon";d:37.5946;s:12:"google_scale";i:13;s:10:"PLACEMARKS";a:1:{i:0;a:3:{s:4:"TEXT";s:10:"Test point";s:3:"LON";d:37.593626976013184;s:3:"LAT";d:55.736905609230966;}}}",
"MAP_WIDTH" => "235",
"MAP_HEIGHT" => "180",
"CONTROLS" => array(
),
"OPTIONS" => array(
0 => "ENABLE_SCROLL_ZOOM",
1 => "ENABLE_DBLCLICK_ZOOM",
2 => "ENABLE_DRAGGING",
3 => "ENABLE_KEYBOARD",
),
"MAP_ID" => "",
"SIDEBAR_MAP_NAME" => "Our offices"
),
false
);?>
Теперь пришла пора взяться за рабочую область!
Для начала создадим инфоблок в котором будет хранить информацию о персонах. Из имеющегося макета видно, что нужны как минимум 4 поля:
Для единственного нестандартного поля (должность) следует завести свойство в настройках инфоблока.
Для универсальности решения мы будем оперировать не ID, а символьными кодами инфоблоков (это очень здорово помогает при переносе компонентов и шаблонов с тестового сервера на боевой, если там разное количество или разный порядок создания инфоблоков и их ID не совпадают).
Может показаться, что на этом этапе нам подойдёт компонент catalog.section с шаблоном board (этот шаблон генерирует таблицу с заданным количеством столбцов), однако в процессе эксплуатации такое решение весьма вероятно окажется сложнее. Поэтому мы всё же воспользуемся bitrix:news.list (скопировав шаблон .default в шаблон сайта под именем team-list) и допишем немного собственного кода.
Добавим в .parameters.php нашего шаблона новое значение:
$arTemplateParameters = array(
"LIST_NAME" => Array(
"NAME" => GetMessage("LIST_NAME"),
"TYPE" => "HTML",
"DEFAULT" => "Our Team",
),
);
Не забудем добавить значения в языковые файлы!
<?
$i++;
if ($i >= 5) {
$i = 0;
?>
</div><div class="row">
<?
}
?>
<?endforeach;?>
<?
if ($i > 0) {
?>
</div>
<?
}
?>
Не забудьте обнулить счётчик перед началом цикла на всякий пожарный.
Помимо счётчика нам понадобится вывести значение нашего свойства «Должность», для которого мы задали код POSITION. В массиве с данными, которые отдаёт компонент это свойство хранится в $arResult[«ITEMS»][«PROPERTIES»][«POSITION»][«VALUE»], поскольку мы будем выводить свойство в перебираемом по ITEMS элементам, то это будет выглядеть:
<?=$arItem["PROPERTIES"]["POSITION"]["VALUE"]?>
Сам шаблон тогда будет выглядеть так:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
$i=0;?>
<h2><?=$arParams['LIST_NAME']?></h2>
<div class="team">
<div class="row">
<?if($arParams["DISPLAY_TOP_PAGER"]):?>
<?=$arResult["NAV_STRING"]?><br />
<?endif;?>
<?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')));
?>
<div class="col col-md-4 <?if($i > 0){?>col-md-offset-1<?} ?>" id="<?=$this->GetEditAreaId($arItem['ID']);?>">
<img src=""PREVIEW_PICTURE"]["SRC"]?>" alt=""PREVIEW_PICTURE"]["ALT"]?>" title=""PREVIEW_PICTURE"]["TITLE"]?>" class="thumbnail">
<div class="caption">
<h3><?echo $arItem["NAME"]?></h3>
<P><?=$arItem["PROPERTIES"]["POSITION"]["VALUE"]?></P>
</div>
</div>
<?
$i++;
if ($i >= 5) {
$i = 0;
?>
</div><div class="row">
<?
}
?>
<?endforeach;?>
<?
if ($i > 0) {
?>
</div>
<?
}
?>
<?if($arParams["DISPLAY_BOTTOM_PAGER"]):?>
<br /><?=$arResult["NAV_STRING"]?>
<?endif;?>
</div>
Мы не стали заморачиваться с выносом кода свойства в параметры, а так же с настройкой количества элементов в строке, чтобы не усложнять шаблон компонента.
Как видите, в нём практически ничего не осталось от первоначального шаблона списка новостей (и он гораздо легче громоздкого компонента каталога).
Не забудьте удалить ненужную более папку /bitrix/templates/whitesquare-bootstrap/images/team/ с картинками в шаблоне после перевода блока с персонами на инфоблок!
Поскольку у нас нет понимания какие функции выполняют остальные элементы страницы, должна ли появляться случайная цитата или, скажем, должны ли картинки вести в фотогалерею, мы пойдём по простому пути.
Весь контент останется статичным, мы лишь добавим несколько стилей, чтобы будущие редакторы могли работать со страницей с большим удобством.
Для этого воспользуемся файлом стилей сайта, приложенном к нашему шаблону /bitrix/templates/whitesquare-bootstrap/styles.css (или административным разделом):
Поскольку этот файл используется для применения CSS к контенту в том числе в визуальном редакторе, нам придётся «забыть» о каскадности CSS и прописать стили без учёта вложенности элементов.
Например, цитата станет выглядеть так:
.jumbotron {
border-radius: 0;
padding: 0;
margin: 0;
font-size: 18px;
font-weight: 200;
background-color: #29c5e6;
box-sizing: border-box;
color: #ffffff;
line-height: 2.1428571435;
display: block;
box-sizing: border-box;
font-family: Tahoma, sans-serif;
blockquote {
border-left: none;
p {
font: 300 italic 33px @brand-font;
text-transform: uppercase;
margin-bottom: 0;
color: #ffffff;
}
small {
display: block;
text-align: right;
color: #1D8EA6;
color: #1D8EA6;
font: 300 20px @brand-font;
&:before {
content: '';
}
}
}
}
Для того, чтобы редакторы могли сами применить этот стиль с помощью виз редактор необходимо добавить в файл .styles.php в корне шаблона массив стилей:
<?
return array(
"jumbotron" => "цитата",
);
?>
Или через инструмент редактирования шаблона (вкладка «стили сайта»):
С целью немного облегчить работу редакторов можно создать в шаблоне сайта папку /page_templates/, где будут находиться шаблоны страниц, которые можно создавать ан проекте по умолчанию.
Шаблон страницы представляет из себя обычный php файл, идентичный странице в публичной части.
Помимо шаблонов необходимо так же разместить файл .content.php с массивом всех возможных шаблонов страниц. В нашем случае это будет:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?><?
IncludeTemplateLangFile(__FILE__);
$TEMPLATE["about.php"] = Array("name"=>GetMessage("about"), "sort"=>1);
?>
Не забудем создать языковые файлы!
Для того чтобы шаблон не был неопознанным объектом для имеющих доступ к административному разделу оформим файл описания и приложим скриншот! Они подхватятся автоматически:
<?$arTemplate = array(
"NAME" => "Шаблон 1 страницы для ХабраХабр",
"DESCRIPTION" => "Шаблон на основе Bootstrap вёрстки в светло-синих тонах",
"SORT" => 100,
);
?>
Вот собственно и всё!
Мы натянули готовую HTML вёрстку Bootstrap на 1С-Битрикс, сверстали страницу и получили полноценный шаблон!
Статья получилась очень длинная, поэтому очень непросто вычитать все неточности и опечатки. Если вы нашли ошибку – напишите мне в личку, и я с удовольствием её исправлю!
Огромное спасибо Mirantus [2] за оригинальную статью и готовую вёрстку, которую я смог взять за основу!
В качестве небольшого бонуса в GitHub проекте помимо собственно шаблона и страниц я разместил папку IMPORT_DATA, в которой содержится дамп демо-данных для единственного инфоблока с членами команды, фигурировавшего в статье. Вы можете импортировать его как XML на странице /bitrix/admin/iblock_xml_import.php?lang=ru
Автор: lexnekr
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/tutorial/55173
Ссылки в тексте:
[1] «Как сверстать веб-страницу. Часть 2 — Bootstrap»: http://habrahabr.ru/post/211032/
[2] Mirantus: http://habrahabr.ru/users/mirantus/
[3] Corporate Blue: http://www.pcklab.com/item.php?id=16
[4] Bootstrap 3: http://getbootstrap.com/
[5] одним из форков репозитория на GitHub: https://github.com/artoodetoo/whitesquare-bootstrap
[6] Проект на GitHub (демо-контент + шаблон): https://github.com/lexnekr/bitrix-template-whitesquare-bootstrap
[7] Шаблон 1С-Битрикс (CP-1251): http://кофедизайн.рф/upload/solutions/php/win-1251/whitesquare-bootstrap.tar.gz
[8] DEMO на 1С-Битрикс: http://тест.кофедизайн.рф
[9] Источник: http://habrahabr.ru/post/212163/
Нажмите здесь для печати.