Создание настроек сайта: различия между версиями
Olga (обсуждение | вклад) |
Olga (обсуждение | вклад) |
||
(не показано 8 промежуточных версий этого же участника) | |||
Строка 25: | Строка 25: | ||
И тут мы сталкиваемся с очередной засадой UMI CMS. Казалось бы, каждому сайту должен соответствовать какой-то один набор настроек. Но в интерфейсе видим, что этих наборов можно создать сколько угодно. '''Господа разработчики''', может, стоило бы для упрощения ограничить эти возможности? Кто-то вообще использует больше одного набора настроек для конкретной языковой версии сайта? Было бы шикарно получать настройки прямо в массиве $variables, как вы считаете? | И тут мы сталкиваемся с очередной засадой UMI CMS. Казалось бы, каждому сайту должен соответствовать какой-то один набор настроек. Но в интерфейсе видим, что этих наборов можно создать сколько угодно. '''Господа разработчики''', может, стоило бы для упрощения ограничить эти возможности? Кто-то вообще использует больше одного набора настроек для конкретной языковой версии сайта? Было бы шикарно получать настройки прямо в массиве $variables, как вы считаете? | ||
− | Зато есть повод поупражняться с API системы. Один из способов получить настройки - использовать | + | Зато есть повод поупражняться с API системы. Один из способов получить настройки - использовать название настроек, в данном случае 'demo': |
− | < | + | <syntaxhighlight lang="php"> |
− | $ | + | $settings = $this->getObjectById($this->macros('umiSettings', 'getIdByName', 'demo'])); |
− | |||
− | |||
var_dump($settings); | var_dump($settings); | ||
− | </ | + | </syntaxhighlight> |
− | Здесь мы использовали | + | Здесь мы использовали метод getIdByName('...') модуля umiSettings для получения id настроек по названию (это именно название, не идентификатор), а потом получили сам объект настроек при помощи метода getObjectById(). |
− | Добавим этот код в самое начало common.phtml. К счастью, в настройках разных языковых версий можно задавать | + | Добавим этот код в самое начало common.phtml. К счастью, в настройках разных языковых версий можно задавать одно и то же название, а то было бы совсем грустно. В общем, получилось. Если добавить на страницу <?= $settings->copyright ?>, то увидим копирайт, который ввели. |
Теперь попробуем другой путь, ведь мы не фанаты делать кучу настроек: | Теперь попробуем другой путь, ведь мы не фанаты делать кучу настроек: | ||
− | < | + | <syntaxhighlight lang="php"> |
$set = new selector('objects'); | $set = new selector('objects'); | ||
$set->types('object-type')->name('umiSettings', 'settings'); | $set->types('object-type')->name('umiSettings', 'settings'); | ||
− | $set->where('domain_id')->equals($variables[' | + | $set->where('domain_id')->equals($variables['domain-id']); |
− | $set->where('lang_id')->equals($variables[' | + | $set->where('lang_id')->equals($variables['lang-id']); |
$set->limit(0, 1); | $set->limit(0, 1); | ||
$settings = $set->result(); | $settings = $set->result(); | ||
var_dump($settings); | var_dump($settings); | ||
− | </ | + | </syntaxhighlight> |
В этом коде был использован самый мощный класс ядра UMI - selector. Он подробно описан в документации. Чего в документации нет, так это - что подставлять в качестве 'object-type'. Но в админке есть где посмотреть: 'Шаблоны данных' - 'Настройки модуля' (ссылка справа вверху). Для начала лучше в этих настройках ничего не менять, но в качестве справочника - бесценно! | В этом коде был использован самый мощный класс ядра UMI - selector. Он подробно описан в документации. Чего в документации нет, так это - что подставлять в качестве 'object-type'. Но в админке есть где посмотреть: 'Шаблоны данных' - 'Настройки модуля' (ссылка справа вверху). Для начала лучше в этих настройках ничего не менять, но в качестве справочника - бесценно! | ||
Строка 56: | Строка 54: | ||
UMI CMS в конце каждой страницы выдает время её формирования, что очень удобно. Легко убедиться, что второй способ на 0.001 секунды быстрее, помимо прочих его преимуществ. Конечно, неплохо бы проверить, что хоть какие-то настройки нашлись. Кроме этого, хотелось бы получить настройки в самом начале, а использовать их в произвольных фрагментах нашего шаблона. В результате модифицируем код common.phtml как-то так: | UMI CMS в конце каждой страницы выдает время её формирования, что очень удобно. Легко убедиться, что второй способ на 0.001 секунды быстрее, помимо прочих его преимуществ. Конечно, неплохо бы проверить, что хоть какие-то настройки нашлись. Кроме этого, хотелось бы получить настройки в самом начале, а использовать их в произвольных фрагментах нашего шаблона. В результате модифицируем код common.phtml как-то так: | ||
− | < | + | <syntaxhighlight lang="php"> |
<?php | <?php | ||
$set = new selector('objects'); | $set = new selector('objects'); | ||
$set->types('object-type')->name('umiSettings', 'settings'); | $set->types('object-type')->name('umiSettings', 'settings'); | ||
− | $set->where('domain_id')->equals($variables[' | + | $set->where('domain_id')->equals($variables['domain-id']); |
− | $set->where('lang_id')->equals($variables[' | + | $set->where('lang_id')->equals($variables['lang-id']); |
$set->limit(0, 1); | $set->limit(0, 1); | ||
$variables['settings'] = array_shift($set->result()); | $variables['settings'] = array_shift($set->result()); | ||
Строка 81: | Строка 79: | ||
</body> | </body> | ||
</html> | </html> | ||
− | </ | + | </syntaxhighlight> |
Копирайт мы собирались использовать в подвале сайта, поэтому пишем в footer.phtml: | Копирайт мы собирались использовать в подвале сайта, поэтому пишем в footer.phtml: | ||
− | < | + | <syntaxhighlight lang="php"> |
<footer> | <footer> | ||
<div class="container"> | <div class="container"> | ||
Строка 92: | Строка 90: | ||
</div> | </div> | ||
</footer> | </footer> | ||
− | </ | + | </syntaxhighlight> |
Проверяем результат - всё получилось! Теперь надо разобраться с логотипом. Добавляем <?php var_dump($variables['settings']->logo); ?> в файл header.phtml, и видим, что это объект. Причем - ещё одна засада UMI CMS - все свойства без исключения protected!!! Зато в нем есть все, что нам нужно. Итак, изучаем документацию по классам umiFile и umiImageFile, и новый header.phtml будет выглядеть примерно так: | Проверяем результат - всё получилось! Теперь надо разобраться с логотипом. Добавляем <?php var_dump($variables['settings']->logo); ?> в файл header.phtml, и видим, что это объект. Причем - ещё одна засада UMI CMS - все свойства без исключения protected!!! Зато в нем есть все, что нам нужно. Итак, изучаем документацию по классам umiFile и umiImageFile, и новый header.phtml будет выглядеть примерно так: | ||
− | < | + | <syntaxhighlight lang="php"> |
<?php | <?php | ||
− | $pageId = isset($variables[' | + | $pageId = isset($variables['pageId'])?$variables['pageId']:0; |
$menuTree = $this->macros('content', 'menu', [0, 2, 0, true, $pageId]); | $menuTree = $this->macros('content', 'menu', [0, 2, 0, true, $pageId]); | ||
$logo = $variables['settings']->logo; | $logo = $variables['settings']->logo; | ||
Строка 116: | Строка 114: | ||
<ul class="navbar-nav mr-auto"> | <ul class="navbar-nav mr-auto"> | ||
<?php | <?php | ||
− | foreach ($menuTree[' | + | foreach ($menuTree['lines'] as $item) { |
$dropdown = !empty($item['items']['nodes:item']); | $dropdown = !empty($item['items']['nodes:item']); | ||
$active = !empty($item['attribute:status']); | $active = !empty($item['attribute:status']); | ||
− | if (isset($item[' | + | if (isset($item['link']) && isset($item['name'])) { |
if ($dropdown) { | if ($dropdown) { | ||
?> | ?> | ||
<li class="nav-item dropdown <?=$active?'active':''?>"> | <li class="nav-item dropdown <?=$active?'active':''?>"> | ||
− | <a class="nav-link dropdown-toggle" href="<?= $item[' | + | <a class="nav-link dropdown-toggle" href="<?= $item['link'] ?>" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><?= $item['name'] ?></a> |
<div class="dropdown-menu" aria-labelledby="navbarDropdown"> | <div class="dropdown-menu" aria-labelledby="navbarDropdown"> | ||
<?php | <?php | ||
− | foreach ($item['items'][' | + | foreach ($item['items']['item'] as $sub) { |
− | if (isset($sub[' | + | if (isset($sub['link']) && isset($sub['name'])) { |
?> | ?> | ||
− | <a class="dropdown-item" href="<?= $sub[' | + | <a class="dropdown-item" href="<?= $sub['link'] ?>"><?= $sub['name'] ?></a> |
<?php | <?php | ||
} | } | ||
Строка 140: | Строка 138: | ||
?> | ?> | ||
<li class="nav-item <?=$active?'active':''?>"> | <li class="nav-item <?=$active?'active':''?>"> | ||
− | <a class="nav-link" href="<?= $item[' | + | <a class="nav-link" href="<?= $item['link'] ?>"><?= $item['name'] ?></a> |
</li> | </li> | ||
<?php | <?php | ||
Строка 151: | Строка 149: | ||
</nav> | </nav> | ||
</header> | </header> | ||
− | </ | + | </syntaxhighlight> |
Почему перед адресом изображения стоит '/'? Потому что getFilePath() зачем-то перед адресом ставит точку, хоть адрес возвращает абсолютный. Загадка. В качестве alt и title пробуем получить значения, которые должны были задать в админке при заливке файла. Но поскольку ничего не задали, они будут пустые. А вообще, по-хорошему, надо добавить в настройки еще одно поле - название компании, и выводить именно его. | Почему перед адресом изображения стоит '/'? Потому что getFilePath() зачем-то перед адресом ставит точку, хоть адрес возвращает абсолютный. Загадка. В качестве alt и title пробуем получить значения, которые должны были задать в админке при заливке файла. Но поскольку ничего не задали, они будут пустые. А вообще, по-хорошему, надо добавить в настройки еще одно поле - название компании, и выводить именно его. | ||
Строка 159: | Строка 157: | ||
Теперь осталось добавить возможность изменять эти поля прямо на сайте. В принципе, ничего сложного: | Теперь осталось добавить возможность изменять эти поля прямо на сайте. В принципе, ничего сложного: | ||
− | < | + | <syntaxhighlight lang="html"> |
<img umi:object-id="<?= $logo->getId() ?>" umi:field-name="logo" src="/<?= $logo->getFilePath() ?>" title="<?= $logo->getTitle() ?>" alt="<?= $logo->getAlt() ?>"> | <img umi:object-id="<?= $logo->getId() ?>" umi:field-name="logo" src="/<?= $logo->getFilePath() ?>" title="<?= $logo->getTitle() ?>" alt="<?= $logo->getAlt() ?>"> | ||
− | </ | + | </syntaxhighlight> |
Это для логотипа, а для копирайта: | Это для логотипа, а для копирайта: | ||
− | < | + | <syntaxhighlight lang="php"> |
<span umi:object-id="<?= $logo->getId() ?>" umi:field-name="logo" umi:empty="<?= $this->translate('empty_copyright') ?>"> | <span umi:object-id="<?= $logo->getId() ?>" umi:field-name="logo" umi:empty="<?= $this->translate('empty_copyright') ?>"> | ||
<?= $variables['settings']->copyright ?> | <?= $variables['settings']->copyright ?> | ||
</span> <?= date("Y") ?> | </span> <?= date("Y") ?> | ||
− | </ | + | </syntaxhighlight> |
− | + | Заметим, что псевдо-атрибуты для id контентных страниц и объектов отличаются, если для полей страниц мы использовали атрибут umi:element-id, то для полей объектов приходится писать umi:object-id. Это отражение внутреннего деления UMI CMS на страницы контента и объекты, за работу с которыми отвечают разные методы. | |
+ | |||
+ | Также пришлось добавить дополнительный <nowiki><span></nowiki>, чтобы копирайт был в отдельном контейнере. | ||
== Другие модули системы == | == Другие модули системы == | ||
Пока нам для сайта хватало модуля content, немного использовали umiSettings. Однако полезных модулей гораздо больше, и пора наконец [[Другие модули системы|добавить на сайт раздел Новости]]. | Пока нам для сайта хватало модуля content, немного использовали umiSettings. Однако полезных модулей гораздо больше, и пора наконец [[Другие модули системы|добавить на сайт раздел Новости]]. |
Текущая версия на 23:10, 5 ноября 2020
Выбираем в админке раздел "Настройки сайта" и не видим никаких настроек:
Жмём "Создать настройки", и создаём:
Название может быть любое, идентификатор - только латиница. Если создаем настройки для русской версии сайта, на английской они видны не будут. Что в принципе логично.
Теперь видим, что настройки появились:
Вопрос только - что с ними делать? Ставим рядом галку, в пиктографическом меню нажимаем "Редактировать" - и видим ту же самую форму, что только что заполнили. Где логотип, где копирайт? Так мы незаметно подошли к большой теме - Создание шаблонов данных.
Вывод настроек в шаблоне
Добавим в настройки логотип и копирайт:
Теперь попробуем вывести всё это на страницах сайта.
И тут мы сталкиваемся с очередной засадой UMI CMS. Казалось бы, каждому сайту должен соответствовать какой-то один набор настроек. Но в интерфейсе видим, что этих наборов можно создать сколько угодно. Господа разработчики, может, стоило бы для упрощения ограничить эти возможности? Кто-то вообще использует больше одного набора настроек для конкретной языковой версии сайта? Было бы шикарно получать настройки прямо в массиве $variables, как вы считаете?
Зато есть повод поупражняться с API системы. Один из способов получить настройки - использовать название настроек, в данном случае 'demo':
$settings = $this->getObjectById($this->macros('umiSettings', 'getIdByName', 'demo']));
var_dump($settings);
Здесь мы использовали метод getIdByName('...') модуля umiSettings для получения id настроек по названию (это именно название, не идентификатор), а потом получили сам объект настроек при помощи метода getObjectById().
Добавим этот код в самое начало common.phtml. К счастью, в настройках разных языковых версий можно задавать одно и то же название, а то было бы совсем грустно. В общем, получилось. Если добавить на страницу <?= $settings->copyright ?>, то увидим копирайт, который ввели.
Теперь попробуем другой путь, ведь мы не фанаты делать кучу настроек:
$set = new selector('objects');
$set->types('object-type')->name('umiSettings', 'settings');
$set->where('domain_id')->equals($variables['domain-id']);
$set->where('lang_id')->equals($variables['lang-id']);
$set->limit(0, 1);
$settings = $set->result();
var_dump($settings);
В этом коде был использован самый мощный класс ядра UMI - selector. Он подробно описан в документации. Чего в документации нет, так это - что подставлять в качестве 'object-type'. Но в админке есть где посмотреть: 'Шаблоны данных' - 'Настройки модуля' (ссылка справа вверху). Для начала лучше в этих настройках ничего не менять, но в качестве справочника - бесценно!
Здесь мы ищем селектором те единственные настройки, что соответствуют конкретной языковой версии нашего сайта. Синтаксически это почти SQL-запрос, на мой взгляд, тут всё просто.
UMI CMS в конце каждой страницы выдает время её формирования, что очень удобно. Легко убедиться, что второй способ на 0.001 секунды быстрее, помимо прочих его преимуществ. Конечно, неплохо бы проверить, что хоть какие-то настройки нашлись. Кроме этого, хотелось бы получить настройки в самом начале, а использовать их в произвольных фрагментах нашего шаблона. В результате модифицируем код common.phtml как-то так:
<?php
$set = new selector('objects');
$set->types('object-type')->name('umiSettings', 'settings');
$set->where('domain_id')->equals($variables['domain-id']);
$set->where('lang_id')->equals($variables['lang-id']);
$set->limit(0, 1);
$variables['settings'] = array_shift($set->result());
if (empty($variables['settings'])) {
echo $this->translate('no settings');
exit();
}
?>
<!DOCTYPE html>
<html>
<?= $this->render($variables, 'layout/head') ?>
<body>
<?= $this->render($variables, 'layout/header') ?>
<?= $this->render($variables, 'layout/main') ?>
<?= $this->render($variables, 'layout/footer') ?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</body>
</html>
Копирайт мы собирались использовать в подвале сайта, поэтому пишем в footer.phtml:
<footer>
<div class="container">
<?= $variables['settings']->copyright ?><?= date("Y") ?>
</div>
</footer>
Проверяем результат - всё получилось! Теперь надо разобраться с логотипом. Добавляем <?php var_dump($variables['settings']->logo); ?> в файл header.phtml, и видим, что это объект. Причем - ещё одна засада UMI CMS - все свойства без исключения protected!!! Зато в нем есть все, что нам нужно. Итак, изучаем документацию по классам umiFile и umiImageFile, и новый header.phtml будет выглядеть примерно так:
<?php
$pageId = isset($variables['pageId'])?$variables['pageId']:0;
$menuTree = $this->macros('content', 'menu', [0, 2, 0, true, $pageId]);
$logo = $variables['settings']->logo;
?>
<header>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="/">
<?php if ($logo): ?>
<img src="/<?= $logo->getFilePath() ?>" title="<?= $logo->getTitle() ?>" alt="<?= $logo->getAlt() ?>">
<?php endif; ?>
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<?php
foreach ($menuTree['lines'] as $item) {
$dropdown = !empty($item['items']['nodes:item']);
$active = !empty($item['attribute:status']);
if (isset($item['link']) && isset($item['name'])) {
if ($dropdown) {
?>
<li class="nav-item dropdown <?=$active?'active':''?>">
<a class="nav-link dropdown-toggle" href="<?= $item['link'] ?>" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><?= $item['name'] ?></a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<?php
foreach ($item['items']['item'] as $sub) {
if (isset($sub['link']) && isset($sub['name'])) {
?>
<a class="dropdown-item" href="<?= $sub['link'] ?>"><?= $sub['name'] ?></a>
<?php
}
}
?>
</div>
</li>
<?php
} else {
?>
<li class="nav-item <?=$active?'active':''?>">
<a class="nav-link" href="<?= $item['link'] ?>"><?= $item['name'] ?></a>
</li>
<?php
}
}
}
?>
</ul>
</div>
</nav>
</header>
Почему перед адресом изображения стоит '/'? Потому что getFilePath() зачем-то перед адресом ставит точку, хоть адрес возвращает абсолютный. Загадка. В качестве alt и title пробуем получить значения, которые должны были задать в админке при заливке файла. Но поскольку ничего не задали, они будут пустые. А вообще, по-хорошему, надо добавить в настройки еще одно поле - название компании, и выводить именно его.
Edit-in-place для настроек
Теперь осталось добавить возможность изменять эти поля прямо на сайте. В принципе, ничего сложного:
<img umi:object-id="<?= $logo->getId() ?>" umi:field-name="logo" src="/<?= $logo->getFilePath() ?>" title="<?= $logo->getTitle() ?>" alt="<?= $logo->getAlt() ?>">
Это для логотипа, а для копирайта:
<span umi:object-id="<?= $logo->getId() ?>" umi:field-name="logo" umi:empty="<?= $this->translate('empty_copyright') ?>">
<?= $variables['settings']->copyright ?>
</span> <?= date("Y") ?>
Заметим, что псевдо-атрибуты для id контентных страниц и объектов отличаются, если для полей страниц мы использовали атрибут umi:element-id, то для полей объектов приходится писать umi:object-id. Это отражение внутреннего деления UMI CMS на страницы контента и объекты, за работу с которыми отвечают разные методы.
Также пришлось добавить дополнительный <span>, чтобы копирайт был в отдельном контейнере.
Другие модули системы
Пока нам для сайта хватало модуля content, немного использовали umiSettings. Однако полезных модулей гораздо больше, и пора наконец добавить на сайт раздел Новости.