Сейчас будет сложновато и долго, но оно того стоит.
- Про будущий дизайн
- Копируем дизайн
- Связь псевдонима и файла шаблона
- Проверка
- Blade
- Шаблоны. Базовый шаблон
- Шаблоны. Наследуем шаблоны
- Шаблоны. Выносим части шаблона в отдельные файлы
- Шаблоны. Секции содержимого
Для начала скачайте html-шаблон. Репозиторий лежит на моём гитхабе.
Жмите Code -> Download ZIP
, либо клонируйте к себе, если умеете работать с git.
Шаблон будет дорабатываться исходя из потребностей и дальнейших уроков. На данный момент там есть страницы:
- index.html - главная,
- single.html - страница поста,
- elements.html - набор разных элементов.
- tags.html - лента тегов
Не обращайте внимания ни на что, кроме папки dist
. Именно там хранится привычный html-код шаблона.
Остальные файлы и папки я сделал для облегчения вёрстки при помощи gulp. Если вам знаком этот термин, то в папке app вы можете найти исходные файлы, отредактировать шаблон и скомпилировать его под себя.
Так что открывайте index.html
и смотрите, что мы будем делать.
В Evolution CMS нет строгого требования к папке, где должны быть размещены изображения, js и css файлы шаблона.
Создайте папку template
в корне сайта, и скопируйте туда всё содержимое папки dist
из репозитория.
Файлы *.html можно не копировать, они ни на что не влияют. Просто в дальнейшем так удобнее таскать оттуда кусочки кода.
На четвёртом занятии мы делали шаблоны в админ-панели. Мы даже использовали их, создавая структуру сайта.
Давайте вспомним, что мы создали, но теперь обратите внимание на поле "Псевдоним".
Имя | Псевдоним | Описание |
---|---|---|
Главная страница | main | Для главной |
Все блоги | blogs | Лента блогов |
Пост в блоге | post | Пост в блоге |
Контакты | contacts | Контакты |
Все теги | tags | Лента тегов |
Тег | tag | Страница тега |
В тот момент он был нам не важен. Теперь настало время его использовать.
Откройте папку views
в корне сайта.
Что-то знакомое - blogs, post, contacts.
Evolution CMS сама сделала пустые файлы шаблонов, соответствующие тем псевдонимам, что мы задавали в админ-панели.
Разве что к псевдониму добавилось окончание .blade.php
.
Если вы не забыли нажать чекбокс "Создать файл шаблона при сохранении", разумеется. Если же забыли - можно создать его руками.
Резюмируем:
Шаблон в папке views связан с шаблоном в админ-панели через поле псевдоним
Давайте проверим, что наши шаблоны работают?
Откройте файл main.blade.php
и напишите там слово "главная". Сохраните и перейдите на главную страницу вашего сайта.
Попробуйте сделать то же самое с другими файлами.
Если какой-то из шаблонов не работает, проверьте внимательно псевдоним и имя созданного файла. Они должны быть одинаковы. В псевдониме и имени файла у вас не должно быть точек, подчёркиваний и пробелов. Почему? Чуть позже мы до этого дойдём.
В Evolution CMS используется шаблонизатор Blade, и это не так страшно выглядит, как называется. Он позаимствован Evolution CMS из Laravel. Привыкнув работать с Blade здесь, вам будет гораздо легче освоиться с Blade в Laravel или, скажем, с Twig в Drupal.
Если заглянуть в дизайн и представить этот сайт с сотней постов, вы увидите, что есть элементы, которые будут всегда неизменны - шапка, логотип. А есть области, где на разных страницах будет разный контент - заголовок, текст, фото.
Именно этим и занят шаблонизатор. Мы задаём некий "шаблон", размечаем его и определяем, в какой области что показывать.
Я примерно показал на скрине, где будут изменяемые области: тайтл, сайдбар, заголовок и текст поста.
Внимательно изучите верстку будущего блога. Выделите для себя, какие части повторяются в index.html и в single.html, какие неизменны. Где находится сайдбар? Где меню? Какие блоки в сайдбаре как называются?
Очень скоро вы поймёте, что было бы логичным создать некий базовый шаблон, который включет в себя только неизменные части дизайна.
А главная страница и страница поста будут "дочерними" шаблонами от этой базы. Таким образом, захоти мы изменить шапку, мы поменяем её одним махом на всех шаблонах.
Давайте сделаем базовый шаблон.
Создайте папку layouts
внутри /views
. Это общепринятое название, вы, разумеется, можете назвать её так, как желаете.
Внутри создайте файл app.blade.php
. Этот файл и будет нашим базовым шаблоном для всех страниц.
Теперь копируйте содержимое файла index.html
в файл app.blade.php
.
В шаблоне есть подключаемые файлы js и css. Исправьте пути на верные:
<link rel="stylesheet" href="template/css/main.min.css" />
<script src="template/js/all.min.js"></script>
Базовый шаблон на этом этапе больше не будем трогать, но обязательно к нему вернёмся.
Секция wrapper свернута для удобства - там код.
Теперь мы хотим, чтобы все наши остальные шаблоны зависели от базового.
Зависимость создаётся директивой @extends('путь.шаблон')
.
Откройте /views/main.blade.php
и впишите туда следующее:
@extends('layouts.app')
В блейде действует так называемая "точечная" нотация. Если быть проще, то вместо слешей - точки.
Так мы получаем конструкцию, которая говорит "наследуй из папки layouts файл app"
.
Точки вместо слешей, .blade.php не пишем
Повторите эту процедуру для всех шаблонов внутри папки /views
.
файл index.html внутри - служебный, его не трогайте
Сохраните файлы и "погуляйте" по сайту при помощи кнопки "Просмотр".
Скажем, попробуйте посмотреть, как выглядит страница контакты и страница поста в блоге.
Если с контактами всё хорошо, то в блоге у вас "слетит" вёрстка. В чём дело? Обычный html и особенность путей. Мы указали пути к css и js без слешей.
Давайте чуток исправим app
файл.
Впишите в <head>
:
<base href="{{ $modx->getConfig('site_url') }}" />
Что мы сделали? Определили базовый путь и присвоили ему значение из конфигурации сайта.
Запоминаем эту конструкцию. Она нужна для того, чтобы вывести из конфигурации сайта значение
Загляните в исходный код. После обработки сайт вернёт следующее:
<base href="http://evoblog.localhost/" />
При желании поправьте пути изображений. Но это не критично.
было | стало |
---|---|
images/pic02.jpg | template/images/pic02.jpg |
Теперь все страницы должны открываться корректно и без ошибок.
Давайте унесём некторые части шаблона в отдельные файлы.
Да, в этом дизайне подобное действие неоправдано - он слишком прост. Однако на живом большом сайте вам будет удобно, если структура шаблонов будет более предсказуема и вариативна.
Создайте папку parts
внутри views
. Сюда будем засовывать части шаблонов.
Найдите в app.blade.php
тег header
и вырежьте его со всем содержимым.
Вместо этого напишите там:
@include('parts.header')
И создайте внутри parts
файл header.blade.php
. В него вставьте содержимое вырезанного header
.
Проделайте ту же работу с menu
и sidebar
.
Запоминаем: директива @include
вставляет содержимое файла в указанное место шаблона
Что у вас должно получиться в app.blade.php
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<base href="{{ $modx->getConfig('site_url') }}" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, user-scalable=no"
/>
<link rel="stylesheet" href="template/css/main.min.css" />
<title>index</title>
</head>
<body class="is-preload">
<div id="wrapper">
@include('parts.header')
<!-- Menu -->
@include('parts.menu')
<!-- Main -->
<main id="main">
<!-- Post -->
<article class="post">
<header>
<div class="title">
<h1><a href="single.html">Magna sed adipiscing</a></h1>
<a href="single.html" class="image featured"
><img src="template/images/pic02.jpg" alt=""
/></a>
</div>
</header>
<p>
Mauris neque quam, fermentum ut nisl vitae, convallis maximus nisl.
Sed mattis nunc id lorem euismod placerat. Vivamus porttitor magna
enim, ac accumsan tortor cursus at. Phasellus sed ultricies mi non
congue ullam corper. Praesent tincidunt sed tellus ut rutrum. Sed
vitae justo condimentum, porta lectus vitae, ultricies congue
gravida diam non fringilla.
</p>
<footer>
<ul class="stats">
<li>
<a href="/tags/afrika" class="icon solid fa-tag">Африка</a>
</li>
<li><a href="#" class="icon solid fa-heart">28</a></li>
<li><a href="#" class="icon solid fa-comment">128</a></li>
</ul>
</footer>
</article>
<!-- Pagination -->
<ul class="actions special pagination">
<li><a href="" class="disabled button previous">«</a></li>
<li><a href="#" class="button ">1</a></li>
<li class=" is-active">2</li>
<li>...</li>
<li><a href="#" class="button ">10</a></li>
<li><a href="#" class="button next">»</a></li>
</ul>
</main>
@include('parts.sidebar')
</div>
<script src="template/js/all.min.js"></script>
</body>
</html>
А вот так выглядит папка views
Даже в нашем дизайне, где страница поста не очень отличается от главной, различия есть. Обратите внимание на секцию main
, где расположен пост/посты. На главной странице это лента всех постов, на странице поста - один пост. У них чуть-чуть отличается разметка, скажем, заголовок h2 заменяется на h1, внутри теги section и т.д.
Как же вывести в разных шаблонах разное содержимое? Вынести это в переменную. Давайте определим, с какого места в шаблоне начинаются различия.
Всё содержимое, включая тег <main id="main">
одинаково. Идём в базовый шаблон app.blade.php
и вырезаем всё внутри этого тега.
Получается вот так:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<base href="{{ $modx->getConfig('site_url') }}" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, user-scalable=no"
/>
<link rel="stylesheet" href="template/css/main.min.css" />
<title>index</title>
</head>
<body class="is-preload">
<div id="wrapper">
@include('parts.header') @include('parts.menu')
<main id="main">
<!-- тут изменяемый контент -->
</main>
@include('parts.sidebar')
</div>
<script src="template/js/all.min.js"></script>
</body>
</html>
Теперь внутри <main>
нужно определить изменяемую секцию, которую смогут поменять дочерние шаблоны. Пишем:
@yield('content')
Директива @yield
выведет содержимое секции content
.
Ближайшая аналогия - мы как будто бы сейчас написали вывод переменной content в определённое место.
Если сейчас открыть сайт, то в <main></main>
будет пусто.
Давайте зададим эту переменную?
Откройте файл main.blade.php
и измените его:
@extends('layouts.app')
@section('content')
я контент
@endsection
Запомнить: директива @section задаёт содержимое секции, которое потом можно вывести при помощи @yield
Ну и вместо "я контент" теперь мы можем спокойно скопировать туда содержимое главной - ленту постов и разметку пагинации.
@extends('layouts.app')
@section('content')
<!-- Post -->
<article class="post">
<header>
<div class="title">
<h1><a href="single.html">Magna sed adipiscing</a></h1>
<a href="single.html" class="image featured"
><img src="images/pic02.jpg" alt=""
/></a>
</div>
</header>
<p>text</p>
<footer>
<ul class="stats">
<li><a href="/tags/afrika" class="icon solid fa-tag">Африка</a></li>
<li><a href="#" class="icon solid fa-heart">28</a></li>
<li><a href="#" class="icon solid fa-comment">128</a></li>
</ul>
</footer>
</article>
<!-- повторите цать раз элемент class="post", если хотите -->
<!-- Pagination -->
<ul class="actions special pagination">
<li><a href="" class="disabled button previous">«</a></li>
<li><a href="#" class="button ">1</a></li>
<li class=" is-active">2</li>
<li>...</li>
<li><a href="#" class="button ">10</a></li>
<li><a href="#" class="button next">»</a></li>
</ul>
@endsection
Отлично. Теперь нас интересует страница конкретного поста.
Найдём его шаблон post.blade.php
и изменим таким же образом. Только внутрь секции мы копируем уже разметку поста из файла single.html
@extends('layouts.app')
@section('content')
<article class="post">
<header>
<div class="title">
<h1>Magna sed adipiscing</h1>
<div class="image featured">
<img src="images/pic02.jpg" alt="">
</div>
</div>
</header>
<section>
<!-- тут куча текста, для экономии места не буду копировать -->
</section>
</section>
<footer>
<ul class="stats">
<li><a href="/tags/afrika" class="icon solid fa-tag">Африка</a></li>
<li><a href="/tags/afrika" class="icon solid fa-tag">Африка</a></li>
<li><a href="#" class="icon solid fa-heart">28</a></li>
<li><a href="#" class="icon solid fa-comment">128</a></li>
</ul>
</footer>
</article>
@endsection
Проверьте себя. Главная страница должна содержать верстку всех постов:
А страница поста - только разметку поста:
Сделайте нечто похожее для оставшихся шаблонов.
Скажем, шаблон "Блоги" будет 1 в 1 как шаблон главной - лента постов и пагинация. Такой же будет и шаблон одного тега -- там будет выведена лента постов по тегу.
Общая страница "Теги" также похожа на ленту постов, но более миниатюрна.
Страницу "Контакты" сделайте такую же, как шаблон поста, просто убрав лишнее типа footer'а и картинок.
А можете открыть файл
elements.html
и собрать из элементов нужный дизайн.
- Знаем про связь псевдонима и файла шаблона
- Запомнили папку
views
. - поняли, как работает наследование от базового шаблона
- запомнили пару директив для шаблонов - section, yield, extend
- увидели первую команду
$modx->getConfig()
- сайт начинает приобретать внешний вид: пост/посты, главная, контакты
- на сайте не выводится содержимое из админки
Теперь настало время оживить сайт и выводить в шаблонах настоящее содержимое.