Шаблон для главной страницы: различия между версиями
Olga (обсуждение | вклад) |
Olga (обсуждение | вклад) |
||
(не показано 9 промежуточных версий этого же участника) | |||
Строка 3: | Строка 3: | ||
Вообще-то очень просто. В массиве $variables есть элемент 'is-default', который мы можем проверить. И если он true, то подтягиваем шаблон главной. Если нет - страницы нужного модуля. Вставим эту проверку в файл main.phtml: | Вообще-то очень просто. В массиве $variables есть элемент 'is-default', который мы можем проверить. И если он true, то подтягиваем шаблон главной. Если нет - страницы нужного модуля. Вставим эту проверку в файл main.phtml: | ||
− | < | + | <syntaxhighlight lang="php"> |
<main> | <main> | ||
<?php | <?php | ||
Строка 10: | Строка 10: | ||
?> | ?> | ||
</main> | </main> | ||
− | </ | + | </syntaxhighlight> |
В объекте $variables['page'] тоже есть такое свойство, но получить его невозможно. Оно, конечно, private. Всегда будет false. | В объекте $variables['page'] тоже есть такое свойство, но получить его невозможно. Оно, конечно, private. Всегда будет false. | ||
Строка 16: | Строка 16: | ||
И надо создать в папке php фрагмент шаблона content/home/index.phtml, который подключаем. Для начала пусть будет просто контентная страница: | И надо создать в папке php фрагмент шаблона content/home/index.phtml, который подключаем. Для начала пусть будет просто контентная страница: | ||
− | < | + | <syntaxhighlight lang="php"> |
<?php | <?php | ||
$page = $variables['page']; | $page = $variables['page']; | ||
Строка 32: | Строка 32: | ||
</div> | </div> | ||
</section> | </section> | ||
− | </ | + | </syntaxhighlight> |
== Добавление блоков == | == Добавление блоков == | ||
Строка 45: | Строка 45: | ||
Вообще хорошим тоном является не портить шаблон данных "Настройки", а создать дочерний шаблон, куда и внести все нужные поля. Это без сомнения пригодится, если на одной системе делать несколько сайтов с разным набором настроек. | Вообще хорошим тоном является не портить шаблон данных "Настройки", а создать дочерний шаблон, куда и внести все нужные поля. Это без сомнения пригодится, если на одной системе делать несколько сайтов с разным набором настроек. | ||
+ | |||
+ | === Разбиваем шаблон на блоки === | ||
Чтобы не тащить простыню кода, разделим content/home/index.phtml на фрагменты по блокам: | Чтобы не тащить простыню кода, разделим content/home/index.phtml на фрагменты по блокам: | ||
− | < | + | <syntaxhighlight lang="php"> |
<?php | <?php | ||
echo $this->render($variables, "content/home/intro"); | echo $this->render($variables, "content/home/intro"); | ||
Строка 54: | Строка 56: | ||
echo $this->render($variables, "content/home/contacts"); | echo $this->render($variables, "content/home/contacts"); | ||
?> | ?> | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | === Вводный текст === | ||
Фрагмент content/home/intro.phtml останется аналогом контентной страницы: | Фрагмент content/home/intro.phtml останется аналогом контентной страницы: | ||
− | < | + | <syntaxhighlight lang="php"> |
<?php | <?php | ||
$page = $variables['page']; | $page = $variables['page']; | ||
Строка 74: | Строка 78: | ||
</div> | </div> | ||
</section> | </section> | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | === Новости === | ||
Фрагмент для новостей content/home/news.phtml: | Фрагмент для новостей content/home/news.phtml: | ||
− | < | + | <syntaxhighlight lang="php"> |
<?php | <?php | ||
− | $ | + | $newsListSettings = $variables['settings']->newslist; |
− | if (!empty($ | + | if (!empty($newsListSettings)) $newsPageId = $newsListSettings[0]->id; |
else $newsPageId = false; | else $newsPageId = false; | ||
$newsList = $this->macros('news', 'lastlist', [$newsPageId]); | $newsList = $this->macros('news', 'lastlist', [$newsPageId]); | ||
Строка 110: | Строка 116: | ||
</div> | </div> | ||
</section> | </section> | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | === Контакты === | ||
Фрагмент для контактов content/home/contacts.phtml: | Фрагмент для контактов content/home/contacts.phtml: | ||
− | < | + | <syntaxhighlight lang="php"> |
<section> | <section> | ||
<div class="container"> | <div class="container"> | ||
Строка 142: | Строка 150: | ||
</div> | </div> | ||
</section> | </section> | ||
− | </ | + | </syntaxhighlight> |
Не забываем пополнять файлы i18n/i18n.ru.php и i18n/i18n.en.php новыми языковыми константами, которые появляются в шаблонах нашего сайта. Также добавили разметку для Edit-in-place, и теперь можем внести адрес и телефон прямо на "морде" сайта. | Не забываем пополнять файлы i18n/i18n.ru.php и i18n/i18n.en.php новыми языковыми константами, которые появляются в шаблонах нашего сайта. Также добавили разметку для Edit-in-place, и теперь можем внести адрес и телефон прямо на "морде" сайта. | ||
+ | |||
+ | == Организация блоков на главной странице == | ||
+ | |||
+ | Хотелось бы дать возможность редактору сайта регулировать контент на главной странице, добавлять и убирать блоки, и чтобы все изменения появлялись на сайте автоматически. | ||
+ | |||
+ | Кто-то из новых разработчиков задал аналогичный вопрос в группе, получил много ответов, которые его не устроили по причине сложной реализации. Что он сделал после этого? У него была верстка, вся такая из разноцветных блоков. Он в "Шаблонах данных" добавил дочерний шаблон в "Раздел сайта", назвал его "Главная", и добавил туда кучу полей типа HTML-текст с кодом section1, section2 и т.д. После чего скопировал код соответствующих блоков из верстки, и вставил в эти поля. Шаблон главной у него при этом получился, видимо, такой: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | <?php | ||
+ | $page = $variables['page']; | ||
+ | ?> | ||
+ | <?= ($page->section1)?$page->section1:'' ?> | ||
+ | <?= ($page->section2)?$page->section2:'' ?> | ||
+ | ... | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | А что, так можно было??? Конечно, можно. Но некрасиво, и нельзя поменять блоки местами. | ||
+ | |||
+ | Мне больше нравится другой способ. Создаём в разделе главной страницы несколько подразделов, например, вот так: | ||
+ | |||
+ | [[Файл:Screenshot 22 UMI CMS - Структура сайта.png|обрамить|без]] | ||
+ | |||
+ | Псевдостатические адреса задаём intro, news и contacts соответственно. После чего шаблон главной страницы приобретает вид: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | <?php | ||
+ | /** | ||
+ | * Главная страница: | ||
+ | * - Блок с вступительным текстом | ||
+ | * - Блок "Новости" | ||
+ | * - Блок "Контакты" | ||
+ | * Для удаления блока достаточно снять | ||
+ | * у соответствующего раздела признак "Отображать в меню" | ||
+ | * Для добавления блока надо добавить блок в структуру | ||
+ | * раздела и создать в папке content/home файл шаблона | ||
+ | * с именем как в поле "Псевдостатический адрес" | ||
+ | * | ||
+ | */ | ||
+ | $blocks = []; | ||
+ | $hierarchy = umiHierarchy::getInstance(); | ||
+ | $children = $hierarchy->getChildrenTree($variables['pageId'], false, false, 1); | ||
+ | foreach ($children as $id => $val) { | ||
+ | $element = $hierarchy->getElement($id); | ||
+ | if ($element instanceof umiHierarchyElement) { | ||
+ | $blocks[$id]['id'] = $element->id; | ||
+ | $blocks[$id]['name'] = $element->name; | ||
+ | $blocks[$id]['h1'] = $element->h1; | ||
+ | $blocks[$id]['altName'] = $element->altName; | ||
+ | $blocks[$id]['content'] = $element->content; | ||
+ | } | ||
+ | } | ||
+ | $resourcesDir = cmsController::getInstance()->getResourcesDirectory(); | ||
+ | |||
+ | foreach ($blocks as $page) { | ||
+ | $page['settings'] = $variables['settings']; | ||
+ | if (isset($page['altName'])) { | ||
+ | if ($resourcesDir && file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this->render($page, 'content/home/' . $page['altName']); | ||
+ | else echo '<div class="alert alert-danger">Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml</div>'; | ||
+ | } | ||
+ | } | ||
+ | ?> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Кода получилось немного больше, но в следующей статье исправим этот недостаток. Подключили класс umiHierarchy, выбрали все дочерние страницы, выбрали соответствующие объекты и наполнили массив $blocks. Да, еще добыли путь к корневой папке нашего шаблона, чтобы не задавать статикой. В качестве данных передаём в render() массив $page, куда добавили $variables['settings'], чтобы не потерять настройки. Вообще это лучше делать по-другому, но об этом чуть позже. | ||
+ | |||
+ | Теперь надо поменять немного шаблоны блоков, чтобы брать оттуда контент соответствующих подразделов. | ||
+ | |||
+ | === Вступительный текст === | ||
+ | |||
+ | В метод render() мы уже передаем не $variables, а элемент массива, содержащий данные подраздела. Здесь название массива по-прежнему будет $variables, но содержимое будет уже другим. Поэтому: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | <section> | ||
+ | <div class="container"> | ||
+ | <div class="row"> | ||
+ | <div class="col-12"> | ||
+ | <h1 umi:element-id="<?= $variables['id'] ?>" umi:field-name="h1" umi:empty="<?= $this->translate('empty_page_name') ?>"><?= $variables['h1'] ?></h1> | ||
+ | </div> | ||
+ | <div class="col-12"> | ||
+ | <div umi:element-id="<?= $variables['id'] ?>" umi:field-name="content" umi:empty="<?= $this->translate('empty_page_content') ?>"><?= $variables['content'] ?></div> | ||
+ | </div> | ||
+ | </div> | ||
+ | </div> | ||
+ | </section> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Остальные шаблоны === | ||
+ | |||
+ | Все, что нам нужно из остальных подразделов - это заголовки, которые специально до этого были оставлены в виде слов. Поэтому меняем только одну строку: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | <h2 umi:element-id="<?= $variables['id'] ?>" umi:field-name="h1" umi:empty="<?= $this->translate('empty_page_name') ?>"><?= $variables['h1'] ?></h2> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === В чем преимущество? === | ||
+ | |||
+ | Редактор сайта получает больше возможностей для изменения контента главной, можно использовать Edit-in-place для исправления заголовков блоков, можно менять блоки местами. Попробуйте и убедитесь. | ||
+ | |||
+ | Вообще я обычно использую 2 уровня вложенности подразделов, чтобы внутри каждого из блоков отображать список дочерних блоков. Это очень удобно для программирования современных сайтов, где есть блоки "Наши преимущества", "Наша команда" и "Отзывы наших клиентов", содержащие свои списки данных. Понятно, что кроме заголовка и контента можно добавлять картинки, пиктограммы, анонсы - всё, что только может понадобиться. | ||
+ | |||
+ | Но есть и недостаток - много кода в шаблоне. Хорошим тоном в UMI считается, если в шаблоне вообще не используется API. Это правильно и с точки зрения MVC. Поэтому пора перейти к [[Расширение функциональности модулей|созданию кастомных методов и функций]]. |
Текущая версия на 18:25, 5 ноября 2020
Как правило, стартовая страница сайта отличается от остальных. Как отразить эту особенность в нашем шаблоне?
Вообще-то очень просто. В массиве $variables есть элемент 'is-default', который мы можем проверить. И если он true, то подтягиваем шаблон главной. Если нет - страницы нужного модуля. Вставим эту проверку в файл main.phtml:
<main>
<?php
if ($variables['is-default']) echo $this->render($variables, "content/home/index");
else echo $this->render($variables, "{$variables['module']}/{$variables['method']}");
?>
</main>
В объекте $variables['page'] тоже есть такое свойство, но получить его невозможно. Оно, конечно, private. Всегда будет false.
И надо создать в папке php фрагмент шаблона content/home/index.phtml, который подключаем. Для начала пусть будет просто контентная страница:
<?php
$page = $variables['page'];
?>
<section>
<div class="container">
<div class="row">
<div class="col-12">
<h1 umi:element-id="<?= $page->id ?>" umi:field-name="h1" umi:empty="<?= $this->translate('empty_page_name') ?>"><?= $page->h1 ?></h1>
</div>
<div class="col-12">
<div umi:element-id="<?= $page->id ?>" umi:field-name="content" umi:empty="<?= $this->translate('empty_page_content') ?>"><?= $page->content ?></div>
</div>
</div>
</div>
</section>
Добавление блоков
Обычно на главную страницу стараются запихнуть весь контент сайта. Наверно потому, что не надеются, что пользователь настолько заинтересуется, что пройдет куда-то ещё.
Продолжим эту скверную традицию. У нас есть контент главной страницы, где можно разместить информацию о компании или продукте, и новости. Явно не хватает контактов, которые лучше добавить в настройки:
Чтобы к этому не возвращаться, добавим все поля, которые хотели, в частности, ссылки на дерево для новостей и 404 ошибки, а также название компании. Новости уже есть, осталось в настройках выбрать нужный раздел, а вот 404 страницы нет, создадим её.
Вообще хорошим тоном является не портить шаблон данных "Настройки", а создать дочерний шаблон, куда и внести все нужные поля. Это без сомнения пригодится, если на одной системе делать несколько сайтов с разным набором настроек.
Разбиваем шаблон на блоки
Чтобы не тащить простыню кода, разделим content/home/index.phtml на фрагменты по блокам:
<?php
echo $this->render($variables, "content/home/intro");
echo $this->render($variables, "content/home/news");
echo $this->render($variables, "content/home/contacts");
?>
Вводный текст
Фрагмент content/home/intro.phtml останется аналогом контентной страницы:
<?php
$page = $variables['page'];
?>
<section>
<div class="container">
<div class="row">
<div class="col-12">
<h1 umi:element-id="<?= $page->id ?>" umi:field-name="h1" umi:empty="<?= $this->translate('empty_page_name') ?>"><?= $page->h1 ?></h1>
</div>
<div class="col-12">
<div umi:element-id="<?= $page->id ?>" umi:field-name="content" umi:empty="<?= $this->translate('empty_page_content') ?>"><?= $page->content ?></div>
</div>
</div>
</div>
</section>
Новости
Фрагмент для новостей content/home/news.phtml:
<?php
$newsListSettings = $variables['settings']->newslist;
if (!empty($newsListSettings)) $newsPageId = $newsListSettings[0]->id;
else $newsPageId = false;
$newsList = $this->macros('news', 'lastlist', [$newsPageId]);
?>
<section>
<div class="container">
<div class="row">
<div class="col-12">
<h2>Что нового?</h2>
</div>
<div class="col-12">
<ul class="list-group">
<?php
if (!empty($newsList['items'])):
foreach ($newsList['items'] as $item):
?>
<li class="list-group-item">
<em><?= date("d.m.Y", $item['publish_time']) ?></em>
<a href="<?= $item['link'] ?>"><h3 umi:element-id="<?= $item['id'] ?>" umi:field-name="name" umi:empty="<?= $this->translate('empty_page_name') ?>"><?= $item['name'] ?></h3></a>
</li>
<?php
endforeach;
endif;
?>
</ul>
</div>
</div>
</div>
</section>
Контакты
Фрагмент для контактов content/home/contacts.phtml:
<section>
<div class="container">
<div class="row">
<div class="col-12">
<h2>Контакты</h2>
</div>
<div class="col-12">
<div class="row">
<div class="col-6">
<h3><?= $this->translate('address') ?></h3>
</div>
<div class="col-6">
<h3 umi:object-id="<?= $variables['settings']->id ?>" umi:field-name="address" umi:empty="<?= $this->translate('empty_address') ?>"><?= $variables['settings']->address ?></h3>
</div>
</div>
<div class="row">
<div class="col-6">
<h3><?= $this->translate('phone') ?></h3>
</div>
<div class="col-6">
<h3 umi:object-id="<?= $variables['settings']->id ?>" umi:field-name="phone" umi:empty="<?= $this->translate('empty_phone') ?>"><?= $variables['settings']->phone ?></h3>
</div>
</div>
</div>
</div>
</div>
</section>
Не забываем пополнять файлы i18n/i18n.ru.php и i18n/i18n.en.php новыми языковыми константами, которые появляются в шаблонах нашего сайта. Также добавили разметку для Edit-in-place, и теперь можем внести адрес и телефон прямо на "морде" сайта.
Организация блоков на главной странице
Хотелось бы дать возможность редактору сайта регулировать контент на главной странице, добавлять и убирать блоки, и чтобы все изменения появлялись на сайте автоматически.
Кто-то из новых разработчиков задал аналогичный вопрос в группе, получил много ответов, которые его не устроили по причине сложной реализации. Что он сделал после этого? У него была верстка, вся такая из разноцветных блоков. Он в "Шаблонах данных" добавил дочерний шаблон в "Раздел сайта", назвал его "Главная", и добавил туда кучу полей типа HTML-текст с кодом section1, section2 и т.д. После чего скопировал код соответствующих блоков из верстки, и вставил в эти поля. Шаблон главной у него при этом получился, видимо, такой:
<?php
$page = $variables['page'];
?>
<?= ($page->section1)?$page->section1:'' ?>
<?= ($page->section2)?$page->section2:'' ?>
...
А что, так можно было??? Конечно, можно. Но некрасиво, и нельзя поменять блоки местами.
Мне больше нравится другой способ. Создаём в разделе главной страницы несколько подразделов, например, вот так:
Псевдостатические адреса задаём intro, news и contacts соответственно. После чего шаблон главной страницы приобретает вид:
<?php
/**
* Главная страница:
* - Блок с вступительным текстом
* - Блок "Новости"
* - Блок "Контакты"
* Для удаления блока достаточно снять
* у соответствующего раздела признак "Отображать в меню"
* Для добавления блока надо добавить блок в структуру
* раздела и создать в папке content/home файл шаблона
* с именем как в поле "Псевдостатический адрес"
*
*/
$blocks = [];
$hierarchy = umiHierarchy::getInstance();
$children = $hierarchy->getChildrenTree($variables['pageId'], false, false, 1);
foreach ($children as $id => $val) {
$element = $hierarchy->getElement($id);
if ($element instanceof umiHierarchyElement) {
$blocks[$id]['id'] = $element->id;
$blocks[$id]['name'] = $element->name;
$blocks[$id]['h1'] = $element->h1;
$blocks[$id]['altName'] = $element->altName;
$blocks[$id]['content'] = $element->content;
}
}
$resourcesDir = cmsController::getInstance()->getResourcesDirectory();
foreach ($blocks as $page) {
$page['settings'] = $variables['settings'];
if (isset($page['altName'])) {
if ($resourcesDir && file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this->render($page, 'content/home/' . $page['altName']);
else echo '<div class="alert alert-danger">Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml</div>';
}
}
?>
Кода получилось немного больше, но в следующей статье исправим этот недостаток. Подключили класс umiHierarchy, выбрали все дочерние страницы, выбрали соответствующие объекты и наполнили массив $blocks. Да, еще добыли путь к корневой папке нашего шаблона, чтобы не задавать статикой. В качестве данных передаём в render() массив $page, куда добавили $variables['settings'], чтобы не потерять настройки. Вообще это лучше делать по-другому, но об этом чуть позже.
Теперь надо поменять немного шаблоны блоков, чтобы брать оттуда контент соответствующих подразделов.
Вступительный текст
В метод render() мы уже передаем не $variables, а элемент массива, содержащий данные подраздела. Здесь название массива по-прежнему будет $variables, но содержимое будет уже другим. Поэтому:
<section>
<div class="container">
<div class="row">
<div class="col-12">
<h1 umi:element-id="<?= $variables['id'] ?>" umi:field-name="h1" umi:empty="<?= $this->translate('empty_page_name') ?>"><?= $variables['h1'] ?></h1>
</div>
<div class="col-12">
<div umi:element-id="<?= $variables['id'] ?>" umi:field-name="content" umi:empty="<?= $this->translate('empty_page_content') ?>"><?= $variables['content'] ?></div>
</div>
</div>
</div>
</section>
Остальные шаблоны
Все, что нам нужно из остальных подразделов - это заголовки, которые специально до этого были оставлены в виде слов. Поэтому меняем только одну строку:
<h2 umi:element-id="<?= $variables['id'] ?>" umi:field-name="h1" umi:empty="<?= $this->translate('empty_page_name') ?>"><?= $variables['h1'] ?></h2>
В чем преимущество?
Редактор сайта получает больше возможностей для изменения контента главной, можно использовать Edit-in-place для исправления заголовков блоков, можно менять блоки местами. Попробуйте и убедитесь.
Вообще я обычно использую 2 уровня вложенности подразделов, чтобы внутри каждого из блоков отображать список дочерних блоков. Это очень удобно для программирования современных сайтов, где есть блоки "Наши преимущества", "Наша команда" и "Отзывы наших клиентов", содержащие свои списки данных. Понятно, что кроме заголовка и контента можно добавлять картинки, пиктограммы, анонсы - всё, что только может понадобиться.
Но есть и недостаток - много кода в шаблоне. Хорошим тоном в UMI считается, если в шаблоне вообще не используется API. Это правильно и с точки зрения MVC. Поэтому пора перейти к созданию кастомных методов и функций.