<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://wiki.adt.ru/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Olga</id>
	<title>Wiki from ADT Web Solutions - Вклад участника [ru]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.adt.ru/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Olga"/>
	<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Olga"/>
	<updated>2026-04-30T16:03:11Z</updated>
	<subtitle>Вклад участника</subtitle>
	<generator>MediaWiki 1.35.0</generator>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=376</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=376"/>
		<updated>2020-11-06T08:28:46Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Создание кастомных событий внутри шаблона */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
Иногда добавленные таким способом методы выдают ошибку, с одним таким случаем только что столкнулись, второй из возможных - это когда в копируемом методе используются другие методы из файла macros.php в виде $this-&amp;gt;название_метода(). При вызове из другого класса метод не обнаруживается.. В этом случае надо заменить вызов на $this-&amp;gt;module-&amp;gt;название_метода(), не зря же переменная $module была добавлена в кастомный класс.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё довольно далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Организация повторяющегося кода ===&lt;br /&gt;
&lt;br /&gt;
На главной странице мы вывели новости с анонсами, но совсем забыли про собственно раздел новостей, где всё ещё используем макрос lastlist(). Было бы правильно добавить в PhpExtension метод:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает список последних новостей&lt;br /&gt;
         * @param bool|int $newsPageId id ленты новостей&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getNewsList($newsPageId = false) {&lt;br /&gt;
            if (!$id) {&lt;br /&gt;
                $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
                $newsList = $templateEngine-&amp;gt;getCommonVar('settings')-&amp;gt;newslist;&lt;br /&gt;
                if (!empty($newsList)) $newsPageId = $newsList[0]-&amp;gt;id;&lt;br /&gt;
                else return false;&lt;br /&gt;
            }&lt;br /&gt;
            return $this-&amp;gt;macros(&amp;quot;news&amp;quot;, &amp;quot;newslist&amp;quot;, [$newsPageId]);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если передан id ленты новостей, то возвращаем массив, если нет - пытаемся найти его в настройках. После этого можем в файле content/home/news.phtml написать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$newsList = $this-&amp;gt;getNewsList();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
а в файле news/rubric.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
$newsList = $this-&amp;gt;getNewsList($page-&amp;gt;id);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Когда надо добавлять методы в в класс шаблонизатора? ===&lt;br /&gt;
&lt;br /&gt;
Даже на этих примерах видно, насколько понятней становится код шаблонов. По сути, это все равно обращение к базе в процессе рендеринга. Но выглядит лучше, и код обращений собран в одном файле. Поэтому лучше создавать методы класса, если надо:&lt;br /&gt;
&lt;br /&gt;
* Организовать глобальны переменные&lt;br /&gt;
* Убрать из шаблона большие куски кода, особенно содержащие обращения к базе данных&lt;br /&gt;
* Ликвидировать повторяющиеся в разных фрагментах шаблона куски кода&lt;br /&gt;
&lt;br /&gt;
== Вместо заключения ==&lt;br /&gt;
&lt;br /&gt;
За рамками этой инструкции остались события, это довольно большая тема, и, к счастью, [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/sobytijnaya_model_umicms/ хорошо документированная].&lt;br /&gt;
&lt;br /&gt;
Следующим этапом можно было также рассмотреть методы работы с формами, это, например, раздел личного кабинета пользователя, методы регистрации и авторизации. Но во-первых, на сайте не всегда нужен такой раздел, во-вторых, делать странички с формами, в то время как это давно везде реализовано при помощи модальных окон и AJAX-запросов, мне просто лень.&lt;br /&gt;
&lt;br /&gt;
Надеюсь, инструкция помогла на примерах понять архитектуру UMI CMS и принципы построения новых элементов. Самое время [[Что дальше?|перейти к практике]]!&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=375</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=375"/>
		<updated>2020-11-06T08:27:30Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Использование кастомного метода в шаблона */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
Иногда добавленные таким способом методы выдают ошибку, с одним таким случаем только что столкнулись, второй из возможных - это когда в копируемом методе используются другие методы из файла macros.php в виде $this-&amp;gt;название_метода(). При вызове из другого класса метод не обнаруживается.. В этом случае надо заменить вызов на $this-&amp;gt;module-&amp;gt;название_метода(), не зря же переменная $module была добавлена в кастомный класс.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Организация повторяющегося кода ===&lt;br /&gt;
&lt;br /&gt;
На главной странице мы вывели новости с анонсами, но совсем забыли про собственно раздел новостей, где всё ещё используем макрос lastlist(). Было бы правильно добавить в PhpExtension метод:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает список последних новостей&lt;br /&gt;
         * @param bool|int $newsPageId id ленты новостей&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getNewsList($newsPageId = false) {&lt;br /&gt;
            if (!$id) {&lt;br /&gt;
                $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
                $newsList = $templateEngine-&amp;gt;getCommonVar('settings')-&amp;gt;newslist;&lt;br /&gt;
                if (!empty($newsList)) $newsPageId = $newsList[0]-&amp;gt;id;&lt;br /&gt;
                else return false;&lt;br /&gt;
            }&lt;br /&gt;
            return $this-&amp;gt;macros(&amp;quot;news&amp;quot;, &amp;quot;newslist&amp;quot;, [$newsPageId]);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если передан id ленты новостей, то возвращаем массив, если нет - пытаемся найти его в настройках. После этого можем в файле content/home/news.phtml написать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$newsList = $this-&amp;gt;getNewsList();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
а в файле news/rubric.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
$newsList = $this-&amp;gt;getNewsList($page-&amp;gt;id);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Когда надо добавлять методы в в класс шаблонизатора? ===&lt;br /&gt;
&lt;br /&gt;
Даже на этих примерах видно, насколько понятней становится код шаблонов. По сути, это все равно обращение к базе в процессе рендеринга. Но выглядит лучше, и код обращений собран в одном файле. Поэтому лучше создавать методы класса, если надо:&lt;br /&gt;
&lt;br /&gt;
* Организовать глобальны переменные&lt;br /&gt;
* Убрать из шаблона большие куски кода, особенно содержащие обращения к базе данных&lt;br /&gt;
* Ликвидировать повторяющиеся в разных фрагментах шаблона куски кода&lt;br /&gt;
&lt;br /&gt;
== Вместо заключения ==&lt;br /&gt;
&lt;br /&gt;
За рамками этой инструкции остались события, это довольно большая тема, и, к счастью, [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/sobytijnaya_model_umicms/ хорошо документированная].&lt;br /&gt;
&lt;br /&gt;
Следующим этапом можно было также рассмотреть методы работы с формами, это, например, раздел личного кабинета пользователя, методы регистрации и авторизации. Но во-первых, на сайте не всегда нужен такой раздел, во-вторых, делать странички с формами, в то время как это давно везде реализовано при помощи модальных окон и AJAX-запросов, мне просто лень.&lt;br /&gt;
&lt;br /&gt;
Надеюсь, инструкция помогла на примерах понять архитектуру UMI CMS и принципы построения новых элементов. Самое время [[Что дальше?|перейти к практике]]!&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%92%D0%B8%D0%BA%D0%B8%D0%BF%D0%B5%D0%B4%D0%B8%D1%8F_%D1%81%D1%82%D1%83%D0%B4%D0%B8%D0%B8_ADT_Web_Solutions&amp;diff=374</id>
		<title>Википедия студии ADT Web Solutions</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%92%D0%B8%D0%BA%D0%B8%D0%BF%D0%B5%D0%B4%D0%B8%D1%8F_%D1%81%D1%82%D1%83%D0%B4%D0%B8%D0%B8_ADT_Web_Solutions&amp;diff=374"/>
		<updated>2020-11-06T08:18:25Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= UMI CMS: первые шаги с PHP-шаблонизатором =&lt;br /&gt;
&lt;br /&gt;
''Инструкция для начинающих разработчиков, написанная начинающим разработчиком, который много раз прошёл по этим граблям''&lt;br /&gt;
&lt;br /&gt;
# [[Преимущества UMI CMS]]&lt;br /&gt;
# [[Установка UMI CMS Trial]]&lt;br /&gt;
# [[Создание сайта на UMI CMS Trial]]&lt;br /&gt;
#* [[Структура сайта]]&lt;br /&gt;
#* [[Создание &amp;quot;правильного&amp;quot; шаблона для сайта]]&lt;br /&gt;
#* [[Добавление возможности Edit-in-place]]&lt;br /&gt;
#* [[Создание настроек сайта]]&lt;br /&gt;
#* [[Шаблоны данных сайта]]&lt;br /&gt;
#* [[Другие модули системы]]&lt;br /&gt;
#* [[Шаблон для главной страницы]]&lt;br /&gt;
#* [[Расширение функциональности модулей]]&lt;br /&gt;
# [[Что дальше?]]&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=373</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=373"/>
		<updated>2020-11-06T08:16:48Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Организация повторяющегося кода */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Организация повторяющегося кода ===&lt;br /&gt;
&lt;br /&gt;
На главной странице мы вывели новости с анонсами, но совсем забыли про собственно раздел новостей, где всё ещё используем макрос lastlist(). Было бы правильно добавить в PhpExtension метод:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает список последних новостей&lt;br /&gt;
         * @param bool|int $newsPageId id ленты новостей&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getNewsList($newsPageId = false) {&lt;br /&gt;
            if (!$id) {&lt;br /&gt;
                $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
                $newsList = $templateEngine-&amp;gt;getCommonVar('settings')-&amp;gt;newslist;&lt;br /&gt;
                if (!empty($newsList)) $newsPageId = $newsList[0]-&amp;gt;id;&lt;br /&gt;
                else return false;&lt;br /&gt;
            }&lt;br /&gt;
            return $this-&amp;gt;macros(&amp;quot;news&amp;quot;, &amp;quot;newslist&amp;quot;, [$newsPageId]);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если передан id ленты новостей, то возвращаем массив, если нет - пытаемся найти его в настройках. После этого можем в файле content/home/news.phtml написать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$newsList = $this-&amp;gt;getNewsList();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
а в файле news/rubric.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
$newsList = $this-&amp;gt;getNewsList($page-&amp;gt;id);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Когда надо добавлять методы в в класс шаблонизатора? ===&lt;br /&gt;
&lt;br /&gt;
Даже на этих примерах видно, насколько понятней становится код шаблонов. По сути, это все равно обращение к базе в процессе рендеринга. Но выглядит лучше, и код обращений собран в одном файле. Поэтому лучше создавать методы класса, если надо:&lt;br /&gt;
&lt;br /&gt;
* Организовать глобальны переменные&lt;br /&gt;
* Убрать из шаблона большие куски кода, особенно содержащие обращения к базе данных&lt;br /&gt;
* Ликвидировать повторяющиеся в разных фрагментах шаблона куски кода&lt;br /&gt;
&lt;br /&gt;
== Вместо заключения ==&lt;br /&gt;
&lt;br /&gt;
За рамками этой инструкции остались события, это довольно большая тема, и, к счастью, [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/sobytijnaya_model_umicms/ хорошо документированная].&lt;br /&gt;
&lt;br /&gt;
Следующим этапом можно было также рассмотреть методы работы с формами, это, например, раздел личного кабинета пользователя, методы регистрации и авторизации. Но во-первых, на сайте не всегда нужен такой раздел, во-вторых, делать странички с формами, в то время как это давно везде реализовано при помощи модальных окон и AJAX-запросов, мне просто лень.&lt;br /&gt;
&lt;br /&gt;
Надеюсь, инструкция помогла на примерах понять архитектуру UMI CMS и принципы построения новых элементов. Самое время [[Что дальше?|перейти к практике]]!&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=372</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=372"/>
		<updated>2020-11-06T08:10:20Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Организация повторяющегося кода */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Организация повторяющегося кода ===&lt;br /&gt;
&lt;br /&gt;
На главной странице мы вывели новости с анонсами, но совсем забыли про собственно раздел новостей, где всё ещё используем макрос lastlist(). Было бы правильно добавить в PhpExtension метод:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает список последних новостей&lt;br /&gt;
         * @param bool|int $newsPageId id ленты новостей&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getNewsList($newsPageId = false) {&lt;br /&gt;
            if (!$id) {&lt;br /&gt;
                $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
                $newsList = $templateEngine-&amp;gt;getCommonVar('settings')-&amp;gt;newslist;&lt;br /&gt;
                if (!empty($newsList)) $newsPageId = $newsList[0]-&amp;gt;id;&lt;br /&gt;
                else return false;&lt;br /&gt;
            }&lt;br /&gt;
            return $this-&amp;gt;macros(&amp;quot;news&amp;quot;, &amp;quot;newslist&amp;quot;, [$newsPageId]);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если передан id ленты новостей, то возвращаем массив, если нет - пытаемся найти его в настройках. После этого можем в файле content/home/news.phtml написать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$newsList = $this-&amp;gt;getNewsList();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
а в файле news/rubric.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$newsList = $this-&amp;gt;getNewsList($variables['pageId']);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Когда надо добавлять методы в в класс шаблонизатора? ===&lt;br /&gt;
&lt;br /&gt;
Даже на этих примерах видно, насколько понятней становится код шаблонов. По сути, это все равно обращение к базе в процессе рендеринга. Но выглядит лучше, и код обращений собран в одном файле. Поэтому лучше создавать методы класса, если надо:&lt;br /&gt;
&lt;br /&gt;
* Организовать глобальны переменные&lt;br /&gt;
* Убрать из шаблона большие куски кода, особенно содержащие обращения к базе данных&lt;br /&gt;
* Ликвидировать повторяющиеся в разных фрагментах шаблона куски кода&lt;br /&gt;
&lt;br /&gt;
== Вместо заключения ==&lt;br /&gt;
&lt;br /&gt;
За рамками этой инструкции остались события, это довольно большая тема, и, к счастью, [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/sobytijnaya_model_umicms/ хорошо документированная].&lt;br /&gt;
&lt;br /&gt;
Следующим этапом можно было также рассмотреть методы работы с формами, это, например, раздел личного кабинета пользователя, методы регистрации и авторизации. Но во-первых, на сайте не всегда нужен такой раздел, во-вторых, делать странички с формами, в то время как это давно везде реализовано при помощи модальных окон и AJAX-запросов, мне просто лень.&lt;br /&gt;
&lt;br /&gt;
Надеюсь, инструкция помогла на примерах понять архитектуру UMI CMS и принципы построения новых элементов. Самое время [[Что дальше?|перейти к практике]]!&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=371</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=371"/>
		<updated>2020-11-06T08:08:46Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Организация повторяющегося кода */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Организация повторяющегося кода ===&lt;br /&gt;
&lt;br /&gt;
На главной странице мы вывели новости с анонсами, но совсем забыли про собственно раздел новостей, где всё ещё используем макрос lastlist(). Было бы правильно добавить в PhpExtension метод:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает список последних новостей&lt;br /&gt;
         * @param bool|int $newsPageId id ленты новостей&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getNewsList($newsPageId = false) {&lt;br /&gt;
            if (!$id) {&lt;br /&gt;
                $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
                $newsList = $templateEngine-&amp;gt;getCommonVar('settings')-&amp;gt;newslist;&lt;br /&gt;
                if (!empty($newsList)) $newsPageId = $newsList[0]-&amp;gt;id;&lt;br /&gt;
                else return false&lt;br /&gt;
            }&lt;br /&gt;
            return $this-&amp;gt;macros(&amp;quot;news&amp;quot;, &amp;quot;newslist&amp;quot;, [$newsPageId]);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если передан id ленты новостей, то возвращаем массив, если нет - пытаемся найти его в настройках. После этого можем в файле content/home/news.phtml написать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$newsList = $this-&amp;gt;getNewsList();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
а в файле news/rubric.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$newsList = $this-&amp;gt;getNewsList($variables['pageId']);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Когда надо добавлять методы в в класс шаблонизатора? ===&lt;br /&gt;
&lt;br /&gt;
Даже на этих примерах видно, насколько понятней становится код шаблонов. По сути, это все равно обращение к базе в процессе рендеринга. Но выглядит лучше, и код обращений собран в одном файле. Поэтому лучше создавать методы класса, если надо:&lt;br /&gt;
&lt;br /&gt;
* Организовать глобальны переменные&lt;br /&gt;
* Убрать из шаблона большие куски кода, особенно содержащие обращения к базе данных&lt;br /&gt;
* Ликвидировать повторяющиеся в разных фрагментах шаблона куски кода&lt;br /&gt;
&lt;br /&gt;
== Вместо заключения ==&lt;br /&gt;
&lt;br /&gt;
За рамками этой инструкции остались события, это довольно большая тема, и, к счастью, [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/sobytijnaya_model_umicms/ хорошо документированная].&lt;br /&gt;
&lt;br /&gt;
Следующим этапом можно было также рассмотреть методы работы с формами, это, например, раздел личного кабинета пользователя, методы регистрации и авторизации. Но во-первых, на сайте не всегда нужен такой раздел, во-вторых, делать странички с формами, в то время как это давно везде реализовано при помощи модальных окон и AJAX-запросов, мне просто лень.&lt;br /&gt;
&lt;br /&gt;
Надеюсь, инструкция помогла на примерах понять архитектуру UMI CMS и принципы построения новых элементов. Самое время [[Что дальше?|перейти к практике]]!&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=370</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=370"/>
		<updated>2020-11-06T07:45:09Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Организация повторяющегося кода */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Организация повторяющегося кода ===&lt;br /&gt;
&lt;br /&gt;
На главной странице мы вывели новости с анонсами, но совсем забыли про собственно раздел новостей, где всё ещё используем макрос lastlist(). Было бы правильно добавить в PhpExtension метод:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает список последних новостей&lt;br /&gt;
         * @param bool|int $newsPageId id ленты новостей&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getNewsList($newsPageId = false) {&lt;br /&gt;
            if (!$id) {&lt;br /&gt;
                $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
                $newsList = $templateEngine-&amp;gt;getCommonVar('settings')-&amp;gt;newslist;&lt;br /&gt;
                if (!empty($newsList)) $newsPageId = $newsList[0]-&amp;gt;id;&lt;br /&gt;
                else {&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $this-&amp;gt;macros(&amp;quot;news&amp;quot;, &amp;quot;newslist&amp;quot;, [$newsPageId]);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого можем&lt;br /&gt;
&lt;br /&gt;
Даже на этих примерах видно, насколько наглядней становится код шаблонов. Конечно, по сути это все равно обращение к базе в процессе рендеринга шаблона. Но выглядит лучше, и код обращений собран в одном файле.&lt;br /&gt;
&lt;br /&gt;
== Вместо заключения ==&lt;br /&gt;
&lt;br /&gt;
За рамками этой инструкции остались события, это довольно большая тема, и, к счастью, [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/sobytijnaya_model_umicms/ хорошо документированная].&lt;br /&gt;
&lt;br /&gt;
Следующим этапом можно было также рассмотреть методы работы с формами, это, например, раздел личного кабинета пользователя, методы регистрации и авторизации. Но во-первых, на сайте не всегда нужен такой раздел, во-вторых, делать странички с формами, в то время как это давно везде реализовано при помощи модальных окон и AJAX-запросов, мне просто лень.&lt;br /&gt;
&lt;br /&gt;
Надеюсь, инструкция помогла на примерах понять архитектуру UMI CMS и принципы построения новых элементов. Самое время [[Что дальше?|перейти к практике]]!&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=369</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=369"/>
		<updated>2020-11-06T07:43:18Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Получение блоков для главной страницы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Организация повторяющегося кода ===&lt;br /&gt;
&lt;br /&gt;
На главной странице мы вывели новости с анонсами, но совсем забыли про собственно раздел новостей, где всё ещё используем макрос lastlist(). Было бы правильно добавить в PhpExtension метод:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает список последних новостей&lt;br /&gt;
         * @param bool|int $newsPageId id ленты новостей&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getNewsList($newsPageId = false) {&lt;br /&gt;
            if (!$id) {&lt;br /&gt;
                $newsList = $this-&amp;gt;getCommonVar('settings')-&amp;gt;newslist;&lt;br /&gt;
                if (!empty($newsList)) $newsPageId = $newsList[0]-&amp;gt;id;&lt;br /&gt;
                else {&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $this-&amp;gt;macros(&amp;quot;news&amp;quot;, &amp;quot;newslist&amp;quot;, [$newsPageId]);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого можем&lt;br /&gt;
&lt;br /&gt;
Даже на этих примерах видно, насколько наглядней становится код шаблонов. Конечно, по сути это все равно обращение к базе в процессе рендеринга шаблона. Но выглядит лучше, и код обращений собран в одном файле.&lt;br /&gt;
&lt;br /&gt;
== Вместо заключения ==&lt;br /&gt;
&lt;br /&gt;
За рамками этой инструкции остались события, это довольно большая тема, и, к счастью, [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/sobytijnaya_model_umicms/ хорошо документированная].&lt;br /&gt;
&lt;br /&gt;
Следующим этапом можно было также рассмотреть методы работы с формами, это, например, раздел личного кабинета пользователя, методы регистрации и авторизации. Но во-первых, на сайте не всегда нужен такой раздел, во-вторых, делать странички с формами, в то время как это давно везде реализовано при помощи модальных окон и AJAX-запросов, мне просто лень.&lt;br /&gt;
&lt;br /&gt;
Надеюсь, инструкция помогла на примерах понять архитектуру UMI CMS и принципы построения новых элементов. Самое время [[Что дальше?|перейти к практике]]!&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BA_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=368</id>
		<title>Создание настроек сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BA_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=368"/>
		<updated>2020-11-05T20:10:01Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Вывод настроек в шаблоне */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Выбираем в админке раздел &amp;quot;Настройки сайта&amp;quot; и не видим никаких настроек:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-30 UMI CMS - Настройки.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Жмём &amp;quot;Создать настройки&amp;quot;, и создаём:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-30 UMI CMS - Создание.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Название может быть любое, идентификатор - только латиница. Если создаем настройки для русской версии сайта, на английской они видны не будут. Что в принципе логично.&lt;br /&gt;
&lt;br /&gt;
Теперь видим, что настройки появились:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Настройки (2).png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Вопрос только - что с ними делать? Ставим рядом галку, в пиктографическом меню нажимаем &amp;quot;Редактировать&amp;quot; - и видим ту же самую форму, что только что заполнили. Где логотип, где копирайт? Так мы незаметно подошли к большой теме - [[Шаблоны данных сайта|Создание шаблонов данных]].&lt;br /&gt;
&lt;br /&gt;
== Вывод настроек в шаблоне ==&lt;br /&gt;
&lt;br /&gt;
Добавим в настройки логотип и копирайт:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 UMI CMS - Редактирование.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь попробуем вывести всё это на страницах сайта.&lt;br /&gt;
&lt;br /&gt;
И тут мы сталкиваемся с очередной засадой UMI CMS. Казалось бы, каждому сайту должен соответствовать какой-то один набор настроек. Но в интерфейсе видим, что этих наборов можно создать сколько угодно. '''Господа разработчики''', может, стоило бы для упрощения ограничить эти возможности? Кто-то вообще использует больше одного набора настроек для конкретной языковой версии сайта? Было бы шикарно получать настройки прямо в массиве $variables, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Зато есть повод поупражняться с API системы. Один из способов получить настройки - использовать название настроек, в данном случае 'demo':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$settings = $this-&amp;gt;getObjectById($this-&amp;gt;macros('umiSettings', 'getIdByName', 'demo']));&lt;br /&gt;
var_dump($settings);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь мы использовали метод getIdByName('...') модуля umiSettings для получения id настроек по названию (это именно название, не идентификатор), а потом получили сам объект настроек при помощи метода getObjectById().&lt;br /&gt;
&lt;br /&gt;
Добавим этот код в самое начало common.phtml. К счастью, в настройках разных языковых версий можно задавать одно и то же название, а то было бы совсем грустно. В общем, получилось. Если добавить на страницу &amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;, то увидим копирайт, который ввели.&lt;br /&gt;
&lt;br /&gt;
Теперь попробуем другой путь, ведь мы не фанаты делать кучу настроек:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$set = new selector('objects');&lt;br /&gt;
$set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
$set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
$set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
$set-&amp;gt;limit(0, 1);&lt;br /&gt;
$settings = $set-&amp;gt;result(); &lt;br /&gt;
var_dump($settings);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде был использован самый мощный класс ядра UMI - selector. Он подробно описан в документации. Чего в документации нет, так это - что подставлять в качестве 'object-type'. Но в админке есть где посмотреть: 'Шаблоны данных' - 'Настройки модуля' (ссылка справа вверху). Для начала лучше в этих настройках ничего не менять, но в качестве справочника - бесценно!&lt;br /&gt;
&lt;br /&gt;
Здесь мы ищем селектором те единственные настройки, что соответствуют конкретной языковой версии нашего сайта. Синтаксически это почти SQL-запрос, на мой взгляд, тут всё просто.&lt;br /&gt;
&lt;br /&gt;
UMI CMS в конце каждой страницы выдает время её формирования, что очень удобно. Легко убедиться, что второй способ на 0.001 секунды быстрее, помимо прочих его преимуществ. Конечно, неплохо бы проверить, что хоть какие-то настройки нашлись. Кроме этого, хотелось бы получить настройки в самом начале, а использовать их в произвольных фрагментах нашего шаблона. В результате модифицируем код common.phtml как-то так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$set = new selector('objects');&lt;br /&gt;
$set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
$set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
$set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
$set-&amp;gt;limit(0, 1);&lt;br /&gt;
$variables['settings'] = array_shift($set-&amp;gt;result()); &lt;br /&gt;
if (empty($variables['settings'])) {&lt;br /&gt;
    echo $this-&amp;gt;translate('no settings');&lt;br /&gt;
    exit();&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Копирайт мы собирались использовать в подвале сайта, поэтому пишем в footer.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?= $variables['settings']-&amp;gt;copyright ?&amp;gt;&amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверяем результат - всё получилось! Теперь надо разобраться с логотипом. Добавляем &amp;lt;?php var_dump($variables['settings']-&amp;gt;logo); ?&amp;gt; в файл header.phtml, и видим, что это объект. Причем - ещё одна засада UMI CMS - все свойства без исключения protected!!! Зато в нем есть все, что нам нужно. Итак, изучаем документацию по классам umiFile и umiImageFile, и новый header.phtml будет выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
$logo = $variables['settings']-&amp;gt;logo;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($logo): ?&amp;gt;&lt;br /&gt;
                &amp;lt;img src=&amp;quot;/&amp;lt;?= $logo-&amp;gt;getFilePath() ?&amp;gt;&amp;quot; title=&amp;quot;&amp;lt;?= $logo-&amp;gt;getTitle() ?&amp;gt;&amp;quot; alt=&amp;quot;&amp;lt;?= $logo-&amp;gt;getAlt() ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php endif; ?&amp;gt;&lt;br /&gt;
            &amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Почему перед адресом изображения стоит '/'? Потому что getFilePath() зачем-то перед адресом ставит точку, хоть адрес возвращает абсолютный. Загадка. В качестве alt и title пробуем получить значения, которые должны были задать в админке при заливке файла. Но поскольку ничего не задали, они будут пустые. А вообще, по-хорошему, надо добавить в настройки еще одно поле - название компании, и выводить именно его.&lt;br /&gt;
&lt;br /&gt;
== Edit-in-place для настроек ==&lt;br /&gt;
&lt;br /&gt;
Теперь осталось добавить возможность изменять эти поля прямо на сайте. В принципе, ничего сложного:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;img umi:object-id=&amp;quot;&amp;lt;?= $logo-&amp;gt;getId() ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;logo&amp;quot; src=&amp;quot;/&amp;lt;?= $logo-&amp;gt;getFilePath() ?&amp;gt;&amp;quot; title=&amp;quot;&amp;lt;?= $logo-&amp;gt;getTitle() ?&amp;gt;&amp;quot; alt=&amp;quot;&amp;lt;?= $logo-&amp;gt;getAlt() ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это для логотипа, а для копирайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $logo-&amp;gt;getId() ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;logo&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_copyright') ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?= $variables['settings']-&amp;gt;copyright ?&amp;gt;&lt;br /&gt;
    &amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что псевдо-атрибуты для id контентных страниц и объектов отличаются, если для полей страниц мы использовали атрибут umi:element-id, то для полей объектов приходится писать umi:object-id. Это отражение внутреннего деления UMI CMS на страницы контента и объекты, за работу с которыми отвечают разные методы.&lt;br /&gt;
&lt;br /&gt;
Также пришлось добавить дополнительный &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt;, чтобы копирайт был в отдельном контейнере.&lt;br /&gt;
&lt;br /&gt;
== Другие модули системы ==&lt;br /&gt;
&lt;br /&gt;
Пока нам для сайта хватало модуля content, немного использовали umiSettings. Однако полезных модулей гораздо больше, и пора наконец [[Другие модули системы|добавить на сайт раздел Новости]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=367</id>
		<title>Создание &quot;правильного&quot; шаблона для сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=367"/>
		<updated>2020-11-05T20:04:50Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Добавляем меню */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для компактности HTML кода буду использовать библиотеку Bootstrap4 - пользуйтесь своими любимыми фреймворками, если не нравится. Итак, сделаем код нашего шаблона несколько более полным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $page-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;description ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;keywords ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В &amp;lt;head&amp;gt; добавили тэг &amp;lt;base ...&amp;gt;, потому что в дальнейшем все, что касается конкретного сайта, планируем хранить в папке конкретного шаблона, в нашем случае default. UMI CMS считает папку шаблона корневой директорией сайта, но это не распространяется на стили, скрипты и картинки.&lt;br /&gt;
&lt;br /&gt;
Теперь главная страница сайта приобрела более &amp;quot;причёсанный&amp;quot; вид:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Главная.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заметим, что Title у страницы пустой, что не слишком хорошо. Можно прописывать это поле для каждой страницы. Но есть способ получше.&lt;br /&gt;
&lt;br /&gt;
== Настраиваем Title и другие SEO-параметры ==&lt;br /&gt;
&lt;br /&gt;
В шаблоне меняем строки заголовка, описания и ключевых слов на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $this-&amp;gt;escape($variables['title']) ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и видим теперь заголовок &amp;lt;title&amp;gt;UMI.CMS - Страница 1&amp;lt;/title&amp;gt;. Нам &amp;quot;UMI.CMS - &amp;quot; ни разу не нужно. Чтобы настроить параметры по умолчанию, в модулях (под бабочкой) находим раздел SEO, в нем справа вверху видим ссылку &amp;quot;Настройка модуля&amp;quot;, жмём и настраиваем, там всё просто. Заменяю &amp;quot;UMI.CMS - &amp;quot; на &amp;quot;Демонстрационный сайт - &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чем отличается от прежнего варианта шаблона? Тем, что мы не выводим тупо поле из данных конкретной страницы, а позволяем CMS сформировать для нас эти параметры, используя настройки по умолчанию.&lt;br /&gt;
&lt;br /&gt;
== Делим шаблон на части ==&lt;br /&gt;
&lt;br /&gt;
Чтобы не мучиться с длинной простынёй кода, существует хорошая практика делить его на разумные фрагменты. Скажем, сразу хочется выделить &amp;lt;head&amp;gt;, &amp;lt;header&amp;gt; и &amp;lt;footer&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В директории /templates/default/php/ создаём поддиректорию layout, а в ней файлы наших фрагментов:&lt;br /&gt;
&lt;br /&gt;
* head.phtml&lt;br /&gt;
* header.phtml&lt;br /&gt;
* main.phtml&lt;br /&gt;
* footer.phtml&lt;br /&gt;
&lt;br /&gt;
Помещаем в эти файлы фрагменты кода шаблонов, например, head.phtml будет выглядеть вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А main.phtml вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь в шаблоне можно просто подключить эти фрагменты:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в качестве первого параметра при вызове метода render() мы передаем массив $variables конкретной страницы. Второй параметр - это адрес шаблона относительно папки php и без расшмрения &amp;quot;.phtml&amp;quot;. Поэтому делать у файлов шаблона именно такое расширение - '''обязательно'''! Иначе не найдет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем меню ==&lt;br /&gt;
&lt;br /&gt;
Выше мы использовали волшебную переменную $this, но для вызова только одного метода - render(). А какие еще методы нам доступны?&lt;br /&gt;
&lt;br /&gt;
Полный список был бы весьма желателен. Но если кратко - все публичные методы модуля '''content''', их описание и код можно посмотреть в /classes/components/content/class.php и /classes/components/content/macros.php, а также системные и сервисные методы, наследуемые этими классами. Методы класса можно использовать непосредственно, макросы - при помощи метода macros().&lt;br /&gt;
&lt;br /&gt;
Нам для сайта надо получить &amp;quot;дерево&amp;quot; меню. Для этого в файл header.phtml добавляем код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
var_dump($menuTree);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый параметр метода macros() - название модуля, второй - название метода, третий - параметры, передаваемые методу. Список параметров можно посмотреть в коде метода, все макросы хорошо документированы комментариями. В данном случае используем:&lt;br /&gt;
&lt;br /&gt;
* шаблон не задан (шаблон задается в других шаблонизаторах, в PHP не работает)&lt;br /&gt;
* 2 уровня вложенности (у нас пока один, но можем потом добавить)&lt;br /&gt;
* начиная от корня сайта (можно указать id страницы, и тогда &amp;quot;дерево&amp;quot; будет построено от неё)&lt;br /&gt;
* выдавать признак, что есть дочерние страницы&lt;br /&gt;
* id текущей страницы передаем, чтобы в результате этот пункт был выделен как активный.&lt;br /&gt;
&lt;br /&gt;
Чтобы изучить возможность добавления второго уровня, добавим вложенную страницу внутрь нашей &amp;quot;Страницы 1&amp;quot;. Для этого с разделе &amp;quot;Структура&amp;quot; сайта ставим галочку рядом со &amp;quot;Страница 1&amp;quot; и нажимаем плюс в меню. Назовем ее &amp;quot;Страница 3&amp;quot; и page3 в качестве псевдостатического адреса. Обновляем страницу в браузере - в массиве $menuTree ничего не поменялось!!!&lt;br /&gt;
&lt;br /&gt;
Это очередная засада UMI CMS. Чтобы используемый нами макрос выдавал вложенные страницы, надо в данном случае на &amp;quot;Странице 1&amp;quot; в '''Дополнительных параметрах''' поставить признаки &amp;quot;Меню всегда развернуто&amp;quot; и &amp;quot;Показывать подменю&amp;quot;. Понятно, что это вопрос умолчаний, но в современных сайтах чаще используется развернутое меню, управляемое JS, а не как раньше - статическое индивидуальное меню для каждой страницы.&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', может, пора уже облегчить жизнь редакторам сайтов, и изменить настройки? Пусть у всех страниц эти признаки будут по умолчанию включены, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Полюбовавшись структурой полученного массива, можем теперь вывести нормальное меню сайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Логотип&amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']);&lt;br /&gt;
        $active = !empty($item['status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом виде сайт уже почти настоящий. На страницах выводится то, что перед этим мы закинули через админку. Но хотелось бы иметь возможность вносить правки прямо на сайте. UMI CMS дает такую возможность, её надо просто [[Добавление возможности Edit-in-place|внести в наш шаблон]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=366</id>
		<title>Создание &quot;правильного&quot; шаблона для сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=366"/>
		<updated>2020-11-05T20:00:58Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Делим шаблон на части */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для компактности HTML кода буду использовать библиотеку Bootstrap4 - пользуйтесь своими любимыми фреймворками, если не нравится. Итак, сделаем код нашего шаблона несколько более полным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $page-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;description ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;keywords ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В &amp;lt;head&amp;gt; добавили тэг &amp;lt;base ...&amp;gt;, потому что в дальнейшем все, что касается конкретного сайта, планируем хранить в папке конкретного шаблона, в нашем случае default. UMI CMS считает папку шаблона корневой директорией сайта, но это не распространяется на стили, скрипты и картинки.&lt;br /&gt;
&lt;br /&gt;
Теперь главная страница сайта приобрела более &amp;quot;причёсанный&amp;quot; вид:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Главная.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заметим, что Title у страницы пустой, что не слишком хорошо. Можно прописывать это поле для каждой страницы. Но есть способ получше.&lt;br /&gt;
&lt;br /&gt;
== Настраиваем Title и другие SEO-параметры ==&lt;br /&gt;
&lt;br /&gt;
В шаблоне меняем строки заголовка, описания и ключевых слов на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $this-&amp;gt;escape($variables['title']) ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и видим теперь заголовок &amp;lt;title&amp;gt;UMI.CMS - Страница 1&amp;lt;/title&amp;gt;. Нам &amp;quot;UMI.CMS - &amp;quot; ни разу не нужно. Чтобы настроить параметры по умолчанию, в модулях (под бабочкой) находим раздел SEO, в нем справа вверху видим ссылку &amp;quot;Настройка модуля&amp;quot;, жмём и настраиваем, там всё просто. Заменяю &amp;quot;UMI.CMS - &amp;quot; на &amp;quot;Демонстрационный сайт - &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чем отличается от прежнего варианта шаблона? Тем, что мы не выводим тупо поле из данных конкретной страницы, а позволяем CMS сформировать для нас эти параметры, используя настройки по умолчанию.&lt;br /&gt;
&lt;br /&gt;
== Делим шаблон на части ==&lt;br /&gt;
&lt;br /&gt;
Чтобы не мучиться с длинной простынёй кода, существует хорошая практика делить его на разумные фрагменты. Скажем, сразу хочется выделить &amp;lt;head&amp;gt;, &amp;lt;header&amp;gt; и &amp;lt;footer&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В директории /templates/default/php/ создаём поддиректорию layout, а в ней файлы наших фрагментов:&lt;br /&gt;
&lt;br /&gt;
* head.phtml&lt;br /&gt;
* header.phtml&lt;br /&gt;
* main.phtml&lt;br /&gt;
* footer.phtml&lt;br /&gt;
&lt;br /&gt;
Помещаем в эти файлы фрагменты кода шаблонов, например, head.phtml будет выглядеть вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А main.phtml вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь в шаблоне можно просто подключить эти фрагменты:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в качестве первого параметра при вызове метода render() мы передаем массив $variables конкретной страницы. Второй параметр - это адрес шаблона относительно папки php и без расшмрения &amp;quot;.phtml&amp;quot;. Поэтому делать у файлов шаблона именно такое расширение - '''обязательно'''! Иначе не найдет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем меню ==&lt;br /&gt;
&lt;br /&gt;
Выше мы использовали волшебную переменную $this, но для вызова только одного метода - render(). А какие еще методы нам доступны?&lt;br /&gt;
&lt;br /&gt;
Полный список был бы весьма желателен. Но если кратко - все публичные методы модуля '''content''', их описание и код можно посмотреть в /classes/components/content/class.php и /classes/components/content/macros.php, а также системные и сервисные методы, наследуемые этими классами. Методы класса можно использовать непосредственно, макросы - при помощи метода macros().&lt;br /&gt;
&lt;br /&gt;
Нам для сайта надо получить &amp;quot;дерево&amp;quot; меню. Для этого в файл header.phtml добавляем код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
var_dump($menuTree);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый параметр метода macros() - название модуля, второй - название метода, третий - параметры, передаваемые методу. Список параметров можно посмотреть в коде метода, все макросы хорошо документированы комментариями. В данном случае используем:&lt;br /&gt;
&lt;br /&gt;
* шаблон не задан (шаблон задается в других шаблонизаторах, в PHP не работает)&lt;br /&gt;
* 2 уровня вложенности (у нас пока один, но можем потом добавить)&lt;br /&gt;
* начиная от корня сайта (можно указать id страницы, и тогда &amp;quot;дерево&amp;quot; будет построено от неё)&lt;br /&gt;
* выдавать признак, что есть дочерние страницы&lt;br /&gt;
* id текущей страницы передаем, чтобы в результате этот пункт был выделен как активный.&lt;br /&gt;
&lt;br /&gt;
Чтобы изучить возможность добавления второго уровня, добавим вложенную страницу внутрь нашей &amp;quot;Страницы 1&amp;quot;. Для этого с разделе &amp;quot;Структура&amp;quot; сайта ставим галочку рядом со &amp;quot;Страница 1&amp;quot; и нажимаем плюс в меню. Назовем ее &amp;quot;Страница 3&amp;quot; и page3 в качестве псевдостатического адреса. Обновляем страницу в браузере - в массиве $menuTree ничего не поменялось!!!&lt;br /&gt;
&lt;br /&gt;
Это очередная засада UMI CMS. Чтобы используемый нами макрос выдавал вложенные страницы, надо в данном случае на &amp;quot;Странице 1&amp;quot; в '''Дополнительных параметрах''' поставить признаки &amp;quot;Меню всегда развернуто&amp;quot; и &amp;quot;Показывать подменю&amp;quot;. Понятно, что это вопрос умолчаний, но в современных сайтах чаще используется развернутое меню, управляемое JS, а не как раньше - статическое индивидуальное меню для каждой страницы.&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', может, пора уже облегчить жизнь редакторам сайтов, и изменить настройки? Пусть у всех страниц эти признаки будут по умолчанию включены, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Полюбовавшись структурой полученного массива, можем теперь вывести нормальное меню сайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Логотип&amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['void:lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['nodes:item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом виде сайт уже почти настоящий. На страницах выводится то, что перед этим мы закинули через админку. Но хотелось бы иметь возможность вносить правки прямо на сайте. UMI CMS дает такую возможность, её надо просто [[Добавление возможности Edit-in-place|внести в наш шаблон]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=365</id>
		<title>Создание &quot;правильного&quot; шаблона для сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=365"/>
		<updated>2020-11-05T20:00:23Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Делим шаблон на части */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для компактности HTML кода буду использовать библиотеку Bootstrap4 - пользуйтесь своими любимыми фреймворками, если не нравится. Итак, сделаем код нашего шаблона несколько более полным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $page-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;description ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;keywords ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В &amp;lt;head&amp;gt; добавили тэг &amp;lt;base ...&amp;gt;, потому что в дальнейшем все, что касается конкретного сайта, планируем хранить в папке конкретного шаблона, в нашем случае default. UMI CMS считает папку шаблона корневой директорией сайта, но это не распространяется на стили, скрипты и картинки.&lt;br /&gt;
&lt;br /&gt;
Теперь главная страница сайта приобрела более &amp;quot;причёсанный&amp;quot; вид:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Главная.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заметим, что Title у страницы пустой, что не слишком хорошо. Можно прописывать это поле для каждой страницы. Но есть способ получше.&lt;br /&gt;
&lt;br /&gt;
== Настраиваем Title и другие SEO-параметры ==&lt;br /&gt;
&lt;br /&gt;
В шаблоне меняем строки заголовка, описания и ключевых слов на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $this-&amp;gt;escape($variables['title']) ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и видим теперь заголовок &amp;lt;title&amp;gt;UMI.CMS - Страница 1&amp;lt;/title&amp;gt;. Нам &amp;quot;UMI.CMS - &amp;quot; ни разу не нужно. Чтобы настроить параметры по умолчанию, в модулях (под бабочкой) находим раздел SEO, в нем справа вверху видим ссылку &amp;quot;Настройка модуля&amp;quot;, жмём и настраиваем, там всё просто. Заменяю &amp;quot;UMI.CMS - &amp;quot; на &amp;quot;Демонстрационный сайт - &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чем отличается от прежнего варианта шаблона? Тем, что мы не выводим тупо поле из данных конкретной страницы, а позволяем CMS сформировать для нас эти параметры, используя настройки по умолчанию.&lt;br /&gt;
&lt;br /&gt;
== Делим шаблон на части ==&lt;br /&gt;
&lt;br /&gt;
Чтобы не мучиться с длинной простынёй кода, существует хорошая практика делить его на разумные фрагменты. Скажем, сразу хочется выделить &amp;lt;head&amp;gt;, &amp;lt;header&amp;gt; и &amp;lt;footer&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В директории /templates/default/php/ создаём поддиректорию layout, а в ней файлы наших фрагментов:&lt;br /&gt;
&lt;br /&gt;
* head.phtml&lt;br /&gt;
* header.phtml&lt;br /&gt;
* main.phtml&lt;br /&gt;
* footer.phtml&lt;br /&gt;
&lt;br /&gt;
Помещаем в эти файлы фрагменты кода шаблонов, например, head.phtml будет выглядеть вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А main.phtml вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь в шаблоне можно просто подключить эти фрагменты:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в качестве первого параметра при вызове метода render() мы передаем массив $variables конкретной страницы. Второй параметр - это адрес шаблона относительно папки php и без расшмрения &amp;quot;.phtml&amp;quot;. Поэтому делать у файлов шаблона именно такое расширение - '''обязательно'''! Иначе не найдет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем меню ==&lt;br /&gt;
&lt;br /&gt;
Выше мы использовали волшебную переменную $this, но для вызова только одного метода - render(). А какие еще методы нам доступны?&lt;br /&gt;
&lt;br /&gt;
Полный список был бы весьма желателен. Но если кратко - все публичные методы модуля '''content''', их описание и код можно посмотреть в /classes/components/content/class.php и /classes/components/content/macros.php, а также системные и сервисные методы, наследуемые этими классами. Методы класса можно использовать непосредственно, макросы - при помощи метода macros().&lt;br /&gt;
&lt;br /&gt;
Нам для сайта надо получить &amp;quot;дерево&amp;quot; меню. Для этого в файл header.phtml добавляем код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
var_dump($menuTree);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый параметр метода macros() - название модуля, второй - название метода, третий - параметры, передаваемые методу. Список параметров можно посмотреть в коде метода, все макросы хорошо документированы комментариями. В данном случае используем:&lt;br /&gt;
&lt;br /&gt;
* шаблон не задан (шаблон задается в других шаблонизаторах, в PHP не работает)&lt;br /&gt;
* 2 уровня вложенности (у нас пока один, но можем потом добавить)&lt;br /&gt;
* начиная от корня сайта (можно указать id страницы, и тогда &amp;quot;дерево&amp;quot; будет построено от неё)&lt;br /&gt;
* выдавать признак, что есть дочерние страницы&lt;br /&gt;
* id текущей страницы передаем, чтобы в результате этот пункт был выделен как активный.&lt;br /&gt;
&lt;br /&gt;
Чтобы изучить возможность добавления второго уровня, добавим вложенную страницу внутрь нашей &amp;quot;Страницы 1&amp;quot;. Для этого с разделе &amp;quot;Структура&amp;quot; сайта ставим галочку рядом со &amp;quot;Страница 1&amp;quot; и нажимаем плюс в меню. Назовем ее &amp;quot;Страница 3&amp;quot; и page3 в качестве псевдостатического адреса. Обновляем страницу в браузере - в массиве $menuTree ничего не поменялось!!!&lt;br /&gt;
&lt;br /&gt;
Это очередная засада UMI CMS. Чтобы используемый нами макрос выдавал вложенные страницы, надо в данном случае на &amp;quot;Странице 1&amp;quot; в '''Дополнительных параметрах''' поставить признаки &amp;quot;Меню всегда развернуто&amp;quot; и &amp;quot;Показывать подменю&amp;quot;. Понятно, что это вопрос умолчаний, но в современных сайтах чаще используется развернутое меню, управляемое JS, а не как раньше - статическое индивидуальное меню для каждой страницы.&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', может, пора уже облегчить жизнь редакторам сайтов, и изменить настройки? Пусть у всех страниц эти признаки будут по умолчанию включены, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Полюбовавшись структурой полученного массива, можем теперь вывести нормальное меню сайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Логотип&amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['void:lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['nodes:item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом виде сайт уже почти настоящий. На страницах выводится то, что перед этим мы закинули через админку. Но хотелось бы иметь возможность вносить правки прямо на сайте. UMI CMS дает такую возможность, её надо просто [[Добавление возможности Edit-in-place|внести в наш шаблон]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=364</id>
		<title>Создание &quot;правильного&quot; шаблона для сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=364"/>
		<updated>2020-11-05T19:58:47Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для компактности HTML кода буду использовать библиотеку Bootstrap4 - пользуйтесь своими любимыми фреймворками, если не нравится. Итак, сделаем код нашего шаблона несколько более полным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $page-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;description ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;keywords ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В &amp;lt;head&amp;gt; добавили тэг &amp;lt;base ...&amp;gt;, потому что в дальнейшем все, что касается конкретного сайта, планируем хранить в папке конкретного шаблона, в нашем случае default. UMI CMS считает папку шаблона корневой директорией сайта, но это не распространяется на стили, скрипты и картинки.&lt;br /&gt;
&lt;br /&gt;
Теперь главная страница сайта приобрела более &amp;quot;причёсанный&amp;quot; вид:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Главная.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заметим, что Title у страницы пустой, что не слишком хорошо. Можно прописывать это поле для каждой страницы. Но есть способ получше.&lt;br /&gt;
&lt;br /&gt;
== Настраиваем Title и другие SEO-параметры ==&lt;br /&gt;
&lt;br /&gt;
В шаблоне меняем строки заголовка, описания и ключевых слов на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $this-&amp;gt;escape($variables['title']) ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и видим теперь заголовок &amp;lt;title&amp;gt;UMI.CMS - Страница 1&amp;lt;/title&amp;gt;. Нам &amp;quot;UMI.CMS - &amp;quot; ни разу не нужно. Чтобы настроить параметры по умолчанию, в модулях (под бабочкой) находим раздел SEO, в нем справа вверху видим ссылку &amp;quot;Настройка модуля&amp;quot;, жмём и настраиваем, там всё просто. Заменяю &amp;quot;UMI.CMS - &amp;quot; на &amp;quot;Демонстрационный сайт - &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чем отличается от прежнего варианта шаблона? Тем, что мы не выводим тупо поле из данных конкретной страницы, а позволяем CMS сформировать для нас эти параметры, используя настройки по умолчанию.&lt;br /&gt;
&lt;br /&gt;
== Делим шаблон на части ==&lt;br /&gt;
&lt;br /&gt;
Чтобы не мучиться с длинной простынёй кода, существует хорошая практика делить его на разумные фрагменты. Скажем, сразу хочется выделить &amp;lt;head&amp;gt;, &amp;lt;header&amp;gt; и &amp;lt;footer&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В директории /templates/default/php/ создаём поддиректорию layout, а в ней файлы наших фрагментов:&lt;br /&gt;
&lt;br /&gt;
* head.phtml&lt;br /&gt;
* header.phtml&lt;br /&gt;
* main.phtml&lt;br /&gt;
* footer.phtml&lt;br /&gt;
&lt;br /&gt;
Помещаем в эти файлы фрагменты кода шаблонов, например, head.phtml будет выглядеть вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А main.phtml вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь в шаблоне можно просто подключить эти фрагменты:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в качестве первого параметра при вызове метода render() мы передаем массив $variables конкретной страницы. Второй параметр - это адрес шаблона относительно папки php и без расшмрения &amp;quot;.phtml&amp;quot;. Поэтому делать у файлов шаблона именно такое расширение - '''обязательно'''! Иначе не найдет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем меню ==&lt;br /&gt;
&lt;br /&gt;
Выше мы использовали волшебную переменную $this, но для вызова только одного метода - render(). А какие еще методы нам доступны?&lt;br /&gt;
&lt;br /&gt;
Полный список был бы весьма желателен. Но если кратко - все публичные методы модуля '''content''', их описание и код можно посмотреть в /classes/components/content/class.php и /classes/components/content/macros.php, а также системные и сервисные методы, наследуемые этими классами. Методы класса можно использовать непосредственно, макросы - при помощи метода macros().&lt;br /&gt;
&lt;br /&gt;
Нам для сайта надо получить &amp;quot;дерево&amp;quot; меню. Для этого в файл header.phtml добавляем код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
var_dump($menuTree);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый параметр метода macros() - название модуля, второй - название метода, третий - параметры, передаваемые методу. Список параметров можно посмотреть в коде метода, все макросы хорошо документированы комментариями. В данном случае используем:&lt;br /&gt;
&lt;br /&gt;
* шаблон не задан (шаблон задается в других шаблонизаторах, в PHP не работает)&lt;br /&gt;
* 2 уровня вложенности (у нас пока один, но можем потом добавить)&lt;br /&gt;
* начиная от корня сайта (можно указать id страницы, и тогда &amp;quot;дерево&amp;quot; будет построено от неё)&lt;br /&gt;
* выдавать признак, что есть дочерние страницы&lt;br /&gt;
* id текущей страницы передаем, чтобы в результате этот пункт был выделен как активный.&lt;br /&gt;
&lt;br /&gt;
Чтобы изучить возможность добавления второго уровня, добавим вложенную страницу внутрь нашей &amp;quot;Страницы 1&amp;quot;. Для этого с разделе &amp;quot;Структура&amp;quot; сайта ставим галочку рядом со &amp;quot;Страница 1&amp;quot; и нажимаем плюс в меню. Назовем ее &amp;quot;Страница 3&amp;quot; и page3 в качестве псевдостатического адреса. Обновляем страницу в браузере - в массиве $menuTree ничего не поменялось!!!&lt;br /&gt;
&lt;br /&gt;
Это очередная засада UMI CMS. Чтобы используемый нами макрос выдавал вложенные страницы, надо в данном случае на &amp;quot;Странице 1&amp;quot; в '''Дополнительных параметрах''' поставить признаки &amp;quot;Меню всегда развернуто&amp;quot; и &amp;quot;Показывать подменю&amp;quot;. Понятно, что это вопрос умолчаний, но в современных сайтах чаще используется развернутое меню, управляемое JS, а не как раньше - статическое индивидуальное меню для каждой страницы.&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', может, пора уже облегчить жизнь редакторам сайтов, и изменить настройки? Пусть у всех страниц эти признаки будут по умолчанию включены, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Полюбовавшись структурой полученного массива, можем теперь вывести нормальное меню сайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Логотип&amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['void:lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['nodes:item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом виде сайт уже почти настоящий. На страницах выводится то, что перед этим мы закинули через админку. Но хотелось бы иметь возможность вносить правки прямо на сайте. UMI CMS дает такую возможность, её надо просто [[Добавление возможности Edit-in-place|внести в наш шаблон]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=363</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=363"/>
		<updated>2020-11-05T19:48:39Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Получение блоков для главной страницы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Даже на этих примерах видно, насколько наглядней становится код шаблонов. Конечно, по сути это все равно обращение к базе в процессе рендеринга шаблона. Но выглядит лучше, и код обращений собран в одном файле.&lt;br /&gt;
&lt;br /&gt;
== Вместо заключения ==&lt;br /&gt;
&lt;br /&gt;
За рамками этой инструкции остались события, это довольно большая тема, и, к счастью, [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/sobytijnaya_model_umicms/ хорошо документированная].&lt;br /&gt;
&lt;br /&gt;
Следующим этапом можно было также рассмотреть методы работы с формами, это, например, раздел личного кабинета пользователя, методы регистрации и авторизации. Но во-первых, на сайте не всегда нужен такой раздел, во-вторых, делать странички с формами, в то время как это давно везде реализовано при помощи модальных окон и AJAX-запросов, мне просто лень.&lt;br /&gt;
&lt;br /&gt;
Надеюсь, инструкция помогла на примерах понять архитектуру UMI CMS и принципы построения новых элементов. Самое время [[Что дальше?|перейти к практике]]!&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=362</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=362"/>
		<updated>2020-11-05T19:28:43Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Получение блоков для главной страницы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Даже на этих примерах видно, насколько наглядней становится код шаблонов. Конечно, по сути это все равно обращение к базе в процессе рендеринга шаблона. Но выглядит лучше, и код обращений собран в одном файле.&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=361</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=361"/>
		<updated>2020-11-05T19:14:41Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Получение блоков для главной страницы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Даже на этих примерах видно, насколько наглядней становится код шаблонов.&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=360</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=360"/>
		<updated>2020-11-05T19:08:08Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Собственный класс сайта */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Пока нам хватит и одного. Но иногда полезно расширения функциональности конкретных модулей группировать в отдельные классы, чтобы проще было ориентироваться в коде.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=359</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=359"/>
		<updated>2020-11-05T19:04:15Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Вызов метода из &amp;quot;чужого&amp;quot; шаблона */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится. Не знаю, кому и зачем это может понадобиться, разве только чтобы в дальнейшем получше запутать себя и коллег.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Но нам хватит и одного.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=358</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=358"/>
		<updated>2020-11-05T19:01:14Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Добавление разрешения на выполнение метода */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобится добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Но нам хватит и одного.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B8_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B&amp;diff=357</id>
		<title>Другие модули системы</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B8_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B&amp;diff=357"/>
		<updated>2020-11-05T18:48:16Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Шаблоны для других модулей */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;До сих пор на нашем сайте использовался только модуль content. Попробуем немного расширить функциональность сайта.&lt;br /&gt;
&lt;br /&gt;
== Новости на сайте ==&lt;br /&gt;
&lt;br /&gt;
Итак, жмём на бабочку и выбираем раздел &amp;quot;Новости&amp;quot;. Новостей, понятно, пока нет, но есть кнопка добавления:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 UMI CMS - Новости и ленты.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Добавляем ленту новостей:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Добавление ленты новостей.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить признак видимости в меню. И наша лента появилась в списке. Что особенно приятно, она же появилась и в структуре:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Если нам хочется поменять порядок следования разделов, можем просто схватить раздел мышкой и перетащить туда, куда нужно. Поставим новости сразу после главной страницы. Просто для тренировки.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 Демонстрационный сайт - Новости.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Во-первых, видим, что никаких новостей нет. Во-вторых, даже когда мы их добавим, всё равно ничего не увидим. Почему? А потому, что для вывода новостей используем тот же шаблон, что и для контентных страниц. Но это легко исправить.&lt;br /&gt;
&lt;br /&gt;
== Шаблоны для других модулей ==&lt;br /&gt;
&lt;br /&gt;
В рамках одного шаблона сайта можно для каждого модуля подключать свой фрагмент. Сделать это очень просто. Достаточно в файле main.phtml вместо кода&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
написать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, &amp;quot;{$variables['module']}/{$variables['method']}&amp;quot;) ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Код, который раньше был в main.phtml, перенести в файл content.phtml, который создать в директории content/ в папке php нашего шаблона:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/dib&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и создать также файл rubric.phtml в директории news/ в той же папке php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если снова вывести массив $variables, увидим, что там есть название модуля и метода, который этот массив формирует. То есть мы фактически для каждого модуля нашей системы должны создать свой фрагмент кода, который бы его отображал. А строка &amp;lt;?= $this-&amp;gt;render($variables, &amp;quot;{$variables['module']}/{$variables['method']}&amp;quot;) ?&amp;gt; этот фрагмент подключит.&lt;br /&gt;
&lt;br /&gt;
Почему список новостей выводится методом rubric, а не list? Видимо, чисто исторически.&lt;br /&gt;
&lt;br /&gt;
Смотрим на выведенный массив $variables - и не видим никаких отличий! Что в общем, логично, новостей-то пока нет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем новости ==&lt;br /&gt;
&lt;br /&gt;
В разделе &amp;quot;Новости&amp;quot; админки ставим галку рядом с новостями, и нажимаем появившуюся как по волшебству кнопку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Новости и ленты.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем открывшуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 UMI CMS - Добавление новости.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Добавим 2 новости, чтобы было не очень пусто. Кстати, можно добавлять новости не только в соответствующем разделе админки, но и в разделе &amp;quot;Структура&amp;quot;, точно так же, поставив галку перед разделом &amp;quot;Новости&amp;quot; и нажав плюс.&lt;br /&gt;
&lt;br /&gt;
Когда обновляем страницу новостей, то видим, что в массиве $variables опять ничего не поменялось!!! Казалось бы, метод rubric должен нам вернуть список последних новостей, но он этого не делает. Не знаю, как других, меня это здорово дезориентирует: несмотря на то, что модуль другой, по сути получаем ту же контентную страницу.&lt;br /&gt;
&lt;br /&gt;
Правда, мы можем использовать методы и макросы модуля.&lt;br /&gt;
&lt;br /&gt;
== Шаблон для списка новостей ==&lt;br /&gt;
&lt;br /&gt;
Меняем код нашего фрагмента rubric.phtml как-то так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'lastlist', [$variables['id']]);&lt;br /&gt;
var_dump($newsList);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;ul class=&amp;quot;list-group&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/ul&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь мы использовали макрос lastlist модуля news, который вернул нам массив, одним из элементов которого является список новостей. Другие элементы содержат вспомогательные параметры для организации списка, в частности, количество новостей на странице (настраивается в админке в &amp;quot;Настройках модуля&amp;quot;). Можно потом использовать для организации постранички (ненавижу термин &amp;quot;пагинация&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Строчку var_dump($newsList); можем убрать. Получилось даже красиво. Жмем на ссылу - и получаем ошибку!&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 Неперехваченное исключение.png|без]]&lt;br /&gt;
&lt;br /&gt;
Что вполне понятно, ведь мы не создали шаблон для отображения конкретной новости.&lt;br /&gt;
&lt;br /&gt;
== Шаблон для текста новости ==&lt;br /&gt;
&lt;br /&gt;
Создадим в папке php в разделе news файл item.phtml, о котором и упоминалось в тексте ошибки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
         &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;em umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;publish_time&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_publish_time') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;publish_time ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;anons ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;anons ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;hr /&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И что же мы видим? В массиве $variables всё та же контентная страница, однако все поля, характерные для новости, в объекте присутствуют, хоть и не видны. Заметим, что дата получилась в формате umiDate, судя по всему, это внутреннее представление базы данных, для преобразования её в нужный формат можно воспользоваться [http://api.docs.umi-cms.ru/spravochnik_po_klassam_yadra_umicms/utilitarnye_klassy/umidate/ соответствующими методами]. Макрос 'lastlist' списка новостей ранее вернул дату в timestump. Вот так оно тут всё неожиданно...&lt;br /&gt;
&lt;br /&gt;
== Шаблон для 404 ==&lt;br /&gt;
&lt;br /&gt;
Теперь наберем в браузере адрес http://umi.example.com/abrakadabra - что получилось? Конечно, ошибка!&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Неперехваченное исключение.png|без]]&lt;br /&gt;
&lt;br /&gt;
Зато понятно, как её исправить - надо в php/content/ создать файл notfound.phtml, например, вот такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
         &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $variables['header'] ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массив $variables как всегда вывели для изучения, но там полезного не слишком много. Если посмотрим заголовки, то увидим, что статус 404 уже отправлен системой, дополнительно его отправлять не требуется.&lt;br /&gt;
&lt;br /&gt;
Вообще удобно сделать страницу 404 прямо на сайте, чтобы была возможность править контент в админке, а не в шаблоне. Для этого можно создать такую страницу, сделать её скрытой, в настройках сайта добавить поле типа &amp;quot;Ссылка на дерево&amp;quot;, указать в этом поле адрес страницы 404, а в этом шаблоне брать оттуда контент. Но оставлю это для [[404 страница|отдельного упражнения]].&lt;br /&gt;
&lt;br /&gt;
== Какие вообще нужны шаблоны? ==&lt;br /&gt;
&lt;br /&gt;
В первую очередь нужны шаблоны модулей, используемых на сайте. В зависимости от редакции набор модулей разный, но, как правило нужны:&lt;br /&gt;
&lt;br /&gt;
* content/&lt;br /&gt;
** content/content.phtml&lt;br /&gt;
** content/nofound.phtml&lt;br /&gt;
* news/&lt;br /&gt;
** news/rubric.phtml&lt;br /&gt;
** news/item.phtml&lt;br /&gt;
** news/subject.phtml - если использовать категории новостей&lt;br /&gt;
* users/ - довольно большой пакет шаблонов с формами регистрации и авторизации, которых мы пока не касались.&lt;br /&gt;
** users/registrate.phtml&lt;br /&gt;
** users/registrate_done.phtml&lt;br /&gt;
** users/activate.phtml&lt;br /&gt;
** users/login.phtml&lt;br /&gt;
** users/login_do.phtml&lt;br /&gt;
** users/logout.phtml&lt;br /&gt;
** users/forget.phtml&lt;br /&gt;
** users/forget_do.phtml&lt;br /&gt;
* search/ - если использовать поиск по сайту&lt;br /&gt;
** search/result.phtml&lt;br /&gt;
** search/search_do.phtml&lt;br /&gt;
&lt;br /&gt;
И, наконец, хотелось бы сделать отдельный шаблон для главной страницы сайта. Но это лучше [[Шаблон для главной страницы|выделить в отдельную тему]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%B4%D0%BB%D1%8F_%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%BE%D0%B9_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B&amp;diff=356</id>
		<title>Шаблон для главной страницы</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%B4%D0%BB%D1%8F_%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%BE%D0%B9_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B&amp;diff=356"/>
		<updated>2020-11-05T15:25:08Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Как правило, стартовая страница сайта отличается от остальных. Как отразить эту особенность в нашем шаблоне?&lt;br /&gt;
&lt;br /&gt;
Вообще-то очень просто. В массиве $variables есть элемент 'is-default', который мы можем проверить. И если он true, то подтягиваем шаблон главной. Если нет - страницы нужного модуля. Вставим эту проверку в файл main.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if ($variables['is-default']) echo $this-&amp;gt;render($variables, &amp;quot;content/home/index&amp;quot;);&lt;br /&gt;
else echo $this-&amp;gt;render($variables, &amp;quot;{$variables['module']}/{$variables['method']}&amp;quot;);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В объекте $variables['page'] тоже есть такое свойство, но получить его невозможно. Оно, конечно, private. Всегда будет false.&lt;br /&gt;
&lt;br /&gt;
И надо создать в папке php фрагмент шаблона content/home/index.phtml, который подключаем. Для начала пусть будет просто контентная страница:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Добавление блоков ==&lt;br /&gt;
&lt;br /&gt;
Обычно на главную страницу стараются запихнуть весь контент сайта. Наверно потому, что не надеются, что пользователь настолько заинтересуется, что пройдет куда-то ещё. &lt;br /&gt;
&lt;br /&gt;
Продолжим эту скверную традицию. У нас есть контент главной страницы, где можно разместить информацию о компании или продукте, и новости. Явно не хватает контактов, которые лучше добавить в настройки:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 5 UMI CMS - Редактирование типа данных.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Чтобы к этому не возвращаться, добавим все поля, которые хотели, в частности, ссылки на дерево для новостей и 404 ошибки, а также название компании. Новости уже есть, осталось в настройках выбрать нужный раздел, а вот 404 страницы нет, [[404 страница|создадим её]].&lt;br /&gt;
&lt;br /&gt;
Вообще хорошим тоном является не портить шаблон данных &amp;quot;Настройки&amp;quot;, а создать дочерний шаблон, куда и внести все нужные поля. Это без сомнения пригодится, если на одной системе делать несколько сайтов с разным набором настроек.&lt;br /&gt;
&lt;br /&gt;
=== Разбиваем шаблон на блоки ===&lt;br /&gt;
&lt;br /&gt;
Чтобы не тащить простыню кода, разделим content/home/index.phtml на фрагменты по блокам:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $this-&amp;gt;render($variables, &amp;quot;content/home/intro&amp;quot;);&lt;br /&gt;
echo $this-&amp;gt;render($variables, &amp;quot;content/home/news&amp;quot;);&lt;br /&gt;
echo $this-&amp;gt;render($variables, &amp;quot;content/home/contacts&amp;quot;);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вводный текст ===&lt;br /&gt;
&lt;br /&gt;
Фрагмент content/home/intro.phtml останется аналогом контентной страницы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Новости ===&lt;br /&gt;
&lt;br /&gt;
Фрагмент для новостей content/home/news.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$newsListSettings = $variables['settings']-&amp;gt;newslist;&lt;br /&gt;
if (!empty($newsListSettings)) $newsPageId = $newsListSettings[0]-&amp;gt;id;&lt;br /&gt;
else $newsPageId = false;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'lastlist', [$newsPageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h2&amp;gt;Что нового?&amp;lt;/h2&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;ul class=&amp;quot;list-group&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/ul&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Контакты ===&lt;br /&gt;
&lt;br /&gt;
Фрагмент для контактов content/home/contacts.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h2&amp;gt;Контакты&amp;lt;/h2&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                            &amp;lt;div class=&amp;quot;col-6&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;h3&amp;gt;&amp;lt;?= $this-&amp;gt;translate('address') ?&amp;gt;&amp;lt;/h3&amp;gt;&lt;br /&gt;
                            &amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;div class=&amp;quot;col-6&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;h3 umi:object-id=&amp;quot;&amp;lt;?= $variables['settings']-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;address&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_address') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $variables['settings']-&amp;gt;address ?&amp;gt;&amp;lt;/h3&amp;gt;&lt;br /&gt;
                            &amp;lt;/div&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                            &amp;lt;div class=&amp;quot;col-6&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;h3&amp;gt;&amp;lt;?= $this-&amp;gt;translate('phone') ?&amp;gt;&amp;lt;/h3&amp;gt;&lt;br /&gt;
                            &amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;div class=&amp;quot;col-6&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;h3 umi:object-id=&amp;quot;&amp;lt;?= $variables['settings']-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;phone&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_phone') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $variables['settings']-&amp;gt;phone ?&amp;gt;&amp;lt;/h3&amp;gt;&lt;br /&gt;
                            &amp;lt;/div&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Не забываем пополнять файлы i18n/i18n.ru.php и i18n/i18n.en.php новыми языковыми константами, которые появляются в шаблонах нашего сайта. Также добавили разметку для Edit-in-place, и теперь можем внести адрес и телефон прямо на &amp;quot;морде&amp;quot; сайта.&lt;br /&gt;
&lt;br /&gt;
== Организация блоков на главной странице ==&lt;br /&gt;
&lt;br /&gt;
Хотелось бы дать возможность редактору сайта регулировать контент на главной странице, добавлять и убирать блоки, и чтобы все изменения появлялись на сайте автоматически.&lt;br /&gt;
&lt;br /&gt;
Кто-то из новых разработчиков задал аналогичный вопрос в группе, получил много ответов, которые его не устроили по причине сложной реализации. Что он сделал после этого? У него была верстка, вся такая из разноцветных блоков. Он в &amp;quot;Шаблонах данных&amp;quot; добавил дочерний шаблон в &amp;quot;Раздел сайта&amp;quot;, назвал его &amp;quot;Главная&amp;quot;, и добавил туда кучу полей типа HTML-текст с кодом section1, section2 и т.д. После чего скопировал код соответствующих блоков из верстки, и вставил в эти поля. Шаблон главной у него при этом получился, видимо, такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;?= ($page-&amp;gt;section1)?$page-&amp;gt;section1:'' ?&amp;gt;&lt;br /&gt;
&amp;lt;?= ($page-&amp;gt;section2)?$page-&amp;gt;section2:'' ?&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А что, так можно было??? Конечно, можно. Но некрасиво, и нельзя поменять блоки местами.&lt;br /&gt;
&lt;br /&gt;
Мне больше нравится другой способ. Создаём в разделе главной страницы несколько подразделов, например, вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 22 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Псевдостатические адреса задаём intro, news и contacts соответственно. После чего шаблон главной страницы приобретает вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = [];&lt;br /&gt;
$hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
$children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
    $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
    if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
        $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
        $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
        $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
        $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
        $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$resourcesDir = cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    $page['settings'] = $variables['settings'];&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кода получилось немного больше, но в следующей статье исправим этот недостаток. Подключили класс umiHierarchy, выбрали все дочерние страницы, выбрали соответствующие объекты и наполнили массив $blocks. Да, еще добыли путь к корневой папке нашего шаблона, чтобы не задавать статикой. В качестве данных передаём в render() массив $page, куда добавили $variables['settings'], чтобы не потерять настройки. Вообще это лучше делать по-другому, но об этом чуть позже.&lt;br /&gt;
&lt;br /&gt;
Теперь надо поменять немного шаблоны блоков, чтобы брать оттуда контент соответствующих подразделов.&lt;br /&gt;
&lt;br /&gt;
=== Вступительный текст ===&lt;br /&gt;
&lt;br /&gt;
В метод render() мы уже передаем не $variables, а элемент массива, содержащий данные подраздела. Здесь название массива по-прежнему будет $variables, но содержимое будет уже другим. Поэтому:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $variables['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $variables['h1'] ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $variables['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $variables['content'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Остальные шаблоны ===&lt;br /&gt;
&lt;br /&gt;
Все, что нам нужно из остальных подразделов - это заголовки, которые специально до этого были оставлены в виде слов. Поэтому меняем только одну строку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h2 umi:element-id=&amp;quot;&amp;lt;?= $variables['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $variables['h1'] ?&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== В чем преимущество? ===&lt;br /&gt;
&lt;br /&gt;
Редактор сайта получает больше возможностей для изменения контента главной, можно использовать Edit-in-place для исправления заголовков блоков, можно менять блоки местами. Попробуйте и убедитесь.&lt;br /&gt;
&lt;br /&gt;
Вообще я обычно использую 2 уровня вложенности подразделов, чтобы внутри каждого из блоков отображать список дочерних блоков. Это очень удобно для программирования современных сайтов, где есть блоки &amp;quot;Наши преимущества&amp;quot;, &amp;quot;Наша команда&amp;quot; и &amp;quot;Отзывы наших клиентов&amp;quot;, содержащие свои списки данных. Понятно, что кроме заголовка и контента можно добавлять картинки, пиктограммы, анонсы - всё, что только может понадобиться.&lt;br /&gt;
&lt;br /&gt;
Но есть и недостаток - много кода в шаблоне. Хорошим тоном в UMI считается, если в шаблоне вообще не используется API. Это правильно и с точки зрения MVC. Поэтому пора перейти к [[Расширение функциональности модулей|созданию кастомных методов и функций]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B8_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B&amp;diff=355</id>
		<title>Другие модули системы</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B8_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B&amp;diff=355"/>
		<updated>2020-11-05T15:23:15Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Шаблоны для других модулей */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;До сих пор на нашем сайте использовался только модуль content. Попробуем немного расширить функциональность сайта.&lt;br /&gt;
&lt;br /&gt;
== Новости на сайте ==&lt;br /&gt;
&lt;br /&gt;
Итак, жмём на бабочку и выбираем раздел &amp;quot;Новости&amp;quot;. Новостей, понятно, пока нет, но есть кнопка добавления:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 UMI CMS - Новости и ленты.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Добавляем ленту новостей:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Добавление ленты новостей.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить признак видимости в меню. И наша лента появилась в списке. Что особенно приятно, она же появилась и в структуре:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Если нам хочется поменять порядок следования разделов, можем просто схватить раздел мышкой и перетащить туда, куда нужно. Поставим новости сразу после главной страницы. Просто для тренировки.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 Демонстрационный сайт - Новости.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Во-первых, видим, что никаких новостей нет. Во-вторых, даже когда мы их добавим, всё равно ничего не увидим. Почему? А потому, что для вывода новостей используем тот же шаблон, что и для контентных страниц. Но это легко исправить.&lt;br /&gt;
&lt;br /&gt;
== Шаблоны для других модулей ==&lt;br /&gt;
&lt;br /&gt;
В рамках одного шаблона сайта можно для каждого модуля подключать свой фрагмент. Сделать это очень просто. Достаточно в файле main.phtml вместо кода&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
написать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, &amp;quot;{$variables['module']}/{$variables['method']}&amp;quot;) ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Код, который раньше был в main.phtml, перенести в файл content.phtml, который создать в директории content/ в папке php нашего шаблона:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/dib&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и создать также файл rubric.phtml в директории news/ в той же папке php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если снова вывести массив $variables, увидим, что там есть название модуля и метода, который этот массив формирует. То есть мы фактически для каждого модуля нашей системы должны создать свой фрагмент кода, который бы его отображал. А строка &amp;lt;?= $this-&amp;gt;render($variables, &amp;quot;{$variables['module']}/{$variables['method']}&amp;quot;) ?&amp;gt; этот фрагмент подключит.&lt;br /&gt;
&lt;br /&gt;
Почему список новостей выводится методом rubric, а не list? Видимо, чисто исторически.&lt;br /&gt;
&lt;br /&gt;
Смотрим на выведенный массив $variables - и не видим никаких отличий! Что в общем, логично, новостей-то пока нет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем новости ==&lt;br /&gt;
&lt;br /&gt;
В разделе &amp;quot;Новости&amp;quot; админки ставим галку рядом с новостями, и нажимаем появившуюся как по волшебству кнопку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Новости и ленты.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем открывшуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 UMI CMS - Добавление новости.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Добавим 2 новости, чтобы было не очень пусто. Кстати, можно добавлять новости не только в соответствующем разделе админки, но и в разделе &amp;quot;Структура&amp;quot;, точно так же, поставив галку перед разделом &amp;quot;Новости&amp;quot; и нажав плюс.&lt;br /&gt;
&lt;br /&gt;
Когда обновляем страницу новостей, то видим, что в массиве $variables опять ничего не поменялось!!! Казалось бы, метод rubric должен нам вернуть список последних новостей, но он этого не делает. Не знаю, как других, меня это здорово дезориентирует: несмотря на то, что модуль другой, по сути получаем ту же контентную страницу.&lt;br /&gt;
&lt;br /&gt;
Правда, мы можем использовать методы и макросы модуля.&lt;br /&gt;
&lt;br /&gt;
== Шаблон для списка новостей ==&lt;br /&gt;
&lt;br /&gt;
Меняем код нашего фрагмента rubric.phtml как-то так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'lastlist', [$variables['id']]);&lt;br /&gt;
var_dump($newsList);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;ul class=&amp;quot;list-group&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/ul&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь мы использовали макрос lastlist модуля news, который вернул нам массив, одним из элементов которого является список новостей. Другие элементы содержат вспомогательные параметры для организации списка, в частности, количество новостей на странице (настраивается в админке в &amp;quot;Настройках модуля&amp;quot;). Можно потом использовать для организации постранички (ненавижу термин &amp;quot;пагинация&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Строчку var_dump($newsList); можем убрать. Получилось даже красиво. Жмем на ссылу - и получаем ошибку!&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 Неперехваченное исключение.png|без]]&lt;br /&gt;
&lt;br /&gt;
Что вполне понятно, ведь мы не создали шаблон для отображения конкретной новости.&lt;br /&gt;
&lt;br /&gt;
== Шаблон для текста новости ==&lt;br /&gt;
&lt;br /&gt;
Создадим в папке php в разделе news файл item.phtml, о котором и упоминалось в тексте ошибки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
         &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;em umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;publish_time&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_publish_time') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;publish_time ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;anons ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;anons ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;hr /&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И что же мы видим? В массиве $variables всё та же контентная страница, однако все поля, характерные для новости, в объекте присутствуют, хоть и не видны. Заметим, что дата получилась в формате umiDate, судя по всему, это внутреннее представление базы данных, для преобразования её в нужный формат можно воспользоваться [http://api.docs.umi-cms.ru/spravochnik_po_klassam_yadra_umicms/utilitarnye_klassy/umidate/ соответствующими методами]. Макрос 'lastlist' списка новостей ранее вернул дату в timestump. Вот так оно тут всё неожиданно...&lt;br /&gt;
&lt;br /&gt;
== Шаблон для 404 ==&lt;br /&gt;
&lt;br /&gt;
Теперь наберем в браузере адрес http://umi.example.com/abrakadabra - что получилось? Конечно, ошибка!&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Неперехваченное исключение.png|без]]&lt;br /&gt;
&lt;br /&gt;
Зато понятно, как её исправить - надо в php/content/ создать файл notfound.phtml, например, вот такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
         &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $variables['header'] ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массив $variables как всегда вывели для изучения, но там полезного не слишком много. Если посмотрим заголовки, то увидим, что статус 404 уже отправлен системой, дополнительно его отправлять не требуется.&lt;br /&gt;
&lt;br /&gt;
Вообще удобно сделать страницу 404 прямо на сайте, чтобы была возможность править контент в админке, а не в шаблоне. Для этого можно создать такую страницу, сделать её скрытой, в настройках сайта добавить поле типа &amp;quot;Ссылка на дерево&amp;quot;, указать в этом поле адрес страницы 404, а в этом шаблоне брать оттуда контент. Но оставлю это для [[404 страница|отдельного упражнения]].&lt;br /&gt;
&lt;br /&gt;
== Какие вообще нужны шаблоны? ==&lt;br /&gt;
&lt;br /&gt;
В первую очередь нужны шаблоны модулей, используемых на сайте. В зависимости от редакции набор модулей разный, но, как правило нужны:&lt;br /&gt;
&lt;br /&gt;
* content/&lt;br /&gt;
** content/content.phtml&lt;br /&gt;
** content/nofound.phtml&lt;br /&gt;
* news/&lt;br /&gt;
** news/rubric.phtml&lt;br /&gt;
** news/item.phtml&lt;br /&gt;
** news/subject.phtml - если использовать категории новостей&lt;br /&gt;
* users/ - довольно большой пакет шаблонов с формами регистрации и авторизации, которых мы пока не касались.&lt;br /&gt;
** users/registrate.phtml&lt;br /&gt;
** users/registrate_done.phtml&lt;br /&gt;
** users/activate.phtml&lt;br /&gt;
** users/login.phtml&lt;br /&gt;
** users/login_do.phtml&lt;br /&gt;
** users/logout.phtml&lt;br /&gt;
** users/forget.phtml&lt;br /&gt;
** users/forget_do.phtml&lt;br /&gt;
* search/ - если использовать поиск по сайту&lt;br /&gt;
** search/result.phtml&lt;br /&gt;
** search/search_do.phtml&lt;br /&gt;
&lt;br /&gt;
И, наконец, хотелось бы сделать отдельный шаблон для главной страницы сайта. Но это лучше [[Шаблон для главной страницы|выделить в отдельную тему]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B8_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B&amp;diff=354</id>
		<title>Другие модули системы</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B8_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B&amp;diff=354"/>
		<updated>2020-11-05T15:22:59Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;До сих пор на нашем сайте использовался только модуль content. Попробуем немного расширить функциональность сайта.&lt;br /&gt;
&lt;br /&gt;
== Новости на сайте ==&lt;br /&gt;
&lt;br /&gt;
Итак, жмём на бабочку и выбираем раздел &amp;quot;Новости&amp;quot;. Новостей, понятно, пока нет, но есть кнопка добавления:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 UMI CMS - Новости и ленты.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Добавляем ленту новостей:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Добавление ленты новостей.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить признак видимости в меню. И наша лента появилась в списке. Что особенно приятно, она же появилась и в структуре:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Если нам хочется поменять порядок следования разделов, можем просто схватить раздел мышкой и перетащить туда, куда нужно. Поставим новости сразу после главной страницы. Просто для тренировки.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 Демонстрационный сайт - Новости.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Во-первых, видим, что никаких новостей нет. Во-вторых, даже когда мы их добавим, всё равно ничего не увидим. Почему? А потому, что для вывода новостей используем тот же шаблон, что и для контентных страниц. Но это легко исправить.&lt;br /&gt;
&lt;br /&gt;
== Шаблоны для других модулей ==&lt;br /&gt;
&lt;br /&gt;
В рамках одного шаблона сайта можно для каждого модуля подключать свой фрагмент. Сделать это очень просто. Достаточно в файле main.phtml вместо кода&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
написать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, &amp;quot;{$variables['module']}/{$variables['method']}&amp;quot;) ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Код, который раньше был в main.phtml, перенести в файл content.phtml, который создать в директории content/ в папке php нашего шаблона:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/dib&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и создать также файл rubric.phtml в директории news/ в той же папке php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если снова вывести массив $variables, увидим, что там есть название модуля и метода, который этот массив формирует. То есть мы фактически для каждого модуля нашей системы должны создать свой фрагмент кода, который бы его отображал. А строка &amp;lt;?= $this-&amp;gt;render($variables, &amp;quot;{$variables['module']}/{$variables['method']}&amp;quot;) ?&amp;gt; этот фрагмент подключит.&lt;br /&gt;
&lt;br /&gt;
Почему список новостей выводится методом rubric, а не list? Видимо, чисто исторически.&lt;br /&gt;
&lt;br /&gt;
Смотрим на выведенный массив $variables - и не видим никаких отличий! Что в общем, логично, новостей-то пока нет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем новости ==&lt;br /&gt;
&lt;br /&gt;
В разделе &amp;quot;Новости&amp;quot; админки ставим галку рядом с новостями, и нажимаем появившуюся как по волшебству кнопку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Новости и ленты.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем открывшуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 UMI CMS - Добавление новости.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Добавим 2 новости, чтобы было не очень пусто. Кстати, можно добавлять новости не только в соответствующем разделе админки, но и в разделе &amp;quot;Структура&amp;quot;, точно так же, поставив галку перед разделом &amp;quot;Новости&amp;quot; и нажав плюс.&lt;br /&gt;
&lt;br /&gt;
Когда обновляем страницу новостей, то видим, что в массиве $variables опять ничего не поменялось!!! Казалось бы, метод rubric должен нам вернуть список последних новостей, но он этого не делает. Не знаю, как других, меня это здорово дезориентирует: несмотря на то, что модуль другой, по сути получаем ту же контентную страницу.&lt;br /&gt;
&lt;br /&gt;
Правда, мы можем использовать методы и макросы модуля.&lt;br /&gt;
&lt;br /&gt;
== Шаблон для списка новостей ==&lt;br /&gt;
&lt;br /&gt;
Меняем код нашего фрагмента rubric.phtml как-то так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'lastlist', [$variables['id']]);&lt;br /&gt;
var_dump($newsList);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;ul class=&amp;quot;list-group&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/ul&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь мы использовали макрос lastlist модуля news, который вернул нам массив, одним из элементов которого является список новостей. Другие элементы содержат вспомогательные параметры для организации списка, в частности, количество новостей на странице (настраивается в админке в &amp;quot;Настройках модуля&amp;quot;). Можно потом использовать для организации постранички (ненавижу термин &amp;quot;пагинация&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Строчку var_dump($newsList); можем убрать. Получилось даже красиво. Жмем на ссылу - и получаем ошибку!&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-11-02 Неперехваченное исключение.png|без]]&lt;br /&gt;
&lt;br /&gt;
Что вполне понятно, ведь мы не создали шаблон для отображения конкретной новости.&lt;br /&gt;
&lt;br /&gt;
== Шаблон для текста новости ==&lt;br /&gt;
&lt;br /&gt;
Создадим в папке php в разделе news файл item.phtml, о котором и упоминалось в тексте ошибки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
         &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;em umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;publish_time&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_publish_time') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;publish_time ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;anons ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;anons ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;hr /&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И что же мы видим? В массиве $variables всё та же контентная страница, однако все поля, характерные для новости, в объекте присутствуют, хоть и не видны. Заметим, что дата получилась в формате umiDate, судя по всему, это внутреннее представление базы данных, для преобразования её в нужный формат можно воспользоваться [http://api.docs.umi-cms.ru/spravochnik_po_klassam_yadra_umicms/utilitarnye_klassy/umidate/ соответствующими методами]. Макрос 'lastlist' списка новостей ранее вернул дату в timestump. Вот так оно тут всё неожиданно...&lt;br /&gt;
&lt;br /&gt;
== Шаблон для 404 ==&lt;br /&gt;
&lt;br /&gt;
Теперь наберем в браузере адрес http://umi.example.com/abrakadabra - что получилось? Конечно, ошибка!&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Неперехваченное исключение.png|без]]&lt;br /&gt;
&lt;br /&gt;
Зато понятно, как её исправить - надо в php/content/ создать файл notfound.phtml, например, вот такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
         &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $variables['header'] ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массив $variables как всегда вывели для изучения, но там полезного не слишком много. Если посмотрим заголовки, то увидим, что статус 404 уже отправлен системой, дополнительно его отправлять не требуется.&lt;br /&gt;
&lt;br /&gt;
Вообще удобно сделать страницу 404 прямо на сайте, чтобы была возможность править контент в админке, а не в шаблоне. Для этого можно создать такую страницу, сделать её скрытой, в настройках сайта добавить поле типа &amp;quot;Ссылка на дерево&amp;quot;, указать в этом поле адрес страницы 404, а в этом шаблоне брать оттуда контент. Но оставлю это для [[404 страница|отдельного упражнения]].&lt;br /&gt;
&lt;br /&gt;
== Какие вообще нужны шаблоны? ==&lt;br /&gt;
&lt;br /&gt;
В первую очередь нужны шаблоны модулей, используемых на сайте. В зависимости от редакции набор модулей разный, но, как правило нужны:&lt;br /&gt;
&lt;br /&gt;
* content/&lt;br /&gt;
** content/content.phtml&lt;br /&gt;
** content/nofound.phtml&lt;br /&gt;
* news/&lt;br /&gt;
** news/rubric.phtml&lt;br /&gt;
** news/item.phtml&lt;br /&gt;
** news/subject.phtml - если использовать категории новостей&lt;br /&gt;
* users/ - довольно большой пакет шаблонов с формами регистрации и авторизации, которых мы пока не касались.&lt;br /&gt;
** users/registrate.phtml&lt;br /&gt;
** users/registrate_done.phtml&lt;br /&gt;
** users/activate.phtml&lt;br /&gt;
** users/login.phtml&lt;br /&gt;
** users/login_do.phtml&lt;br /&gt;
** users/logout.phtml&lt;br /&gt;
** users/forget.phtml&lt;br /&gt;
** users/forget_do.phtml&lt;br /&gt;
* search/ - если использовать поиск по сайту&lt;br /&gt;
** search/result.phtml&lt;br /&gt;
** search/search_do.phtml&lt;br /&gt;
&lt;br /&gt;
И, наконец, хотелось бы сделать отдельный шаблон для главной страницы сайта. Но это лучше [[Шаблон для главной страницы|выделить в отдельную тему]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BA_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=353</id>
		<title>Создание настроек сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BA_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=353"/>
		<updated>2020-11-05T15:21:39Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Edit-in-place для настроек */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Выбираем в админке раздел &amp;quot;Настройки сайта&amp;quot; и не видим никаких настроек:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-30 UMI CMS - Настройки.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Жмём &amp;quot;Создать настройки&amp;quot;, и создаём:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-30 UMI CMS - Создание.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Название может быть любое, идентификатор - только латиница. Если создаем настройки для русской версии сайта, на английской они видны не будут. Что в принципе логично.&lt;br /&gt;
&lt;br /&gt;
Теперь видим, что настройки появились:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Настройки (2).png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Вопрос только - что с ними делать? Ставим рядом галку, в пиктографическом меню нажимаем &amp;quot;Редактировать&amp;quot; - и видим ту же самую форму, что только что заполнили. Где логотип, где копирайт? Так мы незаметно подошли к большой теме - [[Шаблоны данных сайта|Создание шаблонов данных]].&lt;br /&gt;
&lt;br /&gt;
== Вывод настроек в шаблоне ==&lt;br /&gt;
&lt;br /&gt;
Добавим в настройки логотип и копирайт:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 UMI CMS - Редактирование.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь попробуем вывести всё это на страницах сайта.&lt;br /&gt;
&lt;br /&gt;
И тут мы сталкиваемся с очередной засадой UMI CMS. Казалось бы, каждому сайту должен соответствовать какой-то один набор настроек. Но в интерфейсе видим, что этих наборов можно создать сколько угодно. '''Господа разработчики''', может, стоило бы для упрощения ограничить эти возможности? Кто-то вообще использует больше одного набора настроек для конкретной языковой версии сайта? Было бы шикарно получать настройки прямо в массиве $variables, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Зато есть повод поупражняться с API системы. Один из способов получить настройки - использовать заданный нами идентификатор настроек, в данном случае 'demo':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$settings = $this-&amp;gt;getObjectById($this-&amp;gt;macros('umiSettings', 'getIdByName', 'demo']));&lt;br /&gt;
var_dump($settings);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь мы использовали метод getIdByName('...') модуля umiSettings для получения id настроек по названию (это именно название, не идентификатор), а потом получили сам объект настроек при помощи метода getObjectById().&lt;br /&gt;
&lt;br /&gt;
Добавим этот код в самое начало common.phtml. К счастью, в настройках разных языковых версий можно задавать один и тот же идентификатор, а то было бы совсем грустно. В общем, получилось. Если добавить на страницу &amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;, то увидим копирайт, который ввели.&lt;br /&gt;
&lt;br /&gt;
Теперь попробуем другой путь, ведь мы не фанаты делать кучу настроек:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$set = new selector('objects');&lt;br /&gt;
$set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
$set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
$set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
$set-&amp;gt;limit(0, 1);&lt;br /&gt;
$settings = $set-&amp;gt;result(); &lt;br /&gt;
var_dump($settings);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде был использован самый мощный класс ядра UMI - selector. Он подробно описан в документации. Чего в документации нет, так это - что подставлять в качестве 'object-type'. Но в админке есть где посмотреть: 'Шаблоны данных' - 'Настройки модуля' (ссылка справа вверху). Для начала лучше в этих настройках ничего не менять, но в качестве справочника - бесценно!&lt;br /&gt;
&lt;br /&gt;
Здесь мы ищем селектором те единственные настройки, что соответствуют конкретной языковой версии нашего сайта. Синтаксически это почти SQL-запрос, на мой взгляд, тут всё просто.&lt;br /&gt;
&lt;br /&gt;
UMI CMS в конце каждой страницы выдает время её формирования, что очень удобно. Легко убедиться, что второй способ на 0.001 секунды быстрее, помимо прочих его преимуществ. Конечно, неплохо бы проверить, что хоть какие-то настройки нашлись. Кроме этого, хотелось бы получить настройки в самом начале, а использовать их в произвольных фрагментах нашего шаблона. В результате модифицируем код common.phtml как-то так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$set = new selector('objects');&lt;br /&gt;
$set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
$set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
$set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
$set-&amp;gt;limit(0, 1);&lt;br /&gt;
$variables['settings'] = array_shift($set-&amp;gt;result()); &lt;br /&gt;
if (empty($variables['settings'])) {&lt;br /&gt;
    echo $this-&amp;gt;translate('no settings');&lt;br /&gt;
    exit();&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Копирайт мы собирались использовать в подвале сайта, поэтому пишем в footer.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?= $variables['settings']-&amp;gt;copyright ?&amp;gt;&amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверяем результат - всё получилось! Теперь надо разобраться с логотипом. Добавляем &amp;lt;?php var_dump($variables['settings']-&amp;gt;logo); ?&amp;gt; в файл header.phtml, и видим, что это объект. Причем - ещё одна засада UMI CMS - все свойства без исключения protected!!! Зато в нем есть все, что нам нужно. Итак, изучаем документацию по классам umiFile и umiImageFile, и новый header.phtml будет выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
$logo = $variables['settings']-&amp;gt;logo;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($logo): ?&amp;gt;&lt;br /&gt;
                &amp;lt;img src=&amp;quot;/&amp;lt;?= $logo-&amp;gt;getFilePath() ?&amp;gt;&amp;quot; title=&amp;quot;&amp;lt;?= $logo-&amp;gt;getTitle() ?&amp;gt;&amp;quot; alt=&amp;quot;&amp;lt;?= $logo-&amp;gt;getAlt() ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php endif; ?&amp;gt;&lt;br /&gt;
            &amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Почему перед адресом изображения стоит '/'? Потому что getFilePath() зачем-то перед адресом ставит точку, хоть адрес возвращает абсолютный. Загадка. В качестве alt и title пробуем получить значения, которые должны были задать в админке при заливке файла. Но поскольку ничего не задали, они будут пустые. А вообще, по-хорошему, надо добавить в настройки еще одно поле - название компании, и выводить именно его.&lt;br /&gt;
&lt;br /&gt;
== Edit-in-place для настроек ==&lt;br /&gt;
&lt;br /&gt;
Теперь осталось добавить возможность изменять эти поля прямо на сайте. В принципе, ничего сложного:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;img umi:object-id=&amp;quot;&amp;lt;?= $logo-&amp;gt;getId() ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;logo&amp;quot; src=&amp;quot;/&amp;lt;?= $logo-&amp;gt;getFilePath() ?&amp;gt;&amp;quot; title=&amp;quot;&amp;lt;?= $logo-&amp;gt;getTitle() ?&amp;gt;&amp;quot; alt=&amp;quot;&amp;lt;?= $logo-&amp;gt;getAlt() ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это для логотипа, а для копирайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $logo-&amp;gt;getId() ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;logo&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_copyright') ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?= $variables['settings']-&amp;gt;copyright ?&amp;gt;&lt;br /&gt;
    &amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что псевдо-атрибуты для id контентных страниц и объектов отличаются, если для полей страниц мы использовали атрибут umi:element-id, то для полей объектов приходится писать umi:object-id. Это отражение внутреннего деления UMI CMS на страницы контента и объекты, за работу с которыми отвечают разные методы.&lt;br /&gt;
&lt;br /&gt;
Также пришлось добавить дополнительный &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt;, чтобы копирайт был в отдельном контейнере.&lt;br /&gt;
&lt;br /&gt;
== Другие модули системы ==&lt;br /&gt;
&lt;br /&gt;
Пока нам для сайта хватало модуля content, немного использовали umiSettings. Однако полезных модулей гораздо больше, и пора наконец [[Другие модули системы|добавить на сайт раздел Новости]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BA_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=352</id>
		<title>Создание настроек сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BA_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=352"/>
		<updated>2020-11-05T15:21:12Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Выбираем в админке раздел &amp;quot;Настройки сайта&amp;quot; и не видим никаких настроек:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-30 UMI CMS - Настройки.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Жмём &amp;quot;Создать настройки&amp;quot;, и создаём:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-30 UMI CMS - Создание.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Название может быть любое, идентификатор - только латиница. Если создаем настройки для русской версии сайта, на английской они видны не будут. Что в принципе логично.&lt;br /&gt;
&lt;br /&gt;
Теперь видим, что настройки появились:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Настройки (2).png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Вопрос только - что с ними делать? Ставим рядом галку, в пиктографическом меню нажимаем &amp;quot;Редактировать&amp;quot; - и видим ту же самую форму, что только что заполнили. Где логотип, где копирайт? Так мы незаметно подошли к большой теме - [[Шаблоны данных сайта|Создание шаблонов данных]].&lt;br /&gt;
&lt;br /&gt;
== Вывод настроек в шаблоне ==&lt;br /&gt;
&lt;br /&gt;
Добавим в настройки логотип и копирайт:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 UMI CMS - Редактирование.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь попробуем вывести всё это на страницах сайта.&lt;br /&gt;
&lt;br /&gt;
И тут мы сталкиваемся с очередной засадой UMI CMS. Казалось бы, каждому сайту должен соответствовать какой-то один набор настроек. Но в интерфейсе видим, что этих наборов можно создать сколько угодно. '''Господа разработчики''', может, стоило бы для упрощения ограничить эти возможности? Кто-то вообще использует больше одного набора настроек для конкретной языковой версии сайта? Было бы шикарно получать настройки прямо в массиве $variables, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Зато есть повод поупражняться с API системы. Один из способов получить настройки - использовать заданный нами идентификатор настроек, в данном случае 'demo':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$settings = $this-&amp;gt;getObjectById($this-&amp;gt;macros('umiSettings', 'getIdByName', 'demo']));&lt;br /&gt;
var_dump($settings);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь мы использовали метод getIdByName('...') модуля umiSettings для получения id настроек по названию (это именно название, не идентификатор), а потом получили сам объект настроек при помощи метода getObjectById().&lt;br /&gt;
&lt;br /&gt;
Добавим этот код в самое начало common.phtml. К счастью, в настройках разных языковых версий можно задавать один и тот же идентификатор, а то было бы совсем грустно. В общем, получилось. Если добавить на страницу &amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;, то увидим копирайт, который ввели.&lt;br /&gt;
&lt;br /&gt;
Теперь попробуем другой путь, ведь мы не фанаты делать кучу настроек:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$set = new selector('objects');&lt;br /&gt;
$set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
$set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
$set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
$set-&amp;gt;limit(0, 1);&lt;br /&gt;
$settings = $set-&amp;gt;result(); &lt;br /&gt;
var_dump($settings);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде был использован самый мощный класс ядра UMI - selector. Он подробно описан в документации. Чего в документации нет, так это - что подставлять в качестве 'object-type'. Но в админке есть где посмотреть: 'Шаблоны данных' - 'Настройки модуля' (ссылка справа вверху). Для начала лучше в этих настройках ничего не менять, но в качестве справочника - бесценно!&lt;br /&gt;
&lt;br /&gt;
Здесь мы ищем селектором те единственные настройки, что соответствуют конкретной языковой версии нашего сайта. Синтаксически это почти SQL-запрос, на мой взгляд, тут всё просто.&lt;br /&gt;
&lt;br /&gt;
UMI CMS в конце каждой страницы выдает время её формирования, что очень удобно. Легко убедиться, что второй способ на 0.001 секунды быстрее, помимо прочих его преимуществ. Конечно, неплохо бы проверить, что хоть какие-то настройки нашлись. Кроме этого, хотелось бы получить настройки в самом начале, а использовать их в произвольных фрагментах нашего шаблона. В результате модифицируем код common.phtml как-то так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$set = new selector('objects');&lt;br /&gt;
$set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
$set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
$set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
$set-&amp;gt;limit(0, 1);&lt;br /&gt;
$variables['settings'] = array_shift($set-&amp;gt;result()); &lt;br /&gt;
if (empty($variables['settings'])) {&lt;br /&gt;
    echo $this-&amp;gt;translate('no settings');&lt;br /&gt;
    exit();&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Копирайт мы собирались использовать в подвале сайта, поэтому пишем в footer.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?= $variables['settings']-&amp;gt;copyright ?&amp;gt;&amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверяем результат - всё получилось! Теперь надо разобраться с логотипом. Добавляем &amp;lt;?php var_dump($variables['settings']-&amp;gt;logo); ?&amp;gt; в файл header.phtml, и видим, что это объект. Причем - ещё одна засада UMI CMS - все свойства без исключения protected!!! Зато в нем есть все, что нам нужно. Итак, изучаем документацию по классам umiFile и umiImageFile, и новый header.phtml будет выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
$logo = $variables['settings']-&amp;gt;logo;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($logo): ?&amp;gt;&lt;br /&gt;
                &amp;lt;img src=&amp;quot;/&amp;lt;?= $logo-&amp;gt;getFilePath() ?&amp;gt;&amp;quot; title=&amp;quot;&amp;lt;?= $logo-&amp;gt;getTitle() ?&amp;gt;&amp;quot; alt=&amp;quot;&amp;lt;?= $logo-&amp;gt;getAlt() ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php endif; ?&amp;gt;&lt;br /&gt;
            &amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Почему перед адресом изображения стоит '/'? Потому что getFilePath() зачем-то перед адресом ставит точку, хоть адрес возвращает абсолютный. Загадка. В качестве alt и title пробуем получить значения, которые должны были задать в админке при заливке файла. Но поскольку ничего не задали, они будут пустые. А вообще, по-хорошему, надо добавить в настройки еще одно поле - название компании, и выводить именно его.&lt;br /&gt;
&lt;br /&gt;
== Edit-in-place для настроек ==&lt;br /&gt;
&lt;br /&gt;
Теперь осталось добавить возможность изменять эти поля прямо на сайте. В принципе, ничего сложного:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;img umi:object-id=&amp;quot;&amp;lt;?= $logo-&amp;gt;getId() ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;logo&amp;quot; src=&amp;quot;/&amp;lt;?= $logo-&amp;gt;getFilePath() ?&amp;gt;&amp;quot; title=&amp;quot;&amp;lt;?= $logo-&amp;gt;getTitle() ?&amp;gt;&amp;quot; alt=&amp;quot;&amp;lt;?= $logo-&amp;gt;getAlt() ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это для логотипа, а для копирайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $logo-&amp;gt;getId() ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;logo&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_copyright') ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?= $variables['settings']-&amp;gt;copyright ?&amp;gt;&lt;br /&gt;
    &amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что псевдо-атрибуты для id контентных страниц и объектов отличаются, если для полей страниц мы использовали атрибут umi:element-id, то для полей объектов приходится писать umi:object-id. Это отражение внутреннего деления UMI CMS на страницы контента и объекты, за работу с которыми отвечают разные методы.&lt;br /&gt;
&lt;br /&gt;
Также пришлось добавить дополнительный &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt;, чтобы копирайт был в отдельном контейнере.&lt;br /&gt;
&lt;br /&gt;
== Другие модули системы ==&lt;br /&gt;
&lt;br /&gt;
Пока нам для сайта хватало модуля content, немного использовали umiSettings. Однако полезных модулей гораздо больше, и пора наконец [[Другие модули системы|добавить на сайт раздел Новости]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8_Edit-in-place&amp;diff=351</id>
		<title>Добавление возможности Edit-in-place</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8_Edit-in-place&amp;diff=351"/>
		<updated>2020-11-05T15:20:17Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Модифицируем немного файл head.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;&amp;lt;?= $this-&amp;gt;getResourceDirectory() ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;?= $this-&amp;gt;getCanonicalLinkTag($variables) ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;macros('content', 'includeFrontendResources') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Во-первых, использовали метод getResourceDirectory() для получения base директории. Лучше, чем использовать статику.&lt;br /&gt;
&lt;br /&gt;
Во-вторых, добавили &amp;lt;link rel=&amp;quot;canonical&amp;quot; ...&amp;gt; при помощи метода getCanonicalLinkTag() - нам ничего не стоит, а для SEO полезно.&lt;br /&gt;
&lt;br /&gt;
И, наконец, использовали макрос includeFrontendResources, который и отвечает за возможность Edit-in-place.&lt;br /&gt;
&lt;br /&gt;
Если сейчас посмотреть код страницы нашего сайта http://umi.example.com/, то увидим, что макрос добавил в заголовок следующие строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
	window.pageData = {&amp;quot;pageId&amp;quot;:1,&amp;quot;objectId&amp;quot;:583,&amp;quot;page&amp;quot;:{&amp;quot;alt-name&amp;quot;:&amp;quot;main&amp;quot;,&amp;quot;is_default&amp;quot;:true},&amp;quot;title&amp;quot;:&amp;quot;\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0430\u0439\u0442 - \u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0430\u0439\u0442&amp;quot;,&amp;quot;lang&amp;quot;:&amp;quot;ru&amp;quot;,&amp;quot;lang_id&amp;quot;:1,&amp;quot;domain&amp;quot;:&amp;quot;umi.example.com&amp;quot;,&amp;quot;domain_id&amp;quot;:1,&amp;quot;meta&amp;quot;:{&amp;quot;keywords&amp;quot;:&amp;quot;DEMO \u0441\u0430\u0439\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435&amp;quot;,&amp;quot;description&amp;quot;:&amp;quot;&amp;quot;}};&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script src=&amp;quot;/styles/common/js/cms/jquery.compiled.min.js?91415&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;/styles/common/js/guest.js?91415&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link type=&amp;quot;text/css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;/styles/common/js/jquery/fancybox/jquery.fancybox.css?91415&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В частности, подключена библиотека jQuery. Это значит, что из файла common.phtml мы должны эту библиотеку убрать. Если не уберем, то может произойти конфликт версий, и работать не будет.&lt;br /&gt;
&lt;br /&gt;
Итак, скрипты подключены, но пока ничего не происходит. Для редактирования нужно сначала авторизоваться. У нас на сайте пока нет такой возможности, поэтому заходим в админку и авторизуемся. Зайдя на сайт, видим красивую чёрную менюшку вверху, и, нажав &amp;quot;Редактировать&amp;quot; - не видим никаких изменений на странице. Почему? Потому что перед этим не отметили в HTML шаблона нужные поля для редактирования.&lt;br /&gt;
&lt;br /&gt;
== Разметка полей для редактирования ==&lt;br /&gt;
&lt;br /&gt;
В файл main.phtml вносим некоторые изменения:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В теги, содержащие заголовок и контент, добавили атрибуты:&lt;br /&gt;
&lt;br /&gt;
* umi:element-id - id страницы&lt;br /&gt;
* umi:field-name - название поляя&lt;br /&gt;
* umi:empty - placeholder для незаполненного поля, использовали [[Языковые константы|языковую константу]]&lt;br /&gt;
&lt;br /&gt;
Тэг &amp;lt;nowiki&amp;gt;&amp;lt;p&amp;gt;&amp;lt;/nowiki&amp;gt; заменили на &amp;lt;nowiki&amp;gt;&amp;lt;div&amp;gt;&amp;lt;/nowiki&amp;gt; - зачем? Просто потому, что поле content - это текст с визуальным редактором, который своих &amp;lt;nowiki&amp;gt;&amp;lt;p&amp;gt;&amp;lt;/nowiki&amp;gt; понаставит, а вложенные &amp;lt;nowiki&amp;gt;&amp;lt;p&amp;gt;&amp;lt;/nowiki&amp;gt; правилами HTML не приветствуются.&lt;br /&gt;
&lt;br /&gt;
Обновляем страницу, жмём редактирование, и видим, что поля выделились цветом. Щелкнув на любое, можем вносить изменения, вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-30 Демонстрационный сайт - Демонстрационный сайт.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
== Что дальше? ==&lt;br /&gt;
&lt;br /&gt;
Как мне кажется, на сайте отсутствует самое главное - это логотип и контакты. Самое время перейти к [[Создание настроек сайта|созданию настроек сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8_Edit-in-place&amp;diff=350</id>
		<title>Добавление возможности Edit-in-place</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8_Edit-in-place&amp;diff=350"/>
		<updated>2020-11-05T15:19:41Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Модифицируем немного файл head.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;&amp;lt;?= $this-&amp;gt;getResourceDirectory() ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;?= $this-&amp;gt;getCanonicalLinkTag($variables) ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;macros('content', 'includeFrontendResources') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Во-первых, использовали метод getResourceDirectory() для получения base директории. Лучше, чем использовать статику.&lt;br /&gt;
&lt;br /&gt;
Во-вторых, добавили &amp;lt;link rel=&amp;quot;canonical&amp;quot; ...&amp;gt; при помощи метода getCanonicalLinkTag() - нам ничего не стоит, а для SEO полезно.&lt;br /&gt;
&lt;br /&gt;
И, наконец, использовали макрос includeFrontendResources, который и отвечает за возможность Edit-in-place.&lt;br /&gt;
&lt;br /&gt;
Если сейчас посмотреть код страницы нашего сайта http://umi.example.com/, то увидим, что макрос добавил в заголовок следующие строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
	window.pageData = {&amp;quot;pageId&amp;quot;:1,&amp;quot;objectId&amp;quot;:583,&amp;quot;page&amp;quot;:{&amp;quot;alt-name&amp;quot;:&amp;quot;main&amp;quot;,&amp;quot;is_default&amp;quot;:true},&amp;quot;title&amp;quot;:&amp;quot;\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0430\u0439\u0442 - \u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0430\u0439\u0442&amp;quot;,&amp;quot;lang&amp;quot;:&amp;quot;ru&amp;quot;,&amp;quot;lang_id&amp;quot;:1,&amp;quot;domain&amp;quot;:&amp;quot;umi.example.com&amp;quot;,&amp;quot;domain_id&amp;quot;:1,&amp;quot;meta&amp;quot;:{&amp;quot;keywords&amp;quot;:&amp;quot;DEMO \u0441\u0430\u0439\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435&amp;quot;,&amp;quot;description&amp;quot;:&amp;quot;&amp;quot;}};&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script src=&amp;quot;/styles/common/js/cms/jquery.compiled.min.js?91415&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;/styles/common/js/guest.js?91415&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link type=&amp;quot;text/css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;/styles/common/js/jquery/fancybox/jquery.fancybox.css?91415&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В частности, подключена библиотека jQuery. Это значит, что из файла common.phtml мы должны эту библиотеку убрать. Если не уберем, то может произойти конфликт версий, и работать не будет.&lt;br /&gt;
&lt;br /&gt;
Итак, скрипты подключены, но пока ничего не происходит. Для редактирования нужно сначала авторизоваться. У нас на сайте пока нет такой возможности, поэтому заходим в админку и авторизуемся. Зайдя на сайт, видим красивую чёрную менюшку вверху, и, нажав &amp;quot;Редактировать&amp;quot; - не видим никаких изменений на странице. Почему? Потому что перед этим не отметили в HTML шаблона нужные поля для редактирования.&lt;br /&gt;
&lt;br /&gt;
== Разметка полей для редактирования ==&lt;br /&gt;
&lt;br /&gt;
В файл main.phtml вносим некоторые изменения:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1 umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;h1&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $page-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;content&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_content') ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В теги, содержащие заголовок и контент, добавили атрибуты:&lt;br /&gt;
&lt;br /&gt;
* umi:element-id - id страницы&lt;br /&gt;
* umi:field-name - название поляя&lt;br /&gt;
* umi:empty - placeholder для незаполненного поля, использовали [[Языковые константы|языковую константу]]&lt;br /&gt;
&lt;br /&gt;
Тэг &amp;lt;nowiki&amp;gt;&amp;lt;p&amp;gt;&amp;lt;/nowiki&amp;gt; заменили на &amp;lt;nowiki&amp;gt;&amp;lt;div&amp;gt;&amp;lt;/nowiki&amp;gt; - зачем? Просто потому, что поле content - это текст с визуальным редактором, который своих &amp;lt;nowiki&amp;gt;&amp;lt;p&amp;gt;&amp;lt;/nowiki&amp;gt; понаставит, а вложенные &amp;lt;nowiki&amp;gt;&amp;lt;p&amp;gt;&amp;lt;/nowiki&amp;gt; правилами HTML не приветствуются.&lt;br /&gt;
&lt;br /&gt;
Обновляем страницу, жмём редактирование, и видим, что поля выделились цветом. Щелкнув на любое, можем вносить изменения, вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-30 Демонстрационный сайт - Демонстрационный сайт.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
== Что дальше? ==&lt;br /&gt;
&lt;br /&gt;
Как мне кажется, на сайте отсутствует самое главное - это логотип и контакты. Самое время перейти к [[Создание настроек сайта|созданию настроек сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=349</id>
		<title>Создание &quot;правильного&quot; шаблона для сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=349"/>
		<updated>2020-11-05T15:16:22Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Делим шаблон на части */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для компактности HTML кода буду использовать библиотеку Bootstrap4 - пользуйтесь своими любимыми фреймворками, если не нравится. Итак, сделаем код нашего шаблона несколько более полным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $page-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;description ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;keywords ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В &amp;lt;head&amp;gt; добавили тэг &amp;lt;base ...&amp;gt;, потому что в дальнейшем все, что касается конкретного сайта, планируем хранить в папке конкретного шаблона, в нашем случае default. UMI CMS считает папку шаблона корневой директорией сайта, но это не распространяется на стили, скрипты и картинки.&lt;br /&gt;
&lt;br /&gt;
Теперь главная страница сайта приобрела более &amp;quot;причёсанный&amp;quot; вид:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Главная.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заметим, что Title у страницы пустой, что не слишком хорошо. Можно прописывать это поле для каждой страницы. Но есть способ получше.&lt;br /&gt;
&lt;br /&gt;
== Настраиваем Title и другие SEO-параметры ==&lt;br /&gt;
&lt;br /&gt;
В шаблоне меняем строки заголовка, описания и ключевых слов на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $this-&amp;gt;escape($variables['title']) ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и видим теперь заголовок &amp;lt;title&amp;gt;UMI.CMS - Страница 1&amp;lt;/title&amp;gt;. Нам &amp;quot;UMI.CMS - &amp;quot; ни разу не нужно. Чтобы настроить параметры по умолчанию, в модулях (под бабочкой) находим раздел SEO, в нем справа вверху видим ссылку &amp;quot;Настройка модуля&amp;quot;, жмём и настраиваем, там всё просто. Заменяю &amp;quot;UMI.CMS - &amp;quot; на &amp;quot;Демонстрационный сайт - &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чем отличается от прежнего варианта шаблона? Тем, что мы не выводим тупо поле из данных конкретной страницы, а позволяем CMS сформировать для нас эти параметры, используя настройки по умолчанию.&lt;br /&gt;
&lt;br /&gt;
== Делим шаблон на части ==&lt;br /&gt;
&lt;br /&gt;
Чтобы не мучиться с длинной простынёй кода, существует хорошая практика делить его на разумные фрагменты. Скажем, сразу хочется выделить &amp;lt;head&amp;gt;, &amp;lt;header&amp;gt; и &amp;lt;footer&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В директории /templates/default/php/ создаём поддиректорию layout, а в ней файлы наших фрагментов:&lt;br /&gt;
&lt;br /&gt;
* head.phtml&lt;br /&gt;
* header.phtml&lt;br /&gt;
* main.phtml&lt;br /&gt;
* footer.phtml&lt;br /&gt;
&lt;br /&gt;
Помещаем в эти файлы фрагменты кода шаблонов, например, head.phtml будет выглядеть вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А main.phtml вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь в шаблоне можно просто подключить эти фрагменты:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в качестве первого параметра при вызове метода render() мы передаем массив $variables конкретной страницы. Второй параметр - это адрес шаблона относительно папки php и без расшмрения &amp;quot;.phtml&amp;quot;. Поэтому делать у файлов шаблона именно такое расширение - '''обязательно'''! Иначе не найдет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем меню ==&lt;br /&gt;
&lt;br /&gt;
Выше мы использовали волшебную переменную $this, но для вызова только одного метода - render(). А какие еще методы нам доступны?&lt;br /&gt;
&lt;br /&gt;
Полный список был бы весьма желателен. Но если кратко - все публичные методы модуля '''content''', их описание и код можно посмотреть в /classes/components/content/class.php и /classes/components/content/macros.php, а также системные и сервисные методы, наследуемые этими классами. Методы класса можно использовать непосредственно, макросы - при помощи метода macros().&lt;br /&gt;
&lt;br /&gt;
Нам для сайта надо получить &amp;quot;дерево&amp;quot; меню. Для этого в файл header.phtml добавляем код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
var_dump($menuTree);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый параметр метода macros() - название модуля, второй - название метода, третий - параметры, передаваемые методу. Список параметров можно посмотреть в коде метода, все макросы хорошо документированы комментариями. В данном случае используем:&lt;br /&gt;
&lt;br /&gt;
* шаблон не задан (шаблон задается в других шаблонизаторах, в PHP не работает)&lt;br /&gt;
* 2 уровня вложенности (у нас пока один, но можем потом добавить)&lt;br /&gt;
* начиная от корня сайта (можно указать id страницы, и тогда &amp;quot;дерево&amp;quot; будет построено от неё)&lt;br /&gt;
* выдавать признак, что есть дочерние страницы&lt;br /&gt;
* id текущей страницы передаем, чтобы в результате этот пункт был выделен как активный.&lt;br /&gt;
&lt;br /&gt;
Чтобы изучить возможность добавления второго уровня, добавим вложенную страницу внутрь нашей &amp;quot;Страницы 1&amp;quot;. Для этого с разделе &amp;quot;Структура&amp;quot; сайта ставим галочку рядом со &amp;quot;Страница 1&amp;quot; и нажимаем плюс в меню. Назовем ее &amp;quot;Страница 3&amp;quot; и page3 в качестве псевдостатического адреса. Обновляем страницу в браузере - в массиве $menuTree ничего не поменялось!!!&lt;br /&gt;
&lt;br /&gt;
Это очередная засада UMI CMS. Чтобы используемый нами макрос выдавал вложенные страницы, надо в данном случае на &amp;quot;Странице 1&amp;quot; в '''Дополнительных параметрах''' поставить признаки &amp;quot;Меню всегда развернуто&amp;quot; и &amp;quot;Показывать подменю&amp;quot;. Понятно, что это вопрос умолчаний, но в современных сайтах чаще используется развернутое меню, управляемое JS, а не как раньше - статическое индивидуальное меню для каждой страницы.&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', может, пора уже облегчить жизнь редакторам сайтов, и изменить настройки? Пусть у всех страниц эти признаки будут по умолчанию включены, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Полюбовавшись структурой полученного массива, можем теперь вывести нормальное меню сайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Логотип&amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['void:lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['nodes:item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом виде сайт уже почти настоящий. На страницах выводится то, что перед этим мы закинули через админку. Но хотелось бы иметь возможность вносить правки прямо на сайте. UMI CMS дает такую возможность, её надо просто [[Добавление возможности Edit-in-place|внести в наш шаблон]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=348</id>
		<title>Создание &quot;правильного&quot; шаблона для сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=348"/>
		<updated>2020-11-05T15:16:00Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Делим шаблон на части */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для компактности HTML кода буду использовать библиотеку Bootstrap4 - пользуйтесь своими любимыми фреймворками, если не нравится. Итак, сделаем код нашего шаблона несколько более полным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $page-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;description ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;keywords ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В &amp;lt;head&amp;gt; добавили тэг &amp;lt;base ...&amp;gt;, потому что в дальнейшем все, что касается конкретного сайта, планируем хранить в папке конкретного шаблона, в нашем случае default. UMI CMS считает папку шаблона корневой директорией сайта, но это не распространяется на стили, скрипты и картинки.&lt;br /&gt;
&lt;br /&gt;
Теперь главная страница сайта приобрела более &amp;quot;причёсанный&amp;quot; вид:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Главная.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заметим, что Title у страницы пустой, что не слишком хорошо. Можно прописывать это поле для каждой страницы. Но есть способ получше.&lt;br /&gt;
&lt;br /&gt;
== Настраиваем Title и другие SEO-параметры ==&lt;br /&gt;
&lt;br /&gt;
В шаблоне меняем строки заголовка, описания и ключевых слов на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $this-&amp;gt;escape($variables['title']) ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и видим теперь заголовок &amp;lt;title&amp;gt;UMI.CMS - Страница 1&amp;lt;/title&amp;gt;. Нам &amp;quot;UMI.CMS - &amp;quot; ни разу не нужно. Чтобы настроить параметры по умолчанию, в модулях (под бабочкой) находим раздел SEO, в нем справа вверху видим ссылку &amp;quot;Настройка модуля&amp;quot;, жмём и настраиваем, там всё просто. Заменяю &amp;quot;UMI.CMS - &amp;quot; на &amp;quot;Демонстрационный сайт - &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чем отличается от прежнего варианта шаблона? Тем, что мы не выводим тупо поле из данных конкретной страницы, а позволяем CMS сформировать для нас эти параметры, используя настройки по умолчанию.&lt;br /&gt;
&lt;br /&gt;
== Делим шаблон на части ==&lt;br /&gt;
&lt;br /&gt;
Чтобы не мучиться с длинной простынёй кода, существует хорошая практика делить его на разумные фрагменты. Скажем, сразу хочется выделить &amp;lt;head&amp;gt;, &amp;lt;header&amp;gt; и &amp;lt;footer&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В директории /templates/default/php/ создаём поддиректорию layout, а в ней файлы наших фрагментов:&lt;br /&gt;
&lt;br /&gt;
* head.phtml&lt;br /&gt;
* header.phtml&lt;br /&gt;
* main.phtml&lt;br /&gt;
* footer.phtml&lt;br /&gt;
&lt;br /&gt;
Помещаем в эти файлы фрагменты кода шаблонов, например, head.phtml будет выглядеть вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;phtml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А main.phtml вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь в шаблоне можно просто подключить эти фрагменты:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в качестве первого параметра при вызове метода render() мы передаем массив $variables конкретной страницы. Второй параметр - это адрес шаблона относительно папки php и без расшмрения &amp;quot;.phtml&amp;quot;. Поэтому делать у файлов шаблона именно такое расширение - '''обязательно'''! Иначе не найдет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем меню ==&lt;br /&gt;
&lt;br /&gt;
Выше мы использовали волшебную переменную $this, но для вызова только одного метода - render(). А какие еще методы нам доступны?&lt;br /&gt;
&lt;br /&gt;
Полный список был бы весьма желателен. Но если кратко - все публичные методы модуля '''content''', их описание и код можно посмотреть в /classes/components/content/class.php и /classes/components/content/macros.php, а также системные и сервисные методы, наследуемые этими классами. Методы класса можно использовать непосредственно, макросы - при помощи метода macros().&lt;br /&gt;
&lt;br /&gt;
Нам для сайта надо получить &amp;quot;дерево&amp;quot; меню. Для этого в файл header.phtml добавляем код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
var_dump($menuTree);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый параметр метода macros() - название модуля, второй - название метода, третий - параметры, передаваемые методу. Список параметров можно посмотреть в коде метода, все макросы хорошо документированы комментариями. В данном случае используем:&lt;br /&gt;
&lt;br /&gt;
* шаблон не задан (шаблон задается в других шаблонизаторах, в PHP не работает)&lt;br /&gt;
* 2 уровня вложенности (у нас пока один, но можем потом добавить)&lt;br /&gt;
* начиная от корня сайта (можно указать id страницы, и тогда &amp;quot;дерево&amp;quot; будет построено от неё)&lt;br /&gt;
* выдавать признак, что есть дочерние страницы&lt;br /&gt;
* id текущей страницы передаем, чтобы в результате этот пункт был выделен как активный.&lt;br /&gt;
&lt;br /&gt;
Чтобы изучить возможность добавления второго уровня, добавим вложенную страницу внутрь нашей &amp;quot;Страницы 1&amp;quot;. Для этого с разделе &amp;quot;Структура&amp;quot; сайта ставим галочку рядом со &amp;quot;Страница 1&amp;quot; и нажимаем плюс в меню. Назовем ее &amp;quot;Страница 3&amp;quot; и page3 в качестве псевдостатического адреса. Обновляем страницу в браузере - в массиве $menuTree ничего не поменялось!!!&lt;br /&gt;
&lt;br /&gt;
Это очередная засада UMI CMS. Чтобы используемый нами макрос выдавал вложенные страницы, надо в данном случае на &amp;quot;Странице 1&amp;quot; в '''Дополнительных параметрах''' поставить признаки &amp;quot;Меню всегда развернуто&amp;quot; и &amp;quot;Показывать подменю&amp;quot;. Понятно, что это вопрос умолчаний, но в современных сайтах чаще используется развернутое меню, управляемое JS, а не как раньше - статическое индивидуальное меню для каждой страницы.&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', может, пора уже облегчить жизнь редакторам сайтов, и изменить настройки? Пусть у всех страниц эти признаки будут по умолчанию включены, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Полюбовавшись структурой полученного массива, можем теперь вывести нормальное меню сайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Логотип&amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['void:lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['nodes:item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом виде сайт уже почти настоящий. На страницах выводится то, что перед этим мы закинули через админку. Но хотелось бы иметь возможность вносить правки прямо на сайте. UMI CMS дает такую возможность, её надо просто [[Добавление возможности Edit-in-place|внести в наш шаблон]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=347</id>
		<title>Создание &quot;правильного&quot; шаблона для сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=347"/>
		<updated>2020-11-05T15:15:28Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для компактности HTML кода буду использовать библиотеку Bootstrap4 - пользуйтесь своими любимыми фреймворками, если не нравится. Итак, сделаем код нашего шаблона несколько более полным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $page-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;description ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;keywords ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В &amp;lt;head&amp;gt; добавили тэг &amp;lt;base ...&amp;gt;, потому что в дальнейшем все, что касается конкретного сайта, планируем хранить в папке конкретного шаблона, в нашем случае default. UMI CMS считает папку шаблона корневой директорией сайта, но это не распространяется на стили, скрипты и картинки.&lt;br /&gt;
&lt;br /&gt;
Теперь главная страница сайта приобрела более &amp;quot;причёсанный&amp;quot; вид:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Главная.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заметим, что Title у страницы пустой, что не слишком хорошо. Можно прописывать это поле для каждой страницы. Но есть способ получше.&lt;br /&gt;
&lt;br /&gt;
== Настраиваем Title и другие SEO-параметры ==&lt;br /&gt;
&lt;br /&gt;
В шаблоне меняем строки заголовка, описания и ключевых слов на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $this-&amp;gt;escape($variables['title']) ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и видим теперь заголовок &amp;lt;title&amp;gt;UMI.CMS - Страница 1&amp;lt;/title&amp;gt;. Нам &amp;quot;UMI.CMS - &amp;quot; ни разу не нужно. Чтобы настроить параметры по умолчанию, в модулях (под бабочкой) находим раздел SEO, в нем справа вверху видим ссылку &amp;quot;Настройка модуля&amp;quot;, жмём и настраиваем, там всё просто. Заменяю &amp;quot;UMI.CMS - &amp;quot; на &amp;quot;Демонстрационный сайт - &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чем отличается от прежнего варианта шаблона? Тем, что мы не выводим тупо поле из данных конкретной страницы, а позволяем CMS сформировать для нас эти параметры, используя настройки по умолчанию.&lt;br /&gt;
&lt;br /&gt;
== Делим шаблон на части ==&lt;br /&gt;
&lt;br /&gt;
Чтобы не мучиться с длинной простынёй кода, существует хорошая практика делить его на разумные фрагменты. Скажем, сразу хочется выделить &amp;lt;head&amp;gt;, &amp;lt;header&amp;gt; и &amp;lt;footer&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В директории /templates/default/php/ создаём поддиректорию layout, а в ней файлы наших фрагментов:&lt;br /&gt;
&lt;br /&gt;
* head.phtml&lt;br /&gt;
* header.phtml&lt;br /&gt;
* main.phtml&lt;br /&gt;
* footer.phtml&lt;br /&gt;
&lt;br /&gt;
Помещаем в эти файлы фрагменты кода шаблонов, например, head.phtml будет выглядеть вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А main.phtml вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь в шаблоне можно просто подключить эти фрагменты:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в качестве первого параметра при вызове метода render() мы передаем массив $variables конкретной страницы. Второй параметр - это адрес шаблона относительно папки php и без расшмрения &amp;quot;.phtml&amp;quot;. Поэтому делать у файлов шаблона именно такое расширение - '''обязательно'''! Иначе не найдет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем меню ==&lt;br /&gt;
&lt;br /&gt;
Выше мы использовали волшебную переменную $this, но для вызова только одного метода - render(). А какие еще методы нам доступны?&lt;br /&gt;
&lt;br /&gt;
Полный список был бы весьма желателен. Но если кратко - все публичные методы модуля '''content''', их описание и код можно посмотреть в /classes/components/content/class.php и /classes/components/content/macros.php, а также системные и сервисные методы, наследуемые этими классами. Методы класса можно использовать непосредственно, макросы - при помощи метода macros().&lt;br /&gt;
&lt;br /&gt;
Нам для сайта надо получить &amp;quot;дерево&amp;quot; меню. Для этого в файл header.phtml добавляем код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
var_dump($menuTree);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый параметр метода macros() - название модуля, второй - название метода, третий - параметры, передаваемые методу. Список параметров можно посмотреть в коде метода, все макросы хорошо документированы комментариями. В данном случае используем:&lt;br /&gt;
&lt;br /&gt;
* шаблон не задан (шаблон задается в других шаблонизаторах, в PHP не работает)&lt;br /&gt;
* 2 уровня вложенности (у нас пока один, но можем потом добавить)&lt;br /&gt;
* начиная от корня сайта (можно указать id страницы, и тогда &amp;quot;дерево&amp;quot; будет построено от неё)&lt;br /&gt;
* выдавать признак, что есть дочерние страницы&lt;br /&gt;
* id текущей страницы передаем, чтобы в результате этот пункт был выделен как активный.&lt;br /&gt;
&lt;br /&gt;
Чтобы изучить возможность добавления второго уровня, добавим вложенную страницу внутрь нашей &amp;quot;Страницы 1&amp;quot;. Для этого с разделе &amp;quot;Структура&amp;quot; сайта ставим галочку рядом со &amp;quot;Страница 1&amp;quot; и нажимаем плюс в меню. Назовем ее &amp;quot;Страница 3&amp;quot; и page3 в качестве псевдостатического адреса. Обновляем страницу в браузере - в массиве $menuTree ничего не поменялось!!!&lt;br /&gt;
&lt;br /&gt;
Это очередная засада UMI CMS. Чтобы используемый нами макрос выдавал вложенные страницы, надо в данном случае на &amp;quot;Странице 1&amp;quot; в '''Дополнительных параметрах''' поставить признаки &amp;quot;Меню всегда развернуто&amp;quot; и &amp;quot;Показывать подменю&amp;quot;. Понятно, что это вопрос умолчаний, но в современных сайтах чаще используется развернутое меню, управляемое JS, а не как раньше - статическое индивидуальное меню для каждой страницы.&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', может, пора уже облегчить жизнь редакторам сайтов, и изменить настройки? Пусть у всех страниц эти признаки будут по умолчанию включены, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Полюбовавшись структурой полученного массива, можем теперь вывести нормальное меню сайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Логотип&amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['void:lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['nodes:item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом виде сайт уже почти настоящий. На страницах выводится то, что перед этим мы закинули через админку. Но хотелось бы иметь возможность вносить правки прямо на сайте. UMI CMS дает такую возможность, её надо просто [[Добавление возможности Edit-in-place|внести в наш шаблон]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=346</id>
		<title>Создание &quot;правильного&quot; шаблона для сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=346"/>
		<updated>2020-11-05T15:14:36Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для компактности HTML кода буду использовать библиотеку Bootstrap4 - пользуйтесь своими любимыми фреймворками, если не нравится. Итак, сделаем код нашего шаблона несколько более полным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $page-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;description ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;keywords ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В &amp;lt;head&amp;gt; добавили тэг &amp;lt;base ...&amp;gt;, потому что в дальнейшем все, что касается конкретного сайта, планируем хранить в папке конкретного шаблона, в нашем случае default. UMI CMS считает папку шаблона корневой директорией сайта, но это не распространяется на стили, скрипты и картинки.&lt;br /&gt;
&lt;br /&gt;
Теперь главная страница сайта приобрела более &amp;quot;причёсанный&amp;quot; вид:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Главная.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заметим, что Title у страницы пустой, что не слишком хорошо. Можно прописывать это поле для каждой страницы. Но есть способ получше.&lt;br /&gt;
&lt;br /&gt;
== Настраиваем Title и другие SEO-параметры ==&lt;br /&gt;
&lt;br /&gt;
В шаблоне меняем строки заголовка, описания и ключевых слов на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $this-&amp;gt;escape($variables['title']) ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и видим теперь заголовок &amp;lt;title&amp;gt;UMI.CMS - Страница 1&amp;lt;/title&amp;gt;. Нам &amp;quot;UMI.CMS - &amp;quot; ни разу не нужно. Чтобы настроить параметры по умолчанию, в модулях (под бабочкой) находим раздел SEO, в нем справа вверху видим ссылку &amp;quot;Настройка модуля&amp;quot;, жмём и настраиваем, там всё просто. Заменяю &amp;quot;UMI.CMS - &amp;quot; на &amp;quot;Демонстрационный сайт - &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чем отличается от прежнего варианта шаблона? Тем, что мы не выводим тупо поле из данных конкретной страницы, а позволяем CMS сформировать для нас эти параметры, используя настройки по умолчанию.&lt;br /&gt;
&lt;br /&gt;
== Делим шаблон на части ==&lt;br /&gt;
&lt;br /&gt;
Чтобы не мучиться с длинной простынёй кода, существует хорошая практика делить его на разумные фрагменты. Скажем, сразу хочется выделить &amp;lt;head&amp;gt;, &amp;lt;header&amp;gt; и &amp;lt;footer&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В директории /templates/default/php/ создаём поддиректорию layout, а в ней файлы наших фрагментов:&lt;br /&gt;
&lt;br /&gt;
* head.phtml&lt;br /&gt;
* header.phtml&lt;br /&gt;
* main.phtml&lt;br /&gt;
* footer.phtml&lt;br /&gt;
&lt;br /&gt;
Помещаем в эти файлы фрагменты кода шаблонов, например, head.phtml будет выглядеть вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А main.phtml вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь в шаблоне можно просто подключить эти фрагменты:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в качестве первого параметра при вызове метода render() мы передаем массив $variables конкретной страницы. Второй параметр - это адрес шаблона относительно папки php и без расшмрения &amp;quot;.phtml&amp;quot;. Поэтому делать у файлов шаблона именно такое расширение - '''обязательно'''! Иначе не найдет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем меню ==&lt;br /&gt;
&lt;br /&gt;
Выше мы использовали волшебную переменную $this, но для вызова только одного метода - render(). А какие еще методы нам доступны?&lt;br /&gt;
&lt;br /&gt;
Полный список был бы весьма желателен. Но если кратко - все публичные методы модуля '''content''', их описание и код можно посмотреть в /classes/components/content/class.php и /classes/components/content/macros.php, а также системные и сервисные методы, наследуемые этими классами. Методы класса можно использовать непосредственно, макросы - при помощи метода macros().&lt;br /&gt;
&lt;br /&gt;
Нам для сайта надо получить &amp;quot;дерево&amp;quot; меню. Для этого в файл header.phtml добавляем код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
var_dump($menuTree);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый параметр метода macros() - название модуля, второй - название метода, третий - параметры, передаваемые методу. Список параметров можно посмотреть в коде метода, все макросы хорошо документированы комментариями. В данном случае используем:&lt;br /&gt;
&lt;br /&gt;
* шаблон не задан (шаблон задается в других шаблонизаторах, в PHP не работает)&lt;br /&gt;
* 2 уровня вложенности (у нас пока один, но можем потом добавить)&lt;br /&gt;
* начиная от корня сайта (можно указать id страницы, и тогда &amp;quot;дерево&amp;quot; будет построено от неё)&lt;br /&gt;
* выдавать признак, что есть дочерние страницы&lt;br /&gt;
* id текущей страницы передаем, чтобы в результате этот пункт был выделен как активный.&lt;br /&gt;
&lt;br /&gt;
Чтобы изучить возможность добавления второго уровня, добавим вложенную страницу внутрь нашей &amp;quot;Страницы 1&amp;quot;. Для этого с разделе &amp;quot;Структура&amp;quot; сайта ставим галочку рядом со &amp;quot;Страница 1&amp;quot; и нажимаем плюс в меню. Назовем ее &amp;quot;Страница 3&amp;quot; и page3 в качестве псевдостатического адреса. Обновляем страницу в браузере - в массиве $menuTree ничего не поменялось!!!&lt;br /&gt;
&lt;br /&gt;
Это очередная засада UMI CMS. Чтобы используемый нами макрос выдавал вложенные страницы, надо в данном случае на &amp;quot;Странице 1&amp;quot; в '''Дополнительных параметрах''' поставить признаки &amp;quot;Меню всегда развернуто&amp;quot; и &amp;quot;Показывать подменю&amp;quot;. Понятно, что это вопрос умолчаний, но в современных сайтах чаще используется развернутое меню, управляемое JS, а не как раньше - статическое индивидуальное меню для каждой страницы.&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', может, пора уже облегчить жизнь редакторам сайтов, и изменить настройки? Пусть у всех страниц эти признаки будут по умолчанию включены, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Полюбовавшись структурой полученного массива, можем теперь вывести нормальное меню сайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Логотип&amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['void:lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['nodes:item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом виде сайт уже почти настоящий. На страницах выводится то, что перед этим мы закинули через админку. Но хотелось бы иметь возможность вносить правки прямо на сайте. UMI CMS дает такую возможность, её надо просто [[Добавление возможности Edit-in-place|внести в наш шаблон]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=345</id>
		<title>Создание &quot;правильного&quot; шаблона для сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=345"/>
		<updated>2020-11-05T15:14:23Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для компактности HTML кода буду использовать библиотеку Bootstrap4 - пользуйтесь своими любимыми фреймворками, если не нравится. Итак, сделаем код нашего шаблона несколько более полным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php|html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $page-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;description ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;keywords ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В &amp;lt;head&amp;gt; добавили тэг &amp;lt;base ...&amp;gt;, потому что в дальнейшем все, что касается конкретного сайта, планируем хранить в папке конкретного шаблона, в нашем случае default. UMI CMS считает папку шаблона корневой директорией сайта, но это не распространяется на стили, скрипты и картинки.&lt;br /&gt;
&lt;br /&gt;
Теперь главная страница сайта приобрела более &amp;quot;причёсанный&amp;quot; вид:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Главная.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заметим, что Title у страницы пустой, что не слишком хорошо. Можно прописывать это поле для каждой страницы. Но есть способ получше.&lt;br /&gt;
&lt;br /&gt;
== Настраиваем Title и другие SEO-параметры ==&lt;br /&gt;
&lt;br /&gt;
В шаблоне меняем строки заголовка, описания и ключевых слов на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $this-&amp;gt;escape($variables['title']) ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и видим теперь заголовок &amp;lt;title&amp;gt;UMI.CMS - Страница 1&amp;lt;/title&amp;gt;. Нам &amp;quot;UMI.CMS - &amp;quot; ни разу не нужно. Чтобы настроить параметры по умолчанию, в модулях (под бабочкой) находим раздел SEO, в нем справа вверху видим ссылку &amp;quot;Настройка модуля&amp;quot;, жмём и настраиваем, там всё просто. Заменяю &amp;quot;UMI.CMS - &amp;quot; на &amp;quot;Демонстрационный сайт - &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чем отличается от прежнего варианта шаблона? Тем, что мы не выводим тупо поле из данных конкретной страницы, а позволяем CMS сформировать для нас эти параметры, используя настройки по умолчанию.&lt;br /&gt;
&lt;br /&gt;
== Делим шаблон на части ==&lt;br /&gt;
&lt;br /&gt;
Чтобы не мучиться с длинной простынёй кода, существует хорошая практика делить его на разумные фрагменты. Скажем, сразу хочется выделить &amp;lt;head&amp;gt;, &amp;lt;header&amp;gt; и &amp;lt;footer&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В директории /templates/default/php/ создаём поддиректорию layout, а в ней файлы наших фрагментов:&lt;br /&gt;
&lt;br /&gt;
* head.phtml&lt;br /&gt;
* header.phtml&lt;br /&gt;
* main.phtml&lt;br /&gt;
* footer.phtml&lt;br /&gt;
&lt;br /&gt;
Помещаем в эти файлы фрагменты кода шаблонов, например, head.phtml будет выглядеть вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А main.phtml вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь в шаблоне можно просто подключить эти фрагменты:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в качестве первого параметра при вызове метода render() мы передаем массив $variables конкретной страницы. Второй параметр - это адрес шаблона относительно папки php и без расшмрения &amp;quot;.phtml&amp;quot;. Поэтому делать у файлов шаблона именно такое расширение - '''обязательно'''! Иначе не найдет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем меню ==&lt;br /&gt;
&lt;br /&gt;
Выше мы использовали волшебную переменную $this, но для вызова только одного метода - render(). А какие еще методы нам доступны?&lt;br /&gt;
&lt;br /&gt;
Полный список был бы весьма желателен. Но если кратко - все публичные методы модуля '''content''', их описание и код можно посмотреть в /classes/components/content/class.php и /classes/components/content/macros.php, а также системные и сервисные методы, наследуемые этими классами. Методы класса можно использовать непосредственно, макросы - при помощи метода macros().&lt;br /&gt;
&lt;br /&gt;
Нам для сайта надо получить &amp;quot;дерево&amp;quot; меню. Для этого в файл header.phtml добавляем код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
var_dump($menuTree);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый параметр метода macros() - название модуля, второй - название метода, третий - параметры, передаваемые методу. Список параметров можно посмотреть в коде метода, все макросы хорошо документированы комментариями. В данном случае используем:&lt;br /&gt;
&lt;br /&gt;
* шаблон не задан (шаблон задается в других шаблонизаторах, в PHP не работает)&lt;br /&gt;
* 2 уровня вложенности (у нас пока один, но можем потом добавить)&lt;br /&gt;
* начиная от корня сайта (можно указать id страницы, и тогда &amp;quot;дерево&amp;quot; будет построено от неё)&lt;br /&gt;
* выдавать признак, что есть дочерние страницы&lt;br /&gt;
* id текущей страницы передаем, чтобы в результате этот пункт был выделен как активный.&lt;br /&gt;
&lt;br /&gt;
Чтобы изучить возможность добавления второго уровня, добавим вложенную страницу внутрь нашей &amp;quot;Страницы 1&amp;quot;. Для этого с разделе &amp;quot;Структура&amp;quot; сайта ставим галочку рядом со &amp;quot;Страница 1&amp;quot; и нажимаем плюс в меню. Назовем ее &amp;quot;Страница 3&amp;quot; и page3 в качестве псевдостатического адреса. Обновляем страницу в браузере - в массиве $menuTree ничего не поменялось!!!&lt;br /&gt;
&lt;br /&gt;
Это очередная засада UMI CMS. Чтобы используемый нами макрос выдавал вложенные страницы, надо в данном случае на &amp;quot;Странице 1&amp;quot; в '''Дополнительных параметрах''' поставить признаки &amp;quot;Меню всегда развернуто&amp;quot; и &amp;quot;Показывать подменю&amp;quot;. Понятно, что это вопрос умолчаний, но в современных сайтах чаще используется развернутое меню, управляемое JS, а не как раньше - статическое индивидуальное меню для каждой страницы.&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', может, пора уже облегчить жизнь редакторам сайтов, и изменить настройки? Пусть у всех страниц эти признаки будут по умолчанию включены, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Полюбовавшись структурой полученного массива, можем теперь вывести нормальное меню сайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Логотип&amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['void:lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['nodes:item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом виде сайт уже почти настоящий. На страницах выводится то, что перед этим мы закинули через админку. Но хотелось бы иметь возможность вносить правки прямо на сайте. UMI CMS дает такую возможность, её надо просто [[Добавление возможности Edit-in-place|внести в наш шаблон]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=344</id>
		<title>Создание &quot;правильного&quot; шаблона для сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%22%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%22_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=344"/>
		<updated>2020-11-05T15:13:43Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для компактности HTML кода буду использовать библиотеку Bootstrap4 - пользуйтесь своими любимыми фреймворками, если не нравится. Итак, сделаем код нашего шаблона несколько более полным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $page-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;description ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $page-&amp;gt;keywords ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В &amp;lt;head&amp;gt; добавили тэг &amp;lt;base ...&amp;gt;, потому что в дальнейшем все, что касается конкретного сайта, планируем хранить в папке конкретного шаблона, в нашем случае default. UMI CMS считает папку шаблона корневой директорией сайта, но это не распространяется на стили, скрипты и картинки.&lt;br /&gt;
&lt;br /&gt;
Теперь главная страница сайта приобрела более &amp;quot;причёсанный&amp;quot; вид:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Главная.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Заметим, что Title у страницы пустой, что не слишком хорошо. Можно прописывать это поле для каждой страницы. Но есть способ получше.&lt;br /&gt;
&lt;br /&gt;
== Настраиваем Title и другие SEO-параметры ==&lt;br /&gt;
&lt;br /&gt;
В шаблоне меняем строки заголовка, описания и ключевых слов на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $this-&amp;gt;escape($variables['title']) ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и видим теперь заголовок &amp;lt;title&amp;gt;UMI.CMS - Страница 1&amp;lt;/title&amp;gt;. Нам &amp;quot;UMI.CMS - &amp;quot; ни разу не нужно. Чтобы настроить параметры по умолчанию, в модулях (под бабочкой) находим раздел SEO, в нем справа вверху видим ссылку &amp;quot;Настройка модуля&amp;quot;, жмём и настраиваем, там всё просто. Заменяю &amp;quot;UMI.CMS - &amp;quot; на &amp;quot;Демонстрационный сайт - &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чем отличается от прежнего варианта шаблона? Тем, что мы не выводим тупо поле из данных конкретной страницы, а позволяем CMS сформировать для нас эти параметры, используя настройки по умолчанию.&lt;br /&gt;
&lt;br /&gt;
== Делим шаблон на части ==&lt;br /&gt;
&lt;br /&gt;
Чтобы не мучиться с длинной простынёй кода, существует хорошая практика делить его на разумные фрагменты. Скажем, сразу хочется выделить &amp;lt;head&amp;gt;, &amp;lt;header&amp;gt; и &amp;lt;footer&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В директории /templates/default/php/ создаём поддиректорию layout, а в ней файлы наших фрагментов:&lt;br /&gt;
&lt;br /&gt;
* head.phtml&lt;br /&gt;
* header.phtml&lt;br /&gt;
* main.phtml&lt;br /&gt;
* footer.phtml&lt;br /&gt;
&lt;br /&gt;
Помещаем в эти файлы фрагменты кода шаблонов, например, head.phtml будет выглядеть вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;base href=&amp;quot;/templates/default/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $variables['title'] ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['description'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;&amp;lt;?= $variables['meta']['keywords'] ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А main.phtml вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;main&amp;gt;&lt;br /&gt;
        &amp;lt;section&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;col-12&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/section&amp;gt;&lt;br /&gt;
    &amp;lt;/main&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь в шаблоне можно просто подключить эти фрагменты:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в качестве первого параметра при вызове метода render() мы передаем массив $variables конкретной страницы. Второй параметр - это адрес шаблона относительно папки php и без расшмрения &amp;quot;.phtml&amp;quot;. Поэтому делать у файлов шаблона именно такое расширение - '''обязательно'''! Иначе не найдет.&lt;br /&gt;
&lt;br /&gt;
== Добавляем меню ==&lt;br /&gt;
&lt;br /&gt;
Выше мы использовали волшебную переменную $this, но для вызова только одного метода - render(). А какие еще методы нам доступны?&lt;br /&gt;
&lt;br /&gt;
Полный список был бы весьма желателен. Но если кратко - все публичные методы модуля '''content''', их описание и код можно посмотреть в /classes/components/content/class.php и /classes/components/content/macros.php, а также системные и сервисные методы, наследуемые этими классами. Методы класса можно использовать непосредственно, макросы - при помощи метода macros().&lt;br /&gt;
&lt;br /&gt;
Нам для сайта надо получить &amp;quot;дерево&amp;quot; меню. Для этого в файл header.phtml добавляем код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
var_dump($menuTree);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый параметр метода macros() - название модуля, второй - название метода, третий - параметры, передаваемые методу. Список параметров можно посмотреть в коде метода, все макросы хорошо документированы комментариями. В данном случае используем:&lt;br /&gt;
&lt;br /&gt;
* шаблон не задан (шаблон задается в других шаблонизаторах, в PHP не работает)&lt;br /&gt;
* 2 уровня вложенности (у нас пока один, но можем потом добавить)&lt;br /&gt;
* начиная от корня сайта (можно указать id страницы, и тогда &amp;quot;дерево&amp;quot; будет построено от неё)&lt;br /&gt;
* выдавать признак, что есть дочерние страницы&lt;br /&gt;
* id текущей страницы передаем, чтобы в результате этот пункт был выделен как активный.&lt;br /&gt;
&lt;br /&gt;
Чтобы изучить возможность добавления второго уровня, добавим вложенную страницу внутрь нашей &amp;quot;Страницы 1&amp;quot;. Для этого с разделе &amp;quot;Структура&amp;quot; сайта ставим галочку рядом со &amp;quot;Страница 1&amp;quot; и нажимаем плюс в меню. Назовем ее &amp;quot;Страница 3&amp;quot; и page3 в качестве псевдостатического адреса. Обновляем страницу в браузере - в массиве $menuTree ничего не поменялось!!!&lt;br /&gt;
&lt;br /&gt;
Это очередная засада UMI CMS. Чтобы используемый нами макрос выдавал вложенные страницы, надо в данном случае на &amp;quot;Странице 1&amp;quot; в '''Дополнительных параметрах''' поставить признаки &amp;quot;Меню всегда развернуто&amp;quot; и &amp;quot;Показывать подменю&amp;quot;. Понятно, что это вопрос умолчаний, но в современных сайтах чаще используется развернутое меню, управляемое JS, а не как раньше - статическое индивидуальное меню для каждой страницы.&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', может, пора уже облегчить жизнь редакторам сайтов, и изменить настройки? Пусть у всех страниц эти признаки будут по умолчанию включены, как вы считаете?&lt;br /&gt;
&lt;br /&gt;
Полюбовавшись структурой полученного массива, можем теперь вывести нормальное меню сайта:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$pageId = isset($variables['pageId'])?$variables['pageId']:0;&lt;br /&gt;
$menuTree = $this-&amp;gt;macros('content', 'menu', [0, 2, 0, true, $pageId]);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&lt;br /&gt;
        &amp;lt;nav class=&amp;quot;navbar navbar-expand-lg navbar-light bg-light&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;/&amp;quot;&amp;gt;Логотип&amp;lt;/a&amp;gt;&lt;br /&gt;
            &amp;lt;button class=&amp;quot;navbar-toggler&amp;quot; type=&amp;quot;button&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;#navbarSupportedContent&amp;quot; aria-controls=&amp;quot;navbarSupportedContent&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-label=&amp;quot;Toggle navigation&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;span class=&amp;quot;navbar-toggler-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;div class=&amp;quot;collapse navbar-collapse&amp;quot; id=&amp;quot;navbarSupportedContent&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;ul class=&amp;quot;navbar-nav mr-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
    foreach ($menuTree['void:lines'] as $item) {&lt;br /&gt;
        $dropdown = !empty($item['items']['nodes:item']);&lt;br /&gt;
        $active = !empty($item['attribute:status']);&lt;br /&gt;
        if (isset($item['link']) &amp;amp;&amp;amp; isset($item['name'])) {&lt;br /&gt;
            if ($dropdown) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item dropdown &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot; id=&amp;quot;navbarDropdown&amp;quot; role=&amp;quot;button&amp;quot; data-toggle=&amp;quot;dropdown&amp;quot; aria-haspopup=&amp;quot;true&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;dropdown-menu&amp;quot; aria-labelledby=&amp;quot;navbarDropdown&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                foreach ($item['items']['nodes:item'] as $sub) {&lt;br /&gt;
                    if (isset($sub['link']) &amp;amp;&amp;amp; isset($sub['name'])) {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;&amp;lt;?= $sub['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $sub['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            } else {&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                    &amp;lt;li class=&amp;quot;nav-item  &amp;lt;?=$active?'active':''?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                    &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                &amp;lt;/ul&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/nav&amp;gt;&lt;br /&gt;
    &amp;lt;/header&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом виде сайт уже почти настоящий. На страницах выводится то, что перед этим мы закинули через админку. Но хотелось бы иметь возможность вносить правки прямо на сайте. UMI CMS дает такую возможность, её надо просто [[Добавление возможности Edit-in-place|внести в наш шаблон]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=343</id>
		<title>Структура сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=343"/>
		<updated>2020-11-05T15:12:26Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Добавление главной и внутренних страниц ==&lt;br /&gt;
&lt;br /&gt;
На нашем сайте есть шаблон, но нет ни одной страницы. Пора создать несколько. В списке модулей выбираем раздел &amp;quot;Структура&amp;quot; и видим корневую папку нашего домена:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 11 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Ставим галочку рядом с доменом и нажимаем пиктограмму с плюсом в меню над ним:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Добавление страницы.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить галочку &amp;quot;Страница по умолчанию&amp;quot; в группе &amp;quot;Дополнительные параметры&amp;quot;, потому что это будет наша главная страница. Поле &amp;quot;Псевдостатический адрес&amp;quot; заполняется автоматически, но можно изменить. Это поле в дальнейшем будет частью URL страницы для всех, кроме главной.&lt;br /&gt;
&lt;br /&gt;
Добавим еще несколько страниц, уже не главных, для чего опять отмечаем галочкой наш домен и нажимаем плюс. В результате получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Псевдостатические адреса у страниц page1 и page2 соответственно. Мы можем посмотреть каждую из страниц http://umi.example.com/page1/ и увидим то единственное, что выдает наш шаблон - &amp;quot;It works!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Отображение на странице её содержимого ==&lt;br /&gt;
&lt;br /&gt;
Продолжаем эксперименты с шаблоном. Изменяем код шаблона следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И видим много интересного. В массиве содержится информация о пользователе, о элементах запроса, есть заголовок страницы, но не все поля доступны в виде элементов массива $variables. Страница целиком представлена как объект $variables['full:page']. Поэтому пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['full:page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И вот наконец-то по ссылке http://umi.example.com/page1/ мы видим то, что ввели при создании страницы:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
== Немного &amp;quot;причесать&amp;quot; массив $variables ==&lt;br /&gt;
&lt;br /&gt;
Поскольку UMI CMS была установлена без шаблона, то файл конфигурации не был настроен на PHP-шаблонизатор, поэтому и видим всякие 'full:page' и '@name' в качестве ключей в массиве. Можно так и тащить их по всему коду, а можно создать в папке шаблона (у нас default) файл config.ini и вставить в него 4 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[system]&lt;br /&gt;
use-php-template-data-cleaning = &amp;quot;1&amp;quot;&lt;br /&gt;
return-array-from-macros-execution = &amp;quot;1&amp;quot;&lt;br /&gt;
collapse-array-only-with-useless-key-in-data-cleaner = &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого можно будет получить более красивые ключи массива $varianles, например, $varianles['page'], это легко увидеть, вернув var_dump($varianles) в начало common.phtml.&lt;br /&gt;
&lt;br /&gt;
== Некоторые секретные возможности UMI CMS ==&lt;br /&gt;
&lt;br /&gt;
Попробуем вместо ссылки http://umi.example.com/page1/ ввести http://umi.example.com/page1/.json - круто? Это возможность, которую мы получаем прямо из коробки. Нам нет нужды делать для сайта какой-то HTML, мы можем весь сайт сделать на JS при помощи соответствующих AJAX-запросов! Или аналогичным образом сделать мобильное приложение.&lt;br /&gt;
&lt;br /&gt;
Заметим, что получаемая информация вообще не зависит от нашего шаблона. Это json-массив, формируемый методом content модуля content, аналогичный тому, что передается в шаблон в массиве $variables.&lt;br /&gt;
&lt;br /&gt;
К слову, ссылка http://umi.example.com/page1/.xml тоже работает. Кому что больше подходит.&lt;br /&gt;
&lt;br /&gt;
Не все модули отдают контент подобным образом, но все - при помощи модуля udata, ссылка будет выглядеть примерно так http://umi.example.com/udata://news/lastlist/7/.json (где 7 - это id ленты новостей, на других сайтах может быть другой).&lt;br /&gt;
&lt;br /&gt;
== Что дальше? ==&lt;br /&gt;
&lt;br /&gt;
На этом можно было бы и закончить, но конечно, этого пока недостаточно для нормального сайта, поэтому перейдем к [[Создание &amp;quot;правильного&amp;quot; шаблона для сайта|созданию &amp;quot;нормального&amp;quot; шаблона]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=342</id>
		<title>Структура сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=342"/>
		<updated>2020-11-05T15:11:34Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Немного &amp;quot;причесать&amp;quot; массив $variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Добавление главной и внутренних страниц ==&lt;br /&gt;
&lt;br /&gt;
На нашем сайте есть шаблон, но нет ни одной страницы. Пора создать несколько. В списке модулей выбираем раздел &amp;quot;Структура&amp;quot; и видим корневую папку нашего домена:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 11 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Ставим галочку рядом с доменом и нажимаем пиктограмму с плюсом в меню над ним:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Добавление страницы.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить галочку &amp;quot;Страница по умолчанию&amp;quot; в группе &amp;quot;Дополнительные параметры&amp;quot;, потому что это будет наша главная страница. Поле &amp;quot;Псевдостатический адрес&amp;quot; заполняется автоматически, но можно изменить. Это поле в дальнейшем будет частью URL страницы для всех, кроме главной.&lt;br /&gt;
&lt;br /&gt;
Добавим еще несколько страниц, уже не главных, для чего опять отмечаем галочкой наш домен и нажимаем плюс. В результате получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Псевдостатические адреса у страниц page1 и page2 соответственно. Мы можем посмотреть каждую из страниц http://umi.example.com/page1/ и увидим то единственное, что выдает наш шаблон - &amp;quot;It works!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Добавление главной и внутренних страниц ==&lt;br /&gt;
&lt;br /&gt;
На нашем сайте есть шаблон, но нет ни одной страницы. Пора создать несколько. В списке модулей выбираем раздел &amp;quot;Структура&amp;quot; и видим корневую папку нашего домена:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 11 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Ставим галочку рядом с доменом и нажимаем пиктограмму с плюсом в меню над ним:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Добавление страницы.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить галочку &amp;quot;Страница по умолчанию&amp;quot; в группе &amp;quot;Дополнительные параметры&amp;quot;, потому что это будет наша главная страница. Поле &amp;quot;Псевдостатический адрес&amp;quot; заполняется автоматически, но можно изменить. Это поле в дальнейшем будет частью URL страницы для всех, кроме главной.&lt;br /&gt;
&lt;br /&gt;
Добавим еще несколько страниц, уже не главных, для чего опять отмечаем галочкой наш домен и нажимаем плюс. В результате получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Псевдостатические адреса у страниц page1 и page2 соответственно. Мы можем посмотреть каждую из страниц http://umi.example.com/page1/ и увидим то единственное, что выдает наш шаблон - &amp;quot;It works!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Отображение на странице её содержимого ==&lt;br /&gt;
&lt;br /&gt;
Продолжаем эксперименты с шаблоном. Изменяем код шаблона следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И видим много интересного. В массиве содержится информация о пользователе, о элементах запроса, есть заголовок страницы, но не все поля доступны в виде элементов массива $variables. Страница целиком представлена как объект $variables['full:page']. Поэтому пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['full:page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И вот наконец-то по ссылке http://umi.example.com/page1/ мы видим то, что ввели при создании страницы:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
== Немного &amp;quot;причесать&amp;quot; массив $variables ==&lt;br /&gt;
&lt;br /&gt;
Поскольку UMI CMS была установлена без шаблона, то файл конфигурации не был настроен на PHP-шаблонизатор, поэтому и видим всякие 'full:page' и '@name' в качестве ключей в массиве. Можно так и тащить их по всему коду, а можно создать в папке шаблона (у нас default) файл config.ini и вставить в него 4 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;config&amp;quot;&amp;gt;&lt;br /&gt;
[system]&lt;br /&gt;
use-php-template-data-cleaning = &amp;quot;1&amp;quot;&lt;br /&gt;
return-array-from-macros-execution = &amp;quot;1&amp;quot;&lt;br /&gt;
collapse-array-only-with-useless-key-in-data-cleaner = &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого можно будет получить более красивые ключи массива $varianles, например, $varianles['page'], это легко увидеть, вернув var_dump($varianles) в начало common.phtml.&lt;br /&gt;
&lt;br /&gt;
== Некоторые секретные возможности UMI CMS ==&lt;br /&gt;
&lt;br /&gt;
Попробуем вместо ссылки http://umi.example.com/page1/ ввести http://umi.example.com/page1/.json - круто? Это возможность, которую мы получаем прямо из коробки. Нам нет нужды делать для сайта какой-то HTML, мы можем весь сайт сделать на JS при помощи соответствующих AJAX-запросов! Или аналогичным образом сделать мобильное приложение.&lt;br /&gt;
&lt;br /&gt;
Заметим, что получаемая информация вообще не зависит от нашего шаблона. Это json-массив, формируемый методом content модуля content, аналогичный тому, что передается в шаблон в массиве $variables.&lt;br /&gt;
&lt;br /&gt;
К слову, ссылка http://umi.example.com/page1/.xml тоже работает. Кому что больше подходит.&lt;br /&gt;
&lt;br /&gt;
Не все модули отдают контент подобным образом, но все - при помощи модуля udata, ссылка будет выглядеть примерно так http://umi.example.com/udata://news/lastlist/7/.json (где 7 - это id ленты новостей, на других сайтах может быть другой).&lt;br /&gt;
&lt;br /&gt;
== Что дальше? ==&lt;br /&gt;
&lt;br /&gt;
На этом можно было бы и закончить, но конечно, этого пока недостаточно для нормального сайта, поэтому перейдем к [[Создание &amp;quot;правильного&amp;quot; шаблона для сайта|созданию &amp;quot;нормального&amp;quot; шаблона]].&lt;br /&gt;
&lt;br /&gt;
== Немного &amp;quot;причесать&amp;quot; массив $variables ==&lt;br /&gt;
&lt;br /&gt;
Поскольку UMI CMS была установлена без шаблона, то файл конфигурации не был настроен на PHP-шаблонизатор, поэтому и видим всякие 'full:page' и '@name' в качестве ключей в массиве. Можно так и тащить их по всему коду, а можно создать в папке шаблона (у нас default) файл config.ini и вставить в него 4 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[system]&lt;br /&gt;
use-php-template-data-cleaning = &amp;quot;1&amp;quot;&lt;br /&gt;
return-array-from-macros-execution = &amp;quot;1&amp;quot;&lt;br /&gt;
collapse-array-only-with-useless-key-in-data-cleaner = &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого можно будет получить более красивые ключи массива $varianles, например, $varianles['page'], это легко увидеть, вернув var_dump($varianles) в начало common.phtml.&lt;br /&gt;
&lt;br /&gt;
== Некоторые секретные возможности UMI CMS ==&lt;br /&gt;
&lt;br /&gt;
Попробуем вместо ссылки http://umi.example.com/page1/ ввести http://umi.example.com/page1/.json - круто? Это возможность, которую мы получаем прямо из коробки. Нам нет нужды делать для сайта какой-то HTML, мы можем весь сайт сделать на JS при помощи соответствующих AJAX-запросов! Или аналогичным образом сделать мобильное приложение.&lt;br /&gt;
&lt;br /&gt;
Заметим, что получаемая информация вообще не зависит от нашего шаблона. Это json-массив, формируемый методом content модуля content, аналогичный тому, что передается в шаблон в массиве $variables.&lt;br /&gt;
&lt;br /&gt;
К слову, ссылка http://umi.example.com/page1/.xml тоже работает. Кому что больше подходит.&lt;br /&gt;
&lt;br /&gt;
Не все модули отдают контент подобным образом, но все - при помощи модуля udata, ссылка будет выглядеть примерно так http://umi.example.com/udata://news/lastlist/7/.json (где 7 - это id ленты новостей, на других сайтах может быть другой).&lt;br /&gt;
&lt;br /&gt;
== Что дальше? ==&lt;br /&gt;
&lt;br /&gt;
На этом можно было бы и закончить, но конечно, этого пока недостаточно для нормального сайта, поэтому перейдем к [[Создание &amp;quot;правильного&amp;quot; шаблона для сайта|созданию &amp;quot;нормального&amp;quot; шаблона]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=341</id>
		<title>Структура сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=341"/>
		<updated>2020-11-05T15:11:06Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Немного &amp;quot;причесать&amp;quot; массив $variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Добавление главной и внутренних страниц ==&lt;br /&gt;
&lt;br /&gt;
На нашем сайте есть шаблон, но нет ни одной страницы. Пора создать несколько. В списке модулей выбираем раздел &amp;quot;Структура&amp;quot; и видим корневую папку нашего домена:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 11 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Ставим галочку рядом с доменом и нажимаем пиктограмму с плюсом в меню над ним:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Добавление страницы.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить галочку &amp;quot;Страница по умолчанию&amp;quot; в группе &amp;quot;Дополнительные параметры&amp;quot;, потому что это будет наша главная страница. Поле &amp;quot;Псевдостатический адрес&amp;quot; заполняется автоматически, но можно изменить. Это поле в дальнейшем будет частью URL страницы для всех, кроме главной.&lt;br /&gt;
&lt;br /&gt;
Добавим еще несколько страниц, уже не главных, для чего опять отмечаем галочкой наш домен и нажимаем плюс. В результате получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Псевдостатические адреса у страниц page1 и page2 соответственно. Мы можем посмотреть каждую из страниц http://umi.example.com/page1/ и увидим то единственное, что выдает наш шаблон - &amp;quot;It works!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Добавление главной и внутренних страниц ==&lt;br /&gt;
&lt;br /&gt;
На нашем сайте есть шаблон, но нет ни одной страницы. Пора создать несколько. В списке модулей выбираем раздел &amp;quot;Структура&amp;quot; и видим корневую папку нашего домена:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 11 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Ставим галочку рядом с доменом и нажимаем пиктограмму с плюсом в меню над ним:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Добавление страницы.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить галочку &amp;quot;Страница по умолчанию&amp;quot; в группе &amp;quot;Дополнительные параметры&amp;quot;, потому что это будет наша главная страница. Поле &amp;quot;Псевдостатический адрес&amp;quot; заполняется автоматически, но можно изменить. Это поле в дальнейшем будет частью URL страницы для всех, кроме главной.&lt;br /&gt;
&lt;br /&gt;
Добавим еще несколько страниц, уже не главных, для чего опять отмечаем галочкой наш домен и нажимаем плюс. В результате получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Псевдостатические адреса у страниц page1 и page2 соответственно. Мы можем посмотреть каждую из страниц http://umi.example.com/page1/ и увидим то единственное, что выдает наш шаблон - &amp;quot;It works!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Отображение на странице её содержимого ==&lt;br /&gt;
&lt;br /&gt;
Продолжаем эксперименты с шаблоном. Изменяем код шаблона следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И видим много интересного. В массиве содержится информация о пользователе, о элементах запроса, есть заголовок страницы, но не все поля доступны в виде элементов массива $variables. Страница целиком представлена как объект $variables['full:page']. Поэтому пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['full:page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И вот наконец-то по ссылке http://umi.example.com/page1/ мы видим то, что ввели при создании страницы:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
== Немного &amp;quot;причесать&amp;quot; массив $variables ==&lt;br /&gt;
&lt;br /&gt;
Поскольку UMI CMS была установлена без шаблона, то файл конфигурации не был настроен на PHP-шаблонизатор, поэтому и видим всякие 'full:page' и '@name' в качестве ключей в массиве. Можно так и тащить их по всему коду, а можно создать в папке шаблона (у нас default) файл config.ini и вставить в него 4 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;config&amp;quot;&amp;gt;&lt;br /&gt;
[system]&lt;br /&gt;
use-php-template-data-cleaning = &amp;quot;1&amp;quot;&lt;br /&gt;
return-array-from-macros-execution = &amp;quot;1&amp;quot;&lt;br /&gt;
collapse-array-only-with-useless-key-in-data-cleaner = &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого можно будет получить более красивые ключи массива $varianles, например, $varianles['page'], это легко увидеть, вернув var_dump($varianles) в начало common.phtml.&lt;br /&gt;
&lt;br /&gt;
== Некоторые секретные возможности UMI CMS ==&lt;br /&gt;
&lt;br /&gt;
Попробуем вместо ссылки http://umi.example.com/page1/ ввести http://umi.example.com/page1/.json - круто? Это возможность, которую мы получаем прямо из коробки. Нам нет нужды делать для сайта какой-то HTML, мы можем весь сайт сделать на JS при помощи соответствующих AJAX-запросов! Или аналогичным образом сделать мобильное приложение.&lt;br /&gt;
&lt;br /&gt;
Заметим, что получаемая информация вообще не зависит от нашего шаблона. Это json-массив, формируемый методом content модуля content, аналогичный тому, что передается в шаблон в массиве $variables.&lt;br /&gt;
&lt;br /&gt;
К слову, ссылка http://umi.example.com/page1/.xml тоже работает. Кому что больше подходит.&lt;br /&gt;
&lt;br /&gt;
Не все модули отдают контент подобным образом, но все - при помощи модуля udata, ссылка будет выглядеть примерно так http://umi.example.com/udata://news/lastlist/7/.json (где 7 - это id ленты новостей, на других сайтах может быть другой).&lt;br /&gt;
&lt;br /&gt;
== Что дальше? ==&lt;br /&gt;
&lt;br /&gt;
На этом можно было бы и закончить, но конечно, этого пока недостаточно для нормального сайта, поэтому перейдем к [[Создание &amp;quot;правильного&amp;quot; шаблона для сайта|созданию &amp;quot;нормального&amp;quot; шаблона]].&lt;br /&gt;
&lt;br /&gt;
== Немного &amp;quot;причесать&amp;quot; массив $variables ==&lt;br /&gt;
&lt;br /&gt;
Поскольку UMI CMS была установлена без шаблона, то файл конфигурации не был настроен на PHP-шаблонизатор, поэтому и видим всякие 'full:page' и '@name' в качестве ключей в массиве. Можно так и тащить их по всему коду, а можно создать в папке шаблона (у нас default) файл config.ini и вставить в него 4 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[system]&lt;br /&gt;
use-php-template-data-cleaning = &amp;quot;1&amp;quot;&lt;br /&gt;
return-array-from-macros-execution = &amp;quot;1&amp;quot;&lt;br /&gt;
collapse-array-only-with-useless-key-in-data-cleaner = &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого можно будет получить более красивые ключи массива $varianles, например, $varianles['page'], это легко увидеть, вернув var_dump($varianles) в начало common.phtml.&lt;br /&gt;
&lt;br /&gt;
== Некоторые секретные возможности UMI CMS ==&lt;br /&gt;
&lt;br /&gt;
Попробуем вместо ссылки http://umi.example.com/page1/ ввести http://umi.example.com/page1/.json - круто? Это возможность, которую мы получаем прямо из коробки. Нам нет нужды делать для сайта какой-то HTML, мы можем весь сайт сделать на JS при помощи соответствующих AJAX-запросов! Или аналогичным образом сделать мобильное приложение.&lt;br /&gt;
&lt;br /&gt;
Заметим, что получаемая информация вообще не зависит от нашего шаблона. Это json-массив, формируемый методом content модуля content, аналогичный тому, что передается в шаблон в массиве $variables.&lt;br /&gt;
&lt;br /&gt;
К слову, ссылка http://umi.example.com/page1/.xml тоже работает. Кому что больше подходит.&lt;br /&gt;
&lt;br /&gt;
Не все модули отдают контент подобным образом, но все - при помощи модуля udata, ссылка будет выглядеть примерно так http://umi.example.com/udata://news/lastlist/7/.json (где 7 - это id ленты новостей, на других сайтах может быть другой).&lt;br /&gt;
&lt;br /&gt;
== Что дальше? ==&lt;br /&gt;
&lt;br /&gt;
На этом можно было бы и закончить, но конечно, этого пока недостаточно для нормального сайта, поэтому перейдем к [[Создание &amp;quot;правильного&amp;quot; шаблона для сайта|созданию &amp;quot;нормального&amp;quot; шаблона]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=340</id>
		<title>Структура сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=340"/>
		<updated>2020-11-05T15:10:37Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Отображение на странице её содержимого */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Добавление главной и внутренних страниц ==&lt;br /&gt;
&lt;br /&gt;
На нашем сайте есть шаблон, но нет ни одной страницы. Пора создать несколько. В списке модулей выбираем раздел &amp;quot;Структура&amp;quot; и видим корневую папку нашего домена:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 11 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Ставим галочку рядом с доменом и нажимаем пиктограмму с плюсом в меню над ним:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Добавление страницы.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить галочку &amp;quot;Страница по умолчанию&amp;quot; в группе &amp;quot;Дополнительные параметры&amp;quot;, потому что это будет наша главная страница. Поле &amp;quot;Псевдостатический адрес&amp;quot; заполняется автоматически, но можно изменить. Это поле в дальнейшем будет частью URL страницы для всех, кроме главной.&lt;br /&gt;
&lt;br /&gt;
Добавим еще несколько страниц, уже не главных, для чего опять отмечаем галочкой наш домен и нажимаем плюс. В результате получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Псевдостатические адреса у страниц page1 и page2 соответственно. Мы можем посмотреть каждую из страниц http://umi.example.com/page1/ и увидим то единственное, что выдает наш шаблон - &amp;quot;It works!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Добавление главной и внутренних страниц ==&lt;br /&gt;
&lt;br /&gt;
На нашем сайте есть шаблон, но нет ни одной страницы. Пора создать несколько. В списке модулей выбираем раздел &amp;quot;Структура&amp;quot; и видим корневую папку нашего домена:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 11 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Ставим галочку рядом с доменом и нажимаем пиктограмму с плюсом в меню над ним:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Добавление страницы.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить галочку &amp;quot;Страница по умолчанию&amp;quot; в группе &amp;quot;Дополнительные параметры&amp;quot;, потому что это будет наша главная страница. Поле &amp;quot;Псевдостатический адрес&amp;quot; заполняется автоматически, но можно изменить. Это поле в дальнейшем будет частью URL страницы для всех, кроме главной.&lt;br /&gt;
&lt;br /&gt;
Добавим еще несколько страниц, уже не главных, для чего опять отмечаем галочкой наш домен и нажимаем плюс. В результате получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Псевдостатические адреса у страниц page1 и page2 соответственно. Мы можем посмотреть каждую из страниц http://umi.example.com/page1/ и увидим то единственное, что выдает наш шаблон - &amp;quot;It works!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Отображение на странице её содержимого ==&lt;br /&gt;
&lt;br /&gt;
Продолжаем эксперименты с шаблоном. Изменяем код шаблона следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И видим много интересного. В массиве содержится информация о пользователе, о элементах запроса, есть заголовок страницы, но не все поля доступны в виде элементов массива $variables. Страница целиком представлена как объект $variables['full:page']. Поэтому пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['full:page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И вот наконец-то по ссылке http://umi.example.com/page1/ мы видим то, что ввели при создании страницы:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
== Немного &amp;quot;причесать&amp;quot; массив $variables ==&lt;br /&gt;
&lt;br /&gt;
Поскольку UMI CMS была установлена без шаблона, то файл конфигурации не был настроен на PHP-шаблонизатор, поэтому и видим всякие 'full:page' и '@name' в качестве ключей в массиве. Можно так и тащить их по всему коду, а можно создать в папке шаблона (у нас default) файл config.ini и вставить в него 4 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[system]&lt;br /&gt;
use-php-template-data-cleaning = &amp;quot;1&amp;quot;&lt;br /&gt;
return-array-from-macros-execution = &amp;quot;1&amp;quot;&lt;br /&gt;
collapse-array-only-with-useless-key-in-data-cleaner = &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого можно будет получить более красивые ключи массива $varianles, например, $varianles['page'], это легко увидеть, вернув var_dump($varianles) в начало common.phtml.&lt;br /&gt;
&lt;br /&gt;
== Некоторые секретные возможности UMI CMS ==&lt;br /&gt;
&lt;br /&gt;
Попробуем вместо ссылки http://umi.example.com/page1/ ввести http://umi.example.com/page1/.json - круто? Это возможность, которую мы получаем прямо из коробки. Нам нет нужды делать для сайта какой-то HTML, мы можем весь сайт сделать на JS при помощи соответствующих AJAX-запросов! Или аналогичным образом сделать мобильное приложение.&lt;br /&gt;
&lt;br /&gt;
Заметим, что получаемая информация вообще не зависит от нашего шаблона. Это json-массив, формируемый методом content модуля content, аналогичный тому, что передается в шаблон в массиве $variables.&lt;br /&gt;
&lt;br /&gt;
К слову, ссылка http://umi.example.com/page1/.xml тоже работает. Кому что больше подходит.&lt;br /&gt;
&lt;br /&gt;
Не все модули отдают контент подобным образом, но все - при помощи модуля udata, ссылка будет выглядеть примерно так http://umi.example.com/udata://news/lastlist/7/.json (где 7 - это id ленты новостей, на других сайтах может быть другой).&lt;br /&gt;
&lt;br /&gt;
== Что дальше? ==&lt;br /&gt;
&lt;br /&gt;
На этом можно было бы и закончить, но конечно, этого пока недостаточно для нормального сайта, поэтому перейдем к [[Создание &amp;quot;правильного&amp;quot; шаблона для сайта|созданию &amp;quot;нормального&amp;quot; шаблона]].&lt;br /&gt;
&lt;br /&gt;
== Немного &amp;quot;причесать&amp;quot; массив $variables ==&lt;br /&gt;
&lt;br /&gt;
Поскольку UMI CMS была установлена без шаблона, то файл конфигурации не был настроен на PHP-шаблонизатор, поэтому и видим всякие 'full:page' и '@name' в качестве ключей в массиве. Можно так и тащить их по всему коду, а можно создать в папке шаблона (у нас default) файл config.ini и вставить в него 4 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[system]&lt;br /&gt;
use-php-template-data-cleaning = &amp;quot;1&amp;quot;&lt;br /&gt;
return-array-from-macros-execution = &amp;quot;1&amp;quot;&lt;br /&gt;
collapse-array-only-with-useless-key-in-data-cleaner = &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого можно будет получить более красивые ключи массива $varianles, например, $varianles['page'], это легко увидеть, вернув var_dump($varianles) в начало common.phtml.&lt;br /&gt;
&lt;br /&gt;
== Некоторые секретные возможности UMI CMS ==&lt;br /&gt;
&lt;br /&gt;
Попробуем вместо ссылки http://umi.example.com/page1/ ввести http://umi.example.com/page1/.json - круто? Это возможность, которую мы получаем прямо из коробки. Нам нет нужды делать для сайта какой-то HTML, мы можем весь сайт сделать на JS при помощи соответствующих AJAX-запросов! Или аналогичным образом сделать мобильное приложение.&lt;br /&gt;
&lt;br /&gt;
Заметим, что получаемая информация вообще не зависит от нашего шаблона. Это json-массив, формируемый методом content модуля content, аналогичный тому, что передается в шаблон в массиве $variables.&lt;br /&gt;
&lt;br /&gt;
К слову, ссылка http://umi.example.com/page1/.xml тоже работает. Кому что больше подходит.&lt;br /&gt;
&lt;br /&gt;
Не все модули отдают контент подобным образом, но все - при помощи модуля udata, ссылка будет выглядеть примерно так http://umi.example.com/udata://news/lastlist/7/.json (где 7 - это id ленты новостей, на других сайтах может быть другой).&lt;br /&gt;
&lt;br /&gt;
== Что дальше? ==&lt;br /&gt;
&lt;br /&gt;
На этом можно было бы и закончить, но конечно, этого пока недостаточно для нормального сайта, поэтому перейдем к [[Создание &amp;quot;правильного&amp;quot; шаблона для сайта|созданию &amp;quot;нормального&amp;quot; шаблона]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=339</id>
		<title>Структура сайта</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%81%D0%B0%D0%B9%D1%82%D0%B0&amp;diff=339"/>
		<updated>2020-11-05T15:09:34Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Добавление главной и внутренних страниц ==&lt;br /&gt;
&lt;br /&gt;
На нашем сайте есть шаблон, но нет ни одной страницы. Пора создать несколько. В списке модулей выбираем раздел &amp;quot;Структура&amp;quot; и видим корневую папку нашего домена:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 11 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Ставим галочку рядом с доменом и нажимаем пиктограмму с плюсом в меню над ним:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Добавление страницы.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Не забываем поставить галочку &amp;quot;Страница по умолчанию&amp;quot; в группе &amp;quot;Дополнительные параметры&amp;quot;, потому что это будет наша главная страница. Поле &amp;quot;Псевдостатический адрес&amp;quot; заполняется автоматически, но можно изменить. Это поле в дальнейшем будет частью URL страницы для всех, кроме главной.&lt;br /&gt;
&lt;br /&gt;
Добавим еще несколько страниц, уже не главных, для чего опять отмечаем галочкой наш домен и нажимаем плюс. В результате получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 UMI CMS - Структура сайта.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Псевдостатические адреса у страниц page1 и page2 соответственно. Мы можем посмотреть каждую из страниц http://umi.example.com/page1/ и увидим то единственное, что выдает наш шаблон - &amp;quot;It works!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Отображение на странице её содержимого ==&lt;br /&gt;
&lt;br /&gt;
Продолжаем эксперименты с шаблоном. Изменяем код шаблона следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&amp;lt;pre syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
var_dump($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И видим много интересного. В массиве содержится информация о пользователе, о элементах запроса, есть заголовок страницы, но не все поля доступны в виде элементов массива $variables. Страница целиком представлена как объект $variables['full:page']. Поэтому пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$page = $variables['full:page'];&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;&amp;lt;?= $page-&amp;gt;h1 ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;?= $page-&amp;gt;content ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И вот наконец-то по ссылке http://umi.example.com/page1/ мы видим то, что ввели при создании страницы:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-29 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
== Немного &amp;quot;причесать&amp;quot; массив $variables ==&lt;br /&gt;
&lt;br /&gt;
Поскольку UMI CMS была установлена без шаблона, то файл конфигурации не был настроен на PHP-шаблонизатор, поэтому и видим всякие 'full:page' и '@name' в качестве ключей в массиве. Можно так и тащить их по всему коду, а можно создать в папке шаблона (у нас default) файл config.ini и вставить в него 4 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[system]&lt;br /&gt;
use-php-template-data-cleaning = &amp;quot;1&amp;quot;&lt;br /&gt;
return-array-from-macros-execution = &amp;quot;1&amp;quot;&lt;br /&gt;
collapse-array-only-with-useless-key-in-data-cleaner = &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого можно будет получить более красивые ключи массива $varianles, например, $varianles['page'], это легко увидеть, вернув var_dump($varianles) в начало common.phtml.&lt;br /&gt;
&lt;br /&gt;
== Некоторые секретные возможности UMI CMS ==&lt;br /&gt;
&lt;br /&gt;
Попробуем вместо ссылки http://umi.example.com/page1/ ввести http://umi.example.com/page1/.json - круто? Это возможность, которую мы получаем прямо из коробки. Нам нет нужды делать для сайта какой-то HTML, мы можем весь сайт сделать на JS при помощи соответствующих AJAX-запросов! Или аналогичным образом сделать мобильное приложение.&lt;br /&gt;
&lt;br /&gt;
Заметим, что получаемая информация вообще не зависит от нашего шаблона. Это json-массив, формируемый методом content модуля content, аналогичный тому, что передается в шаблон в массиве $variables.&lt;br /&gt;
&lt;br /&gt;
К слову, ссылка http://umi.example.com/page1/.xml тоже работает. Кому что больше подходит.&lt;br /&gt;
&lt;br /&gt;
Не все модули отдают контент подобным образом, но все - при помощи модуля udata, ссылка будет выглядеть примерно так http://umi.example.com/udata://news/lastlist/7/.json (где 7 - это id ленты новостей, на других сайтах может быть другой).&lt;br /&gt;
&lt;br /&gt;
== Что дальше? ==&lt;br /&gt;
&lt;br /&gt;
На этом можно было бы и закончить, но конечно, этого пока недостаточно для нормального сайта, поэтому перейдем к [[Создание &amp;quot;правильного&amp;quot; шаблона для сайта|созданию &amp;quot;нормального&amp;quot; шаблона]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=338</id>
		<title>Установка UMI CMS Trial</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=338"/>
		<updated>2020-11-05T15:07:15Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
На странице https://www.umi-cms.ru/downloads/full/ нажимаем &amp;quot;Скачать&amp;quot; и получаем файл umi-cms.zip, в котором содержится единственный файл install.php.&lt;br /&gt;
&lt;br /&gt;
Можно установить систему на локальном хостинге, но я сразу установлю UMI CMS на сервере. Для этого требуется некоторая подготовка. На сервере обычно есть интерфейс для создания хостов и баз данных, в этом случае следующие 2 раздела можно пропустить. Все используемые ниже имена, конечно, надо заменить на требуемые.&lt;br /&gt;
&lt;br /&gt;
== Создаем хост umi.example.com ==&lt;br /&gt;
&lt;br /&gt;
Системные требования можно посмотреть [http://help.docs.umi-cms.ru/vvedenie/ustanovka_i_nastrojka/sistemnie_trebovaniya/ здесь].&lt;br /&gt;
&lt;br /&gt;
В них нет ничего необычного, внимательно прочесть можно будет, если не заработает. А пока заходим на свой сервер по ssh и заводим корневую директорию для нашего хоста:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd www&lt;br /&gt;
mkdir umi.example.com&lt;br /&gt;
scp имя_файла_на_локальном_компьютере имя_пользователя_на_сервере@ip_сервера:/home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где 'имя_файла_на_локальном_компьютере' - путь к распакованному файлу install.php. В зависимости от настроек конкретного сервера поддиректории хостов могут быть расположены в другом месте. Создать директорию и залить файл инсталлятора можно также, используя любой ftp или scp клиент.&lt;br /&gt;
&lt;br /&gt;
Создаем новый хост, для чего в конфигурацию Apache добавляем строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Apache&amp;quot;&amp;gt;&lt;br /&gt;
DocumentRoot /home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
ServerName umi.example.com&lt;br /&gt;
# Адрес администратора и файлы логов можно указать другие, но для начала сойдет&lt;br /&gt;
ServerAdmin admin@localhost&lt;br /&gt;
ErrorLog /var/log/apache2/error.log&lt;br /&gt;
CustomLog /var/log/apache2/access.log combined&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options +FollowSymLinks -Indexes +SymLinksIfOwnerMatch&lt;br /&gt;
&amp;lt;Directory /home/имя_пользователя_на_сервере/www/umi.example.com&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule . index.php&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options -Indexes +FollowSymLinks +SymLinksIfOwnerMatch&lt;br /&gt;
AllowOverride All&lt;br /&gt;
Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
# Это запуск Apache от имени пользователя, чтобы не париться с правами на файлы&lt;br /&gt;
&amp;lt;ifmodule mpm_itk_module&amp;gt;&lt;br /&gt;
AssignUserID имя_пользователя_на_сервере имя_группы_на_сервере&lt;br /&gt;
&amp;lt;/ifmodule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После чего не забудьте проверить правильность конфигурации и обновить конфигурацию запущенного Apache (мягкий перезапуск):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl configtest&lt;br /&gt;
apachectl -k graceful&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или, в зависимости от конкретного UNIX,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создаем базу данных umi и одноименного пользователя базы данных ==&lt;br /&gt;
&lt;br /&gt;
Имя пользователя может быть и другим. Просто мне так нравится.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE DATABASE umi;&lt;br /&gt;
CREATE USER 'umi'@'localhost' IDENTIFIED BY 'password';&lt;br /&gt;
GRANT ALL PRIVILEGES ON umi.* TO 'umi'@'localhost' WITH GRANT OPTION;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если база на другом хосте, то вместо localhost надо указать адрес хоста, например, 'db.example.com'.&lt;br /&gt;
&lt;br /&gt;
== Добавляем домен в локальный файл hosts ==&lt;br /&gt;
&lt;br /&gt;
И последний шаг. Конечно, у нас нет в собственности домена umi.example.com. Но это не значит, что мы не можем видеть свой сайт, набрав этот домен в браузере. Для этого достаточно на локальном компьютере в файле C:\Windows\System32\drivers\etc\hosts добавить строку&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
umi.example.com    IP_адрес_вашего_сервера&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Файл системный, и чтобы его поправить, редактор, скажем, Notepad, надо запускать от имени администратора.&lt;br /&gt;
&lt;br /&gt;
Если создать хост именно с таким именем, а потом прописать его локально с нужным адресом, то все ссылки, приведенные мной в дальнейшем, будут работать и у вас, только вести они будут уже на ваш сервер и сайт.&lt;br /&gt;
&lt;br /&gt;
== Запускаем инсталлятор UMI ==&lt;br /&gt;
&lt;br /&gt;
В браузере набираем адрес umi.example.com/install.php&lt;br /&gt;
&lt;br /&gt;
Если хост был настроен правильно, то увидим:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Смело жмем на &amp;quot;Получить бесплатный ключ&amp;quot;, заполняем появившуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмем &amp;quot;Далее&amp;quot;, смотрим в почту, и вводим полученный ключ в форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И - о чудо! - переходим наконец к шагу 2, где вводим доступы к нашей базе данных:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Заполняем параметры доступа к базе данных, жмем &amp;quot;Далее&amp;quot;, получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 5 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Вообще у инсталлятора есть все возможности проверить, пустая база или нет, и не заставлять нас ставить эту глупую галку, ну да ладно... После чего сидим и любуемся процессом установки. Процесс не слишком быстрый. &lt;br /&gt;
&lt;br /&gt;
В процессе установки могут возникнуть какие-либо ошибки в настройках хостинга, они подробно описаны в документации UMI CMS. Отображение всех возможных вариантов выходит за рамки этой статьи. У меня ошибок не возникло, и вот что получилось:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 6 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
По порядку:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Мои покупки&amp;quot; не рассматриваем вообще, ибо их нет. Покупать готовый шаблон мы и не планировали.&lt;br /&gt;
* &amp;quot;Бесплатные готовые решения&amp;quot; - это набор старых шаблонов на других шаблонизаторах, не PHP. Нам не подходят.&lt;br /&gt;
* &amp;quot;Демо-сайт&amp;quot; - это интересный вариант, там присутствует несколько PHP-шаблонов для разных редакций системы, написанных непосредственно разработчиками UMI CMS, хорошо документированных (в комментариях) и экономящих массу времени при разработке сайта. Но придется много копаться в чужом коде.&lt;br /&gt;
* &amp;quot;Без шаблона&amp;quot; - вот это наш вариант&lt;br /&gt;
&lt;br /&gt;
Опять любуемся на процесс установки. После чего вводим параметры нашего суперадминского доступа:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 7 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И получаем красивую картинку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot8 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмём на кнопку и - о ужас! - получаем вот это:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Ошибка Шаблон дизайна не найден.png]]&lt;br /&gt;
&lt;br /&gt;
Да, мы выбрали вариант без шаблона. Но это не значит, что должны сразу увидеть ошибку! Нажмем на ссылку, и что же? Все стало понятно?&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS ошибка 16005.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', так нельзя! Для исправления ситуации я вижу несколько путей:&lt;br /&gt;
# Создавать пустой шаблон, как это сделано во всех нормальных системах, типа надписи &amp;quot;It works!&amp;quot;&lt;br /&gt;
# Выдавать сообщение (не ошибку!), что шаблона нет, с кнопкой для перехода в админку и ссылкой на инструкцию, как этот шаблон создавать&lt;br /&gt;
# Информация о том, что шаблона нет, в инсталляторе имеется, и в этом случае давайте сразу переходить в админку в форму создания шаблона! Тем более, что админка работает и доступна по ссылке http://umi.example.com/admin/. Вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Структура сайта.png]]&lt;br /&gt;
&lt;br /&gt;
== Создаем шаблон ==&lt;br /&gt;
&lt;br /&gt;
Задача для начинающего разработчика очень сложная, и даже я сверяюсь с собственной инструкцией каждый раз при создании нового сайта. Именно поэтому создание пустого шаблона при инсталляции кажется мне очень привлекательным решением с точки зрения юзабилити.&lt;br /&gt;
&lt;br /&gt;
Самое главное: '''ни в коем случае не следуйте инструкции, предлагаемой по ссылке в сообщении об ошибке'''! -100500 в карму тому, кто ее писал!&lt;br /&gt;
&lt;br /&gt;
Заходим в админку, введя свой суперпароль, и попадаем в раздел &amp;quot;Структура&amp;quot;, который нам пока что не нужен. Вместо этого находим в левом верхнем углу бабочку и жмём не нее. В открывшейся панели выбираем &amp;quot;Шаблоны сайта&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Список модулей.png|без]]&lt;br /&gt;
&lt;br /&gt;
Шаблонов там пока нет, но над пустым списком есть черный кружок с плюсом - это волшебная кнопка создания нового шаблона. Жмём её:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Список шаблонов.png|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Список шаблонов.png]]&lt;br /&gt;
&lt;br /&gt;
И - voila! - шаблон появляется в нашем списке. Конечно, этого недостаточно, надо в директории templates/default/php/ создать файл common.phtml, например, такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще один удивительный факт: директория default создалась автоматически при создании шаблона, а вот поддиректория php - нет. '''Вопрос разработчикам''': может, стоит все это делать автоматически???&lt;br /&gt;
&lt;br /&gt;
Все сделали, находим вверху на черном фоне белую ссылку &amp;quot;На сайт&amp;quot;, жмём, и, наконец, видим что-то осмысленное:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь можно переходить непосредственно к [[Структура сайта|разработке сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=337</id>
		<title>Установка UMI CMS Trial</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=337"/>
		<updated>2020-11-05T15:04:51Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
На странице https://www.umi-cms.ru/downloads/full/ нажимаем &amp;quot;Скачать&amp;quot; и получаем файл umi-cms.zip, в котором содержится единственный файл install.php.&lt;br /&gt;
&lt;br /&gt;
Можно установить систему на локальном хостинге, но я сразу установлю UMI CMS на сервере. Для этого требуется некоторая подготовка. На сервере обычно есть интерфейс для создания хостов и баз данных, в этом случае следующие 2 раздела можно пропустить. Все используемые ниже имена, конечно, надо заменить на требуемые.&lt;br /&gt;
&lt;br /&gt;
== Создаем хост umi.example.com ==&lt;br /&gt;
&lt;br /&gt;
Системные требования можно посмотреть [http://help.docs.umi-cms.ru/vvedenie/ustanovka_i_nastrojka/sistemnie_trebovaniya/ здесь].&lt;br /&gt;
&lt;br /&gt;
В них нет ничего необычного, внимательно прочесть можно будет, если не заработает. А пока заходим на свой сервер по ssh и заводим корневую директорию для нашего хоста:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
cd www&lt;br /&gt;
mkdir umi.example.com&lt;br /&gt;
scp имя_файла_на_локальном_компьютере имя_пользователя_на_сервере@ip_сервера:/home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где 'имя_файла_на_локальном_компьютере' - путь к распакованному файлу install.php. В зависимости от настроек конкретного сервера поддиректории хостов могут быть расположены в другом месте. Создать директорию и залить файл инсталлятора можно также, используя любой ftp или scp клиент.&lt;br /&gt;
&lt;br /&gt;
Создаем новый хост, для чего в конфигурацию Apache добавляем строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Apache&amp;quot;&amp;gt;&lt;br /&gt;
DocumentRoot /home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
ServerName umi.example.com&lt;br /&gt;
# Адрес администратора и файлы логов можно указать другие, но для начала сойдет&lt;br /&gt;
ServerAdmin admin@localhost&lt;br /&gt;
ErrorLog /var/log/apache2/error.log&lt;br /&gt;
CustomLog /var/log/apache2/access.log combined&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options +FollowSymLinks -Indexes +SymLinksIfOwnerMatch&lt;br /&gt;
&amp;lt;Directory /home/имя_пользователя_на_сервере/www/umi.example.com&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule . index.php&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options -Indexes +FollowSymLinks +SymLinksIfOwnerMatch&lt;br /&gt;
AllowOverride All&lt;br /&gt;
Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
# Это запуск Apache от имени пользователя, чтобы не париться с правами на файлы&lt;br /&gt;
&amp;lt;ifmodule mpm_itk_module&amp;gt;&lt;br /&gt;
AssignUserID имя_пользователя_на_сервере имя_группы_на_сервере&lt;br /&gt;
&amp;lt;/ifmodule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После чего не забудьте проверить правильность конфигурации и обновить конфигурацию запущенного Apache (мягкий перезапуск):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
apachectl configtest&lt;br /&gt;
apachectl -k graceful&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или, в зависимости от конкретного UNIX,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создаем базу данных umi и одноименного пользователя базы данных ==&lt;br /&gt;
&lt;br /&gt;
Имя пользователя может быть и другим. Просто мне так нравится.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE DATABASE umi;&lt;br /&gt;
CREATE USER 'umi'@'localhost' IDENTIFIED BY 'password';&lt;br /&gt;
GRANT ALL PRIVILEGES ON umi.* TO 'umi'@'localhost' WITH GRANT OPTION;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если база на другом хосте, то вместо localhost надо указать адрес хоста, например, 'db.example.com'.&lt;br /&gt;
&lt;br /&gt;
== Добавляем домен в локальный файл hosts ==&lt;br /&gt;
&lt;br /&gt;
И последний шаг. Конечно, у нас нет в собственности домена umi.example.com. Но это не значит, что мы не можем видеть свой сайт, набрав этот домен в браузере. Для этого достаточно на локальном компьютере в файле C:\Windows\System32\drivers\etc\hosts добавить строку&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
umi.example.com    IP_адрес_вашего_сервера&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Файл системный, и чтобы его поправить, редактор, скажем, Notepad, надо запускать от имени администратора.&lt;br /&gt;
&lt;br /&gt;
Если создать хост именно с таким именем, а потом прописать его локально с нужным адресом, то все ссылки, приведенные мной в дальнейшем, будут работать и у вас, только вести они будут уже на ваш сервер и сайт.&lt;br /&gt;
&lt;br /&gt;
== Запускаем инсталлятор UMI ==&lt;br /&gt;
&lt;br /&gt;
В браузере набираем адрес umi.example.com/install.php&lt;br /&gt;
&lt;br /&gt;
Если хост был настроен правильно, то увидим:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Смело жмем на &amp;quot;Получить бесплатный ключ&amp;quot;, заполняем появившуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмем &amp;quot;Далее&amp;quot;, смотрим в почту, и вводим полученный ключ в форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И - о чудо! - переходим наконец к шагу 2, где вводим доступы к нашей базе данных:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Заполняем параметры доступа к базе данных, жмем &amp;quot;Далее&amp;quot;, получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 5 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Вообще у инсталлятора есть все возможности проверить, пустая база или нет, и не заставлять нас ставить эту глупую галку, ну да ладно... После чего сидим и любуемся процессом установки. Процесс не слишком быстрый. &lt;br /&gt;
&lt;br /&gt;
В процессе установки могут возникнуть какие-либо ошибки в настройках хостинга, они подробно описаны в документации UMI CMS. Отображение всех возможных вариантов выходит за рамки этой статьи. У меня ошибок не возникло, и вот что получилось:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 6 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
По порядку:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Мои покупки&amp;quot; не рассматриваем вообще, ибо их нет. Покупать готовый шаблон мы и не планировали.&lt;br /&gt;
* &amp;quot;Бесплатные готовые решения&amp;quot; - это набор старых шаблонов на других шаблонизаторах, не PHP. Нам не подходят.&lt;br /&gt;
* &amp;quot;Демо-сайт&amp;quot; - это интересный вариант, там присутствует несколько PHP-шаблонов для разных редакций системы, написанных непосредственно разработчиками UMI CMS, хорошо документированных (в комментариях) и экономящих массу времени при разработке сайта. Но придется много копаться в чужом коде.&lt;br /&gt;
* &amp;quot;Без шаблона&amp;quot; - вот это наш вариант&lt;br /&gt;
&lt;br /&gt;
Опять любуемся на процесс установки. После чего вводим параметры нашего суперадминского доступа:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 7 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И получаем красивую картинку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot8 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмём на кнопку и - о ужас! - получаем вот это:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Ошибка Шаблон дизайна не найден.png]]&lt;br /&gt;
&lt;br /&gt;
Да, мы выбрали вариант без шаблона. Но это не значит, что должны сразу увидеть ошибку! Нажмем на ссылку, и что же? Все стало понятно?&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS ошибка 16005.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', так нельзя! Для исправления ситуации я вижу несколько путей:&lt;br /&gt;
# Создавать пустой шаблон, как это сделано во всех нормальных системах, типа надписи &amp;quot;It works!&amp;quot;&lt;br /&gt;
# Выдавать сообщение (не ошибку!), что шаблона нет, с кнопкой для перехода в админку и ссылкой на инструкцию, как этот шаблон создавать&lt;br /&gt;
# Информация о том, что шаблона нет, в инсталляторе имеется, и в этом случае давайте сразу переходить в админку в форму создания шаблона! Тем более, что админка работает и доступна по ссылке http://umi.example.com/admin/. Вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Структура сайта.png]]&lt;br /&gt;
&lt;br /&gt;
== Создаем шаблон ==&lt;br /&gt;
&lt;br /&gt;
Задача для начинающего разработчика очень сложная, и даже я сверяюсь с собственной инструкцией каждый раз при создании нового сайта. Именно поэтому создание пустого шаблона при инсталляции кажется мне очень привлекательным решением с точки зрения юзабилити.&lt;br /&gt;
&lt;br /&gt;
Самое главное: '''ни в коем случае не следуйте инструкции, предлагаемой по ссылке в сообщении об ошибке'''! -100500 в карму тому, кто ее писал!&lt;br /&gt;
&lt;br /&gt;
Заходим в админку, введя свой суперпароль, и попадаем в раздел &amp;quot;Структура&amp;quot;, который нам пока что не нужен. Вместо этого находим в левом верхнем углу бабочку и жмём не нее. В открывшейся панели выбираем &amp;quot;Шаблоны сайта&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Список модулей.png|без]]&lt;br /&gt;
&lt;br /&gt;
Шаблонов там пока нет, но над пустым списком есть черный кружок с плюсом - это волшебная кнопка создания нового шаблона. Жмём её:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Список шаблонов.png|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Список шаблонов.png]]&lt;br /&gt;
&lt;br /&gt;
И - voila! - шаблон появляется в нашем списке. Конечно, этого недостаточно, надо в директории templates/default/php/ создать файл common.phtml, например, такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще один удивительный факт: директория default создалась автоматически при создании шаблона, а вот поддиректория php - нет. '''Вопрос разработчикам''': может, стоит все это делать автоматически???&lt;br /&gt;
&lt;br /&gt;
Все сделали, находим вверху на черном фоне белую ссылку &amp;quot;На сайт&amp;quot;, жмём, и, наконец, видим что-то осмысленное:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь можно переходить непосредственно к [[Структура сайта|разработке сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=336</id>
		<title>Установка UMI CMS Trial</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=336"/>
		<updated>2020-11-05T15:03:52Z</updated>

		<summary type="html">&lt;p&gt;Olga: /* Создаем хост umi.example.com */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
На странице https://www.umi-cms.ru/downloads/full/ нажимаем &amp;quot;Скачать&amp;quot; и получаем файл umi-cms.zip, в котором содержится единственный файл install.php.&lt;br /&gt;
&lt;br /&gt;
Можно установить систему на локальном хостинге, но я сразу установлю UMI CMS на сервере. Для этого требуется некоторая подготовка. На сервере обычно есть интерфейс для создания хостов и баз данных, в этом случае следующие 2 раздела можно пропустить. Все используемые ниже имена, конечно, надо заменить на требуемые.&lt;br /&gt;
&lt;br /&gt;
== Создаем хост umi.example.com ==&lt;br /&gt;
&lt;br /&gt;
Системные требования можно посмотреть [http://help.docs.umi-cms.ru/vvedenie/ustanovka_i_nastrojka/sistemnie_trebovaniya/ здесь].&lt;br /&gt;
&lt;br /&gt;
В них нет ничего необычного, внимательно прочесть можно будет, если не заработает. А пока заходим на свой сервер по ssh и заводим корневую директорию для нашего хоста:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
cd www&lt;br /&gt;
mkdir umi.example.com&lt;br /&gt;
scp имя_файла_на_локальном_компьютере имя_пользователя_на_сервере@ip_сервера:/home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где 'имя_файла_на_локальном_компьютере' - путь к распакованному файлу install.php. В зависимости от настроек конкретного сервера поддиректории хостов могут быть расположены в другом месте. Создать директорию и залить файл инсталлятора можно также, используя любой ftp или scp клиент.&lt;br /&gt;
&lt;br /&gt;
Создаем новый хост, для чего в конфигурацию Apache добавляем строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Apache&amp;quot;&amp;gt;&lt;br /&gt;
DocumentRoot /home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
ServerName umi.example.com&lt;br /&gt;
# Адрес администратора и файлы логов можно указать другие, но для начала сойдет&lt;br /&gt;
ServerAdmin admin@localhost&lt;br /&gt;
ErrorLog /var/log/apache2/error.log&lt;br /&gt;
CustomLog /var/log/apache2/access.log combined&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options +FollowSymLinks -Indexes +SymLinksIfOwnerMatch&lt;br /&gt;
&amp;lt;Directory /home/имя_пользователя_на_сервере/www/umi.example.com&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule . index.php&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options -Indexes +FollowSymLinks +SymLinksIfOwnerMatch&lt;br /&gt;
AllowOverride All&lt;br /&gt;
Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
# Это запуск Apache от имени пользователя, чтобы не париться с правами на файлы&lt;br /&gt;
&amp;lt;ifmodule mpm_itk_module&amp;gt;&lt;br /&gt;
AssignUserID имя_пользователя_на_сервере имя_группы_на_сервере&lt;br /&gt;
&amp;lt;/ifmodule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После чего не забудьте проверить правильность конфигурации и обновить конфигурацию запущенного Apache (мягкий перезапуск):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
apachectl configtest&lt;br /&gt;
apachectl -k graceful&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или, в зависимости от конкретного UNIX,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создаем базу данных umi и одноименного пользователя базы данных ==&lt;br /&gt;
&lt;br /&gt;
Имя пользователя может быть и другим. Просто мне так нравится.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE DATABASE umi;&lt;br /&gt;
CREATE USER 'umi'@'localhost' IDENTIFIED BY 'password';&lt;br /&gt;
GRANT ALL PRIVILEGES ON umi.* TO 'umi'@'localhost' WITH GRANT OPTION;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если база на другом хосте, то вместо localhost надо указать адрес хоста, например, 'db.example.com'.&lt;br /&gt;
&lt;br /&gt;
== Добавляем домен в локальный файл hosts ==&lt;br /&gt;
&lt;br /&gt;
И последний шаг. Конечно, у нас нет в собственности домена umi.example.com. Но это не значит, что мы не можем видеть свой сайт, набрав этот домен в браузере. Для этого достаточно на локальном компьютере в файле C:\Windows\System32\drivers\etc\hosts добавить строку&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
umi.example.com    IP_адрес_вашего_сервера&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Файл системный, и чтобы его поправить, редактор, скажем, Notepad, надо запускать от имени администратора.&lt;br /&gt;
&lt;br /&gt;
Если создать хост именно с таким именем, а потом прописать его локально с нужным адресом, то все ссылки, приведенные мной в дальнейшем, будут работать и у вас, только вести они будут уже на ваш сервер и сайт.&lt;br /&gt;
&lt;br /&gt;
== Запускаем инсталлятор UMI ==&lt;br /&gt;
&lt;br /&gt;
В браузере набираем адрес umi.example.com/install.php&lt;br /&gt;
&lt;br /&gt;
Если хост был настроен правильно, то увидим:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Смело жмем на &amp;quot;Получить бесплатный ключ&amp;quot;, заполняем появившуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмем &amp;quot;Далее&amp;quot;, смотрим в почту, и вводим полученный ключ в форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И - о чудо! - переходим наконец к шагу 2, где вводим доступы к нашей базе данных:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Заполняем параметры доступа к базе данных, жмем &amp;quot;Далее&amp;quot;, получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 5 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Вообще у инсталлятора есть все возможности проверить, пустая база или нет, и не заставлять нас ставить эту глупую галку, ну да ладно... После чего сидим и любуемся процессом установки. Процесс не слишком быстрый. &lt;br /&gt;
&lt;br /&gt;
В процессе установки могут возникнуть какие-либо ошибки в настройках хостинга, они подробно описаны в документации UMI CMS. Отображение всех возможных вариантов выходит за рамки этой статьи. У меня ошибок не возникло, и вот что получилось:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 6 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
По порядку:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Мои покупки&amp;quot; не рассматриваем вообще, ибо их нет. Покупать готовый шаблон мы и не планировали.&lt;br /&gt;
* &amp;quot;Бесплатные готовые решения&amp;quot; - это набор старых шаблонов на других шаблонизаторах, не PHP. Нам не подходят.&lt;br /&gt;
* &amp;quot;Демо-сайт&amp;quot; - это интересный вариант, там присутствует несколько PHP-шаблонов для разных редакций системы, написанных непосредственно разработчиками UMI CMS, хорошо документированных (в комментариях) и экономящих массу времени при разработке сайта. Но придется много копаться в чужом коде.&lt;br /&gt;
* &amp;quot;Без шаблона&amp;quot; - вот это наш вариант&lt;br /&gt;
&lt;br /&gt;
Опять любуемся на процесс установки. После чего вводим параметры нашего суперадминского доступа:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 7 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И получаем красивую картинку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot8 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмём на кнопку и - о ужас! - получаем вот это:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Ошибка Шаблон дизайна не найден.png]]&lt;br /&gt;
&lt;br /&gt;
Да, мы выбрали вариант без шаблона. Но это не значит, что должны сразу увидеть ошибку! Нажмем на ссылку, и что же? Все стало понятно?&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS ошибка 16005.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', так нельзя! Для исправления ситуации я вижу несколько путей:&lt;br /&gt;
# Создавать пустой шаблон, как это сделано во всех нормальных системах, типа надписи &amp;quot;It works!&amp;quot;&lt;br /&gt;
# Выдавать сообщение (не ошибку!), что шаблона нет, с кнопкой для перехода в админку и ссылкой на инструкцию, как этот шаблон создавать&lt;br /&gt;
# Информация о том, что шаблона нет, в инсталляторе имеется, и в этом случае давайте сразу переходить в админку в форму создания шаблона! Тем более, что админка работает и доступна по ссылке http://umi.example.com/admin/. Вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Структура сайта.png]]&lt;br /&gt;
&lt;br /&gt;
== Создаем шаблон ==&lt;br /&gt;
&lt;br /&gt;
Задача для начинающего разработчика очень сложная, и даже я сверяюсь с собственной инструкцией каждый раз при создании нового сайта. Именно поэтому создание пустого шаблона при инсталляции кажется мне очень привлекательным решением с точки зрения юзабилити.&lt;br /&gt;
&lt;br /&gt;
Самое главное: '''ни в коем случае не следуйте инструкции, предлагаемой по ссылке в сообщении об ошибке'''! -100500 в карму тому, кто ее писал!&lt;br /&gt;
&lt;br /&gt;
Заходим в админку, введя свой суперпароль, и попадаем в раздел &amp;quot;Структура&amp;quot;, который нам пока что не нужен. Вместо этого находим в левом верхнем углу бабочку и жмём не нее. В открывшейся панели выбираем &amp;quot;Шаблоны сайта&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Список модулей.png|без]]&lt;br /&gt;
&lt;br /&gt;
Шаблонов там пока нет, но над пустым списком есть черный кружок с плюсом - это волшебная кнопка создания нового шаблона. Жмём её:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Список шаблонов.png|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Список шаблонов.png]]&lt;br /&gt;
&lt;br /&gt;
И - voila! - шаблон появляется в нашем списке. Конечно, этого недостаточно, надо в директории templates/default/php/ создать файл common.phtml, например, такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще один удивительный факт: директория default создалась автоматически при создании шаблона, а вот поддиректория php - нет. '''Вопрос разработчикам''': может, стоит все это делать автоматически???&lt;br /&gt;
&lt;br /&gt;
Все сделали, находим вверху на черном фоне белую ссылку &amp;quot;На сайт&amp;quot;, жмём, и, наконец, видим что-то осмысленное:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь можно переходить непосредственно к [[Структура сайта|разработке сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=335</id>
		<title>Установка UMI CMS Trial</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=335"/>
		<updated>2020-11-05T15:03:19Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
На странице https://www.umi-cms.ru/downloads/full/ нажимаем &amp;quot;Скачать&amp;quot; и получаем файл umi-cms.zip, в котором содержится единственный файл install.php.&lt;br /&gt;
&lt;br /&gt;
Можно установить систему на локальном хостинге, но я сразу установлю UMI CMS на сервере. Для этого требуется некоторая подготовка. На сервере обычно есть интерфейс для создания хостов и баз данных, в этом случае следующие 2 раздела можно пропустить. Все используемые ниже имена, конечно, надо заменить на требуемые.&lt;br /&gt;
&lt;br /&gt;
== Создаем хост umi.example.com ==&lt;br /&gt;
&lt;br /&gt;
Системные требования можно посмотреть [http://help.docs.umi-cms.ru/vvedenie/ustanovka_i_nastrojka/sistemnie_trebovaniya/ здесь].&lt;br /&gt;
&lt;br /&gt;
В них нет ничего необычного, внимательно прочесть можно будет, если не заработает. А пока заходим на свой сервер по ssh и заводим корневую директорию для нашего хоста:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
cd www&lt;br /&gt;
mkdir umi.example.com&lt;br /&gt;
scp имя_файла_на_локальном_компьютере имя_пользователя_на_сервере@ip_сервера:/home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где 'имя_файла_на_локальном_компьютере' - путь к распакованному файлу install.php. В зависимости от настроек конкретного сервера поддиректории хостов могут быть расположены в другом месте. Создать директорию и залить файл инсталлятора можно также, используя любой ftp или scp клиент.&lt;br /&gt;
&lt;br /&gt;
Создаем новый хост, для чего в конфигурацию Apache добавляем строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Apache&amp;quot;&amp;gt;&lt;br /&gt;
DocumentRoot /home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
ServerName umi.example.com&lt;br /&gt;
# Адрес администратора и файлы логов можно указать другие, но для начала сойдет&lt;br /&gt;
ServerAdmin admin@localhost&lt;br /&gt;
ErrorLog /var/log/apache2/error.log&lt;br /&gt;
CustomLog /var/log/apache2/access.log combined&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options +FollowSymLinks -Indexes +SymLinksIfOwnerMatch&lt;br /&gt;
&amp;lt;Directory /home/имя_пользователя_на_сервере/www/umi.example.com&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule . index.php&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options -Indexes +FollowSymLinks +SymLinksIfOwnerMatch&lt;br /&gt;
AllowOverride All&lt;br /&gt;
Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
# Это запуск Apache от имени пользователя, чтобы не париться с правами на файлы&lt;br /&gt;
&amp;lt;ifmodule mpm_itk_module&amp;gt;&lt;br /&gt;
AssignUserID имя_пользователя_на_сервере имя_группы_на_сервере&lt;br /&gt;
&amp;lt;/ifmodule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После чего не забудьте проверить правильность конфигурации и обновить конфигурацию запущенного Apache (мягкий перезапуск):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl configtest&lt;br /&gt;
apachectl -k graceful&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или, в зависимости от конкретного UNIX,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создаем базу данных umi и одноименного пользователя базы данных ==&lt;br /&gt;
&lt;br /&gt;
Имя пользователя может быть и другим. Просто мне так нравится.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE DATABASE umi;&lt;br /&gt;
CREATE USER 'umi'@'localhost' IDENTIFIED BY 'password';&lt;br /&gt;
GRANT ALL PRIVILEGES ON umi.* TO 'umi'@'localhost' WITH GRANT OPTION;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если база на другом хосте, то вместо localhost надо указать адрес хоста, например, 'db.example.com'.&lt;br /&gt;
&lt;br /&gt;
== Добавляем домен в локальный файл hosts ==&lt;br /&gt;
&lt;br /&gt;
И последний шаг. Конечно, у нас нет в собственности домена umi.example.com. Но это не значит, что мы не можем видеть свой сайт, набрав этот домен в браузере. Для этого достаточно на локальном компьютере в файле C:\Windows\System32\drivers\etc\hosts добавить строку&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
umi.example.com    IP_адрес_вашего_сервера&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Файл системный, и чтобы его поправить, редактор, скажем, Notepad, надо запускать от имени администратора.&lt;br /&gt;
&lt;br /&gt;
Если создать хост именно с таким именем, а потом прописать его локально с нужным адресом, то все ссылки, приведенные мной в дальнейшем, будут работать и у вас, только вести они будут уже на ваш сервер и сайт.&lt;br /&gt;
&lt;br /&gt;
== Запускаем инсталлятор UMI ==&lt;br /&gt;
&lt;br /&gt;
В браузере набираем адрес umi.example.com/install.php&lt;br /&gt;
&lt;br /&gt;
Если хост был настроен правильно, то увидим:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Смело жмем на &amp;quot;Получить бесплатный ключ&amp;quot;, заполняем появившуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмем &amp;quot;Далее&amp;quot;, смотрим в почту, и вводим полученный ключ в форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И - о чудо! - переходим наконец к шагу 2, где вводим доступы к нашей базе данных:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Заполняем параметры доступа к базе данных, жмем &amp;quot;Далее&amp;quot;, получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 5 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Вообще у инсталлятора есть все возможности проверить, пустая база или нет, и не заставлять нас ставить эту глупую галку, ну да ладно... После чего сидим и любуемся процессом установки. Процесс не слишком быстрый. &lt;br /&gt;
&lt;br /&gt;
В процессе установки могут возникнуть какие-либо ошибки в настройках хостинга, они подробно описаны в документации UMI CMS. Отображение всех возможных вариантов выходит за рамки этой статьи. У меня ошибок не возникло, и вот что получилось:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 6 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
По порядку:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Мои покупки&amp;quot; не рассматриваем вообще, ибо их нет. Покупать готовый шаблон мы и не планировали.&lt;br /&gt;
* &amp;quot;Бесплатные готовые решения&amp;quot; - это набор старых шаблонов на других шаблонизаторах, не PHP. Нам не подходят.&lt;br /&gt;
* &amp;quot;Демо-сайт&amp;quot; - это интересный вариант, там присутствует несколько PHP-шаблонов для разных редакций системы, написанных непосредственно разработчиками UMI CMS, хорошо документированных (в комментариях) и экономящих массу времени при разработке сайта. Но придется много копаться в чужом коде.&lt;br /&gt;
* &amp;quot;Без шаблона&amp;quot; - вот это наш вариант&lt;br /&gt;
&lt;br /&gt;
Опять любуемся на процесс установки. После чего вводим параметры нашего суперадминского доступа:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 7 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И получаем красивую картинку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot8 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмём на кнопку и - о ужас! - получаем вот это:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Ошибка Шаблон дизайна не найден.png]]&lt;br /&gt;
&lt;br /&gt;
Да, мы выбрали вариант без шаблона. Но это не значит, что должны сразу увидеть ошибку! Нажмем на ссылку, и что же? Все стало понятно?&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS ошибка 16005.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', так нельзя! Для исправления ситуации я вижу несколько путей:&lt;br /&gt;
# Создавать пустой шаблон, как это сделано во всех нормальных системах, типа надписи &amp;quot;It works!&amp;quot;&lt;br /&gt;
# Выдавать сообщение (не ошибку!), что шаблона нет, с кнопкой для перехода в админку и ссылкой на инструкцию, как этот шаблон создавать&lt;br /&gt;
# Информация о том, что шаблона нет, в инсталляторе имеется, и в этом случае давайте сразу переходить в админку в форму создания шаблона! Тем более, что админка работает и доступна по ссылке http://umi.example.com/admin/. Вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Структура сайта.png]]&lt;br /&gt;
&lt;br /&gt;
== Создаем шаблон ==&lt;br /&gt;
&lt;br /&gt;
Задача для начинающего разработчика очень сложная, и даже я сверяюсь с собственной инструкцией каждый раз при создании нового сайта. Именно поэтому создание пустого шаблона при инсталляции кажется мне очень привлекательным решением с точки зрения юзабилити.&lt;br /&gt;
&lt;br /&gt;
Самое главное: '''ни в коем случае не следуйте инструкции, предлагаемой по ссылке в сообщении об ошибке'''! -100500 в карму тому, кто ее писал!&lt;br /&gt;
&lt;br /&gt;
Заходим в админку, введя свой суперпароль, и попадаем в раздел &amp;quot;Структура&amp;quot;, который нам пока что не нужен. Вместо этого находим в левом верхнем углу бабочку и жмём не нее. В открывшейся панели выбираем &amp;quot;Шаблоны сайта&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Список модулей.png|без]]&lt;br /&gt;
&lt;br /&gt;
Шаблонов там пока нет, но над пустым списком есть черный кружок с плюсом - это волшебная кнопка создания нового шаблона. Жмём её:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Список шаблонов.png|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Список шаблонов.png]]&lt;br /&gt;
&lt;br /&gt;
И - voila! - шаблон появляется в нашем списке. Конечно, этого недостаточно, надо в директории templates/default/php/ создать файл common.phtml, например, такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще один удивительный факт: директория default создалась автоматически при создании шаблона, а вот поддиректория php - нет. '''Вопрос разработчикам''': может, стоит все это делать автоматически???&lt;br /&gt;
&lt;br /&gt;
Все сделали, находим вверху на черном фоне белую ссылку &amp;quot;На сайт&amp;quot;, жмём, и, наконец, видим что-то осмысленное:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь можно переходить непосредственно к [[Структура сайта|разработке сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=334</id>
		<title>Установка UMI CMS Trial</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=334"/>
		<updated>2020-11-05T14:49:35Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
На странице https://www.umi-cms.ru/downloads/full/ нажимаем &amp;quot;Скачать&amp;quot; и получаем файл umi-cms.zip, в котором содержится единственный файл install.php.&lt;br /&gt;
&lt;br /&gt;
Можно установить систему на локальном хостинге, но я сразу установлю UMI CMS на сервере. Для этого требуется некоторая подготовка. На сервере обычно есть интерфейс для создания хостов и баз данных, в этом случае следующие 2 раздела можно пропустить. Все используемые ниже имена, конечно, надо заменить на требуемые.&lt;br /&gt;
&lt;br /&gt;
== Создаем хост umi.example.com ==&lt;br /&gt;
&lt;br /&gt;
Системные требования можно посмотреть [http://help.docs.umi-cms.ru/vvedenie/ustanovka_i_nastrojka/sistemnie_trebovaniya/ здесь].&lt;br /&gt;
&lt;br /&gt;
В них нет ничего необычного, внимательно прочесть можно будет, если не заработает. А пока заходим на свой сервер по ssh и заводим корневую директорию для нашего хоста:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
cd www&lt;br /&gt;
mkdir umi.example.com&lt;br /&gt;
scp имя_файла_на_локальном_компьютере имя_пользователя_на_сервере@ip_сервера:/home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где 'имя_файла_на_локальном_компьютере' - путь к распакованному файлу install.php. В зависимости от настроек конкретного сервера поддиректории хостов могут быть расположены в другом месте. Создать директорию и залить файл инсталлятора можно также, используя любой ftp или scp клиент.&lt;br /&gt;
&lt;br /&gt;
Создаем новый хост, для чего в конфигурацию Apache добавляем строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Apache&amp;quot;&amp;gt;&lt;br /&gt;
DocumentRoot /home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
ServerName umi.example.com&lt;br /&gt;
# Адрес администратора и файлы логов можно указать другие, но для начала сойдет&lt;br /&gt;
ServerAdmin admin@localhost&lt;br /&gt;
ErrorLog /var/log/apache2/error.log&lt;br /&gt;
CustomLog /var/log/apache2/access.log combined&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options +FollowSymLinks -Indexes +SymLinksIfOwnerMatch&lt;br /&gt;
&amp;lt;Directory /home/имя_пользователя_на_сервере/www/umi.example.com&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule . index.php&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options -Indexes +FollowSymLinks +SymLinksIfOwnerMatch&lt;br /&gt;
AllowOverride All&lt;br /&gt;
Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
# Это запуск Apache от имени пользователя, чтобы не париться с правами на файлы&lt;br /&gt;
&amp;lt;ifmodule mpm_itk_module&amp;gt;&lt;br /&gt;
AssignUserID имя_пользователя_на_сервере имя_группы_на_сервере&lt;br /&gt;
&amp;lt;/ifmodule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После чего не забудьте проверить правильность конфигурации и обновить конфигурацию запущенного Apache (мягкий перезапуск):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl configtest&lt;br /&gt;
apachectl -k graceful&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или, в зависимости от конкретного UNIX,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создаем базу данных umi и одноименного пользователя базы данных ==&lt;br /&gt;
&lt;br /&gt;
Имя пользователя может быть и другим. Просто мне так нравится.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE DATABASE umi;&lt;br /&gt;
CREATE USER 'umi'@'localhost' IDENTIFIED BY 'password';&lt;br /&gt;
GRANT ALL PRIVILEGES ON umi.* TO 'umi'@'localhost' WITH GRANT OPTION;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если база на другом хосте, то вместо localhost надо указать адрес хоста, например, 'db.example.com'.&lt;br /&gt;
&lt;br /&gt;
== Добавляем домен в локальный файл hosts ==&lt;br /&gt;
&lt;br /&gt;
И последний шаг. Конечно, у нас нет в собственности домена umi.example.com. Но это не значит, что мы не можем видеть свой сайт, набрав этот домен в браузере. Для этого достаточно на локальном компьютере в файле C:\Windows\System32\drivers\etc\hosts добавить строку&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
umi.example.com    IP_адрес_вашего_сервера&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Файл системный, и чтобы его поправить, редактор, скажем, Notepad, надо запускать от имени администратора.&lt;br /&gt;
&lt;br /&gt;
Если создать хост именно с таким именем, а потом прописать его локально с нужным адресом, то все ссылки, приведенные мной в дальнейшем, будут работать и у вас, только вести они будут уже на ваш сервер и сайт.&lt;br /&gt;
&lt;br /&gt;
== Запускаем инсталлятор UMI ==&lt;br /&gt;
&lt;br /&gt;
В браузере набираем адрес umi.example.com/install.php&lt;br /&gt;
&lt;br /&gt;
Если хост был настроен правильно, то увидим:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Смело жмем на &amp;quot;Получить бесплатный ключ&amp;quot;, заполняем появившуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмем &amp;quot;Далее&amp;quot;, смотрим в почту, и вводим полученный ключ в форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И - о чудо! - переходим наконец к шагу 2, где вводим доступы к нашей базе данных:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Заполняем параметры доступа к базе данных, жмем &amp;quot;Далее&amp;quot;, получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 5 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Вообще у инсталлятора есть все возможности проверить, пустая база или нет, и не заставлять нас ставить эту глупую галку, ну да ладно... После чего сидим и любуемся процессом установки. Процесс не слишком быстрый. &lt;br /&gt;
&lt;br /&gt;
В процессе установки могут возникнуть какие-либо ошибки в настройках хостинга, они подробно описаны в документации UMI CMS. Отображение всех возможных вариантов выходит за рамки этой статьи. У меня ошибок не возникло, и вот что получилось:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 6 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
По порядку:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Мои покупки&amp;quot; не рассматриваем вообще, ибо их нет. Покупать готовый шаблон мы и не планировали.&lt;br /&gt;
* &amp;quot;Бесплатные готовые решения&amp;quot; - это набор старых шаблонов на других шаблонизаторах, не PHP. Нам не подходят.&lt;br /&gt;
* &amp;quot;Демо-сайт&amp;quot; - это интересный вариант, там присутствует несколько PHP-шаблонов для разных редакций системы, написанных непосредственно разработчиками UMI CMS, хорошо документированных (в комментариях) и экономящих массу времени при разработке сайта. Но придется много копаться в чужом коде.&lt;br /&gt;
* &amp;quot;Без шаблона&amp;quot; - вот это наш вариант&lt;br /&gt;
&lt;br /&gt;
Опять любуемся на процесс установки. После чего вводим параметры нашего суперадминского доступа:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 7 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И получаем красивую картинку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot8 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмём на кнопку и - о ужас! - получаем вот это:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Ошибка Шаблон дизайна не найден.png]]&lt;br /&gt;
&lt;br /&gt;
Да, мы выбрали вариант без шаблона. Но это не значит, что должны сразу увидеть ошибку! Нажмем на ссылку, и что же? Все стало понятно?&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS ошибка 16005.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', так нельзя! Для исправления ситуации я вижу несколько путей:&lt;br /&gt;
# Создавать пустой шаблон, как это сделано во всех нормальных системах, типа надписи &amp;quot;It works!&amp;quot;&lt;br /&gt;
# Выдавать сообщение (не ошибку!), что шаблона нет, с кнопкой для перехода в админку и ссылкой на инструкцию, как этот шаблон создавать&lt;br /&gt;
# Информация о том, что шаблона нет, в инсталляторе имеется, и в этом случае давайте сразу переходить в админку в форму создания шаблона! Тем более, что админка работает и доступна по ссылке http://umi.example.com/admin/. Вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Структура сайта.png]]&lt;br /&gt;
&lt;br /&gt;
== Создаем шаблон ==&lt;br /&gt;
&lt;br /&gt;
Задача для начинающего разработчика очень сложная, и даже я сверяюсь с собственной инструкцией каждый раз при создании нового сайта. Именно поэтому создание пустого шаблона при инсталляции кажется мне очень привлекательным решением с точки зрения юзабилити.&lt;br /&gt;
&lt;br /&gt;
Самое главное: '''ни в коем случае не следуйте инструкции, предлагаемой по ссылке в сообщении об ошибке'''! -100500 в карму тому, кто ее писал!&lt;br /&gt;
&lt;br /&gt;
Заходим в админку, введя свой суперпароль, и попадаем в раздел &amp;quot;Структура&amp;quot;, который нам пока что не нужен. Вместо этого находим в левом верхнем углу бабочку и жмём не нее. В открывшейся панели выбираем &amp;quot;Шаблоны сайта&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Список модулей.png|без]]&lt;br /&gt;
&lt;br /&gt;
Шаблонов там пока нет, но над пустым списком есть черный кружок с плюсом - это волшебная кнопка создания нового шаблона. Жмём её:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Список шаблонов.png|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Список шаблонов.png]]&lt;br /&gt;
&lt;br /&gt;
И - voila! - шаблон появляется в нашем списке. Конечно, этого недостаточно, надо в директории templates/default/php/ создать файл common.phtml, например, такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще один удивительный факт: директория default создалась автоматически при создании шаблона, а вот поддиректория php - нет. '''Вопрос разработчикам''': может, стоит все это делать автоматически???&lt;br /&gt;
&lt;br /&gt;
Все сделали, находим вверху на черном фоне белую ссылку &amp;quot;На сайт&amp;quot;, жмём, и, наконец, видим что-то осмысленное:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь можно переходить непосредственно к [[Структура сайта|разработке сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=333</id>
		<title>Установка UMI CMS Trial</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=333"/>
		<updated>2020-11-05T14:48:21Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
На странице https://www.umi-cms.ru/downloads/full/ нажимаем &amp;quot;Скачать&amp;quot; и получаем файл umi-cms.zip, в котором содержится единственный файл install.php.&lt;br /&gt;
&lt;br /&gt;
Можно установить систему на локальном хостинге, но я сразу установлю UMI CMS на сервере. Для этого требуется некоторая подготовка. На сервере обычно есть интерфейс для создания хостов и баз данных, в этом случае следующие 2 раздела можно пропустить. Все используемые ниже имена, конечно, надо заменить на требуемые.&lt;br /&gt;
&lt;br /&gt;
== Создаем хост umi.example.com ==&lt;br /&gt;
&lt;br /&gt;
Системные требования можно посмотреть [http://help.docs.umi-cms.ru/vvedenie/ustanovka_i_nastrojka/sistemnie_trebovaniya/ здесь].&lt;br /&gt;
&lt;br /&gt;
В них нет ничего необычного, внимательно прочесть можно будет, если не заработает. А пока заходим на свой сервер по ssh и заводим корневую директорию для нашего хоста:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;unix&amp;quot;&amp;gt;&lt;br /&gt;
cd www&lt;br /&gt;
mkdir umi.example.com&lt;br /&gt;
scp имя_файла_на_локальном_компьютере имя_пользователя_на_сервере@ip_сервера:/home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где 'имя_файла_на_локальном_компьютере' - путь к распакованному файлу install.php. В зависимости от настроек конкретного сервера поддиректории хостов могут быть расположены в другом месте. Создать директорию и залить файл инсталлятора можно также, используя любой ftp или scp клиент.&lt;br /&gt;
&lt;br /&gt;
Создаем новый хост, для чего в конфигурацию Apache добавляем строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Apache&amp;quot;&amp;gt;&lt;br /&gt;
DocumentRoot /home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
ServerName umi.example.com&lt;br /&gt;
# Адрес администратора и файлы логов можно указать другие, но для начала сойдет&lt;br /&gt;
ServerAdmin admin@localhost&lt;br /&gt;
ErrorLog /var/log/apache2/error.log&lt;br /&gt;
CustomLog /var/log/apache2/access.log combined&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options +FollowSymLinks -Indexes +SymLinksIfOwnerMatch&lt;br /&gt;
&amp;lt;Directory /home/имя_пользователя_на_сервере/www/umi.example.com&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule . index.php&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options -Indexes +FollowSymLinks +SymLinksIfOwnerMatch&lt;br /&gt;
AllowOverride All&lt;br /&gt;
Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
# Это запуск Apache от имени пользователя, чтобы не париться с правами на файлы&lt;br /&gt;
&amp;lt;ifmodule mpm_itk_module&amp;gt;&lt;br /&gt;
AssignUserID имя_пользователя_на_сервере имя_группы_на_сервере&lt;br /&gt;
&amp;lt;/ifmodule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После чего не забудьте проверить правильность конфигурации и обновить конфигурацию запущенного Apache (мягкий перезапуск):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl configtest&lt;br /&gt;
apachectl -k graceful&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или, в зависимости от конкретного UNIX,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создаем базу данных umi и одноименного пользователя базы данных ==&lt;br /&gt;
&lt;br /&gt;
Имя пользователя может быть и другим. Просто мне так нравится.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE DATABASE umi;&lt;br /&gt;
CREATE USER 'umi'@'localhost' IDENTIFIED BY 'password';&lt;br /&gt;
GRANT ALL PRIVILEGES ON umi.* TO 'umi'@'localhost' WITH GRANT OPTION;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если база на другом хосте, то вместо localhost надо указать адрес хоста, например, 'db.example.com'.&lt;br /&gt;
&lt;br /&gt;
== Добавляем домен в локальный файл hosts ==&lt;br /&gt;
&lt;br /&gt;
И последний шаг. Конечно, у нас нет в собственности домена umi.example.com. Но это не значит, что мы не можем видеть свой сайт, набрав этот домен в браузере. Для этого достаточно на локальном компьютере в файле C:\Windows\System32\drivers\etc\hosts добавить строку&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
umi.example.com    IP_адрес_вашего_сервера&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Файл системный, и чтобы его поправить, редактор, скажем, Notepad, надо запускать от имени администратора.&lt;br /&gt;
&lt;br /&gt;
Если создать хост именно с таким именем, а потом прописать его локально с нужным адресом, то все ссылки, приведенные мной в дальнейшем, будут работать и у вас, только вести они будут уже на ваш сервер и сайт.&lt;br /&gt;
&lt;br /&gt;
== Запускаем инсталлятор UMI ==&lt;br /&gt;
&lt;br /&gt;
В браузере набираем адрес umi.example.com/install.php&lt;br /&gt;
&lt;br /&gt;
Если хост был настроен правильно, то увидим:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Смело жмем на &amp;quot;Получить бесплатный ключ&amp;quot;, заполняем появившуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмем &amp;quot;Далее&amp;quot;, смотрим в почту, и вводим полученный ключ в форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И - о чудо! - переходим наконец к шагу 2, где вводим доступы к нашей базе данных:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Заполняем параметры доступа к базе данных, жмем &amp;quot;Далее&amp;quot;, получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 5 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Вообще у инсталлятора есть все возможности проверить, пустая база или нет, и не заставлять нас ставить эту глупую галку, ну да ладно... После чего сидим и любуемся процессом установки. Процесс не слишком быстрый. &lt;br /&gt;
&lt;br /&gt;
В процессе установки могут возникнуть какие-либо ошибки в настройках хостинга, они подробно описаны в документации UMI CMS. Отображение всех возможных вариантов выходит за рамки этой статьи. У меня ошибок не возникло, и вот что получилось:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 6 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
По порядку:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Мои покупки&amp;quot; не рассматриваем вообще, ибо их нет. Покупать готовый шаблон мы и не планировали.&lt;br /&gt;
* &amp;quot;Бесплатные готовые решения&amp;quot; - это набор старых шаблонов на других шаблонизаторах, не PHP. Нам не подходят.&lt;br /&gt;
* &amp;quot;Демо-сайт&amp;quot; - это интересный вариант, там присутствует несколько PHP-шаблонов для разных редакций системы, написанных непосредственно разработчиками UMI CMS, хорошо документированных (в комментариях) и экономящих массу времени при разработке сайта. Но придется много копаться в чужом коде.&lt;br /&gt;
* &amp;quot;Без шаблона&amp;quot; - вот это наш вариант&lt;br /&gt;
&lt;br /&gt;
Опять любуемся на процесс установки. После чего вводим параметры нашего суперадминского доступа:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 7 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И получаем красивую картинку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot8 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмём на кнопку и - о ужас! - получаем вот это:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Ошибка Шаблон дизайна не найден.png]]&lt;br /&gt;
&lt;br /&gt;
Да, мы выбрали вариант без шаблона. Но это не значит, что должны сразу увидеть ошибку! Нажмем на ссылку, и что же? Все стало понятно?&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS ошибка 16005.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', так нельзя! Для исправления ситуации я вижу несколько путей:&lt;br /&gt;
# Создавать пустой шаблон, как это сделано во всех нормальных системах, типа надписи &amp;quot;It works!&amp;quot;&lt;br /&gt;
# Выдавать сообщение (не ошибку!), что шаблона нет, с кнопкой для перехода в админку и ссылкой на инструкцию, как этот шаблон создавать&lt;br /&gt;
# Информация о том, что шаблона нет, в инсталляторе имеется, и в этом случае давайте сразу переходить в админку в форму создания шаблона! Тем более, что админка работает и доступна по ссылке http://umi.example.com/admin/. Вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Структура сайта.png]]&lt;br /&gt;
&lt;br /&gt;
== Создаем шаблон ==&lt;br /&gt;
&lt;br /&gt;
Задача для начинающего разработчика очень сложная, и даже я сверяюсь с собственной инструкцией каждый раз при создании нового сайта. Именно поэтому создание пустого шаблона при инсталляции кажется мне очень привлекательным решением с точки зрения юзабилити.&lt;br /&gt;
&lt;br /&gt;
Самое главное: '''ни в коем случае не следуйте инструкции, предлагаемой по ссылке в сообщении об ошибке'''! -100500 в карму тому, кто ее писал!&lt;br /&gt;
&lt;br /&gt;
Заходим в админку, введя свой суперпароль, и попадаем в раздел &amp;quot;Структура&amp;quot;, который нам пока что не нужен. Вместо этого находим в левом верхнем углу бабочку и жмём не нее. В открывшейся панели выбираем &amp;quot;Шаблоны сайта&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Список модулей.png|без]]&lt;br /&gt;
&lt;br /&gt;
Шаблонов там пока нет, но над пустым списком есть черный кружок с плюсом - это волшебная кнопка создания нового шаблона. Жмём её:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Список шаблонов.png|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Список шаблонов.png]]&lt;br /&gt;
&lt;br /&gt;
И - voila! - шаблон появляется в нашем списке. Конечно, этого недостаточно, надо в директории templates/default/php/ создать файл common.phtml, например, такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще один удивительный факт: директория default создалась автоматически при создании шаблона, а вот поддиректория php - нет. '''Вопрос разработчикам''': может, стоит все это делать автоматически???&lt;br /&gt;
&lt;br /&gt;
Все сделали, находим вверху на черном фоне белую ссылку &amp;quot;На сайт&amp;quot;, жмём, и, наконец, видим что-то осмысленное:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь можно переходить непосредственно к [[Структура сайта|разработке сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=332</id>
		<title>Установка UMI CMS Trial</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=332"/>
		<updated>2020-11-05T14:47:44Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
На странице https://www.umi-cms.ru/downloads/full/ нажимаем &amp;quot;Скачать&amp;quot; и получаем файл umi-cms.zip, в котором содержится единственный файл install.php.&lt;br /&gt;
&lt;br /&gt;
Можно установить систему на локальном хостинге, но я сразу установлю UMI CMS на сервере. Для этого требуется некоторая подготовка. На сервере обычно есть интерфейс для создания хостов и баз данных, в этом случае следующие 2 раздела можно пропустить. Все используемые ниже имена, конечно, надо заменить на требуемые.&lt;br /&gt;
&lt;br /&gt;
== Создаем хост umi.example.com ==&lt;br /&gt;
&lt;br /&gt;
Системные требования можно посмотреть [http://help.docs.umi-cms.ru/vvedenie/ustanovka_i_nastrojka/sistemnie_trebovaniya/ здесь].&lt;br /&gt;
&lt;br /&gt;
В них нет ничего необычного, внимательно прочесть можно будет, если не заработает. А пока заходим на свой сервер по ssh и заводим корневую директорию для нашего хоста:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd www&lt;br /&gt;
mkdir umi.example.com&lt;br /&gt;
scp имя_файла_на_локальном_компьютере имя_пользователя_на_сервере@ip_сервера:/home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где 'имя_файла_на_локальном_компьютере' - путь к распакованному файлу install.php. В зависимости от настроек конкретного сервера поддиректории хостов могут быть расположены в другом месте. Создать директорию и залить файл инсталлятора можно также, используя любой ftp или scp клиент.&lt;br /&gt;
&lt;br /&gt;
Создаем новый хост, для чего в конфигурацию Apache добавляем строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Apache&amp;quot;&amp;gt;&lt;br /&gt;
DocumentRoot /home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
ServerName umi.example.com&lt;br /&gt;
# Адрес администратора и файлы логов можно указать другие, но для начала сойдет&lt;br /&gt;
ServerAdmin admin@localhost&lt;br /&gt;
ErrorLog /var/log/apache2/error.log&lt;br /&gt;
CustomLog /var/log/apache2/access.log combined&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options +FollowSymLinks -Indexes +SymLinksIfOwnerMatch&lt;br /&gt;
&amp;lt;Directory /home/имя_пользователя_на_сервере/www/umi.example.com&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule . index.php&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options -Indexes +FollowSymLinks +SymLinksIfOwnerMatch&lt;br /&gt;
AllowOverride All&lt;br /&gt;
Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
# Это запуск Apache от имени пользователя, чтобы не париться с правами на файлы&lt;br /&gt;
&amp;lt;ifmodule mpm_itk_module&amp;gt;&lt;br /&gt;
AssignUserID имя_пользователя_на_сервере имя_группы_на_сервере&lt;br /&gt;
&amp;lt;/ifmodule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После чего не забудьте проверить правильность конфигурации и обновить конфигурацию запущенного Apache (мягкий перезапуск):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl configtest&lt;br /&gt;
apachectl -k graceful&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или, в зависимости от конкретного UNIX,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создаем базу данных umi и одноименного пользователя базы данных ==&lt;br /&gt;
&lt;br /&gt;
Имя пользователя может быть и другим. Просто мне так нравится.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE DATABASE umi;&lt;br /&gt;
CREATE USER 'umi'@'localhost' IDENTIFIED BY 'password';&lt;br /&gt;
GRANT ALL PRIVILEGES ON umi.* TO 'umi'@'localhost' WITH GRANT OPTION;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если база на другом хосте, то вместо localhost надо указать адрес хоста, например, 'db.example.com'.&lt;br /&gt;
&lt;br /&gt;
== Добавляем домен в локальный файл hosts ==&lt;br /&gt;
&lt;br /&gt;
И последний шаг. Конечно, у нас нет в собственности домена umi.example.com. Но это не значит, что мы не можем видеть свой сайт, набрав этот домен в браузере. Для этого достаточно на локальном компьютере в файле C:\Windows\System32\drivers\etc\hosts добавить строку&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
umi.example.com    IP_адрес_вашего_сервера&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Файл системный, и чтобы его поправить, редактор, скажем, Notepad, надо запускать от имени администратора.&lt;br /&gt;
&lt;br /&gt;
Если создать хост именно с таким именем, а потом прописать его локально с нужным адресом, то все ссылки, приведенные мной в дальнейшем, будут работать и у вас, только вести они будут уже на ваш сервер и сайт.&lt;br /&gt;
&lt;br /&gt;
== Запускаем инсталлятор UMI ==&lt;br /&gt;
&lt;br /&gt;
В браузере набираем адрес umi.example.com/install.php&lt;br /&gt;
&lt;br /&gt;
Если хост был настроен правильно, то увидим:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Смело жмем на &amp;quot;Получить бесплатный ключ&amp;quot;, заполняем появившуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмем &amp;quot;Далее&amp;quot;, смотрим в почту, и вводим полученный ключ в форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И - о чудо! - переходим наконец к шагу 2, где вводим доступы к нашей базе данных:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Заполняем параметры доступа к базе данных, жмем &amp;quot;Далее&amp;quot;, получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 5 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Вообще у инсталлятора есть все возможности проверить, пустая база или нет, и не заставлять нас ставить эту глупую галку, ну да ладно... После чего сидим и любуемся процессом установки. Процесс не слишком быстрый. &lt;br /&gt;
&lt;br /&gt;
В процессе установки могут возникнуть какие-либо ошибки в настройках хостинга, они подробно описаны в документации UMI CMS. Отображение всех возможных вариантов выходит за рамки этой статьи. У меня ошибок не возникло, и вот что получилось:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 6 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
По порядку:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Мои покупки&amp;quot; не рассматриваем вообще, ибо их нет. Покупать готовый шаблон мы и не планировали.&lt;br /&gt;
* &amp;quot;Бесплатные готовые решения&amp;quot; - это набор старых шаблонов на других шаблонизаторах, не PHP. Нам не подходят.&lt;br /&gt;
* &amp;quot;Демо-сайт&amp;quot; - это интересный вариант, там присутствует несколько PHP-шаблонов для разных редакций системы, написанных непосредственно разработчиками UMI CMS, хорошо документированных (в комментариях) и экономящих массу времени при разработке сайта. Но придется много копаться в чужом коде.&lt;br /&gt;
* &amp;quot;Без шаблона&amp;quot; - вот это наш вариант&lt;br /&gt;
&lt;br /&gt;
Опять любуемся на процесс установки. После чего вводим параметры нашего суперадминского доступа:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 7 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И получаем красивую картинку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot8 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмём на кнопку и - о ужас! - получаем вот это:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Ошибка Шаблон дизайна не найден.png]]&lt;br /&gt;
&lt;br /&gt;
Да, мы выбрали вариант без шаблона. Но это не значит, что должны сразу увидеть ошибку! Нажмем на ссылку, и что же? Все стало понятно?&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS ошибка 16005.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', так нельзя! Для исправления ситуации я вижу несколько путей:&lt;br /&gt;
# Создавать пустой шаблон, как это сделано во всех нормальных системах, типа надписи &amp;quot;It works!&amp;quot;&lt;br /&gt;
# Выдавать сообщение (не ошибку!), что шаблона нет, с кнопкой для перехода в админку и ссылкой на инструкцию, как этот шаблон создавать&lt;br /&gt;
# Информация о том, что шаблона нет, в инсталляторе имеется, и в этом случае давайте сразу переходить в админку в форму создания шаблона! Тем более, что админка работает и доступна по ссылке http://umi.example.com/admin/. Вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Структура сайта.png]]&lt;br /&gt;
&lt;br /&gt;
== Создаем шаблон ==&lt;br /&gt;
&lt;br /&gt;
Задача для начинающего разработчика очень сложная, и даже я сверяюсь с собственной инструкцией каждый раз при создании нового сайта. Именно поэтому создание пустого шаблона при инсталляции кажется мне очень привлекательным решением с точки зрения юзабилити.&lt;br /&gt;
&lt;br /&gt;
Самое главное: '''ни в коем случае не следуйте инструкции, предлагаемой по ссылке в сообщении об ошибке'''! -100500 в карму тому, кто ее писал!&lt;br /&gt;
&lt;br /&gt;
Заходим в админку, введя свой суперпароль, и попадаем в раздел &amp;quot;Структура&amp;quot;, который нам пока что не нужен. Вместо этого находим в левом верхнем углу бабочку и жмём не нее. В открывшейся панели выбираем &amp;quot;Шаблоны сайта&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Список модулей.png|без]]&lt;br /&gt;
&lt;br /&gt;
Шаблонов там пока нет, но над пустым списком есть черный кружок с плюсом - это волшебная кнопка создания нового шаблона. Жмём её:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Список шаблонов.png|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Список шаблонов.png]]&lt;br /&gt;
&lt;br /&gt;
И - voila! - шаблон появляется в нашем списке. Конечно, этого недостаточно, надо в директории templates/default/php/ создать файл common.phtml, например, такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще один удивительный факт: директория default создалась автоматически при создании шаблона, а вот поддиректория php - нет. '''Вопрос разработчикам''': может, стоит все это делать автоматически???&lt;br /&gt;
&lt;br /&gt;
Все сделали, находим вверху на черном фоне белую ссылку &amp;quot;На сайт&amp;quot;, жмём, и, наконец, видим что-то осмысленное:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь можно переходить непосредственно к [[Структура сайта|разработке сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=331</id>
		<title>Установка UMI CMS Trial</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=331"/>
		<updated>2020-11-05T14:46:44Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br&amp;gt;&lt;br /&gt;
На странице https://www.umi-cms.ru/downloads/full/ нажимаем &amp;quot;Скачать&amp;quot; и получаем файл umi-cms.zip, в котором содержится единственный файл install.php.&lt;br /&gt;
&lt;br /&gt;
Можно установить систему на локальном хостинге, но я сразу установлю UMI CMS на сервере. Для этого требуется некоторая подготовка. На сервере обычно есть интерфейс для создания хостов и баз данных, в этом случае следующие 2 раздела можно пропустить. Все используемые ниже имена, конечно, надо заменить на требуемые.&lt;br /&gt;
&lt;br /&gt;
== Создаем хост umi.example.com ==&lt;br /&gt;
&lt;br /&gt;
Системные требования можно посмотреть [http://help.docs.umi-cms.ru/vvedenie/ustanovka_i_nastrojka/sistemnie_trebovaniya/ здесь].&lt;br /&gt;
&lt;br /&gt;
В них нет ничего необычного, внимательно прочесть можно будет, если не заработает. А пока заходим на свой сервер по ssh и заводим корневую директорию для нашего хоста:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd www&lt;br /&gt;
mkdir umi.example.com&lt;br /&gt;
scp имя_файла_на_локальном_компьютере имя_пользователя_на_сервере@ip_сервера:/home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где 'имя_файла_на_локальном_компьютере' - путь к распакованному файлу install.php. В зависимости от настроек конкретного сервера поддиректории хостов могут быть расположены в другом месте. Создать директорию и залить файл инсталлятора можно также, используя любой ftp или scp клиент.&lt;br /&gt;
&lt;br /&gt;
Создаем новый хост, для чего в конфигурацию Apache добавляем строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Apache config files&amp;quot;&amp;gt;&lt;br /&gt;
DocumentRoot /home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
ServerName umi.example.com&lt;br /&gt;
# Адрес администратора и файлы логов можно указать другие, но для начала сойдет&lt;br /&gt;
ServerAdmin admin@localhost&lt;br /&gt;
ErrorLog /var/log/apache2/error.log&lt;br /&gt;
CustomLog /var/log/apache2/access.log combined&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options +FollowSymLinks -Indexes +SymLinksIfOwnerMatch&lt;br /&gt;
&amp;lt;Directory /home/имя_пользователя_на_сервере/www/umi.example.com&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule . index.php&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options -Indexes +FollowSymLinks +SymLinksIfOwnerMatch&lt;br /&gt;
AllowOverride All&lt;br /&gt;
Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
# Это запуск Apache от имени пользователя, чтобы не париться с правами на файлы&lt;br /&gt;
&amp;lt;ifmodule mpm_itk_module&amp;gt;&lt;br /&gt;
AssignUserID имя_пользователя_на_сервере имя_группы_на_сервере&lt;br /&gt;
&amp;lt;/ifmodule&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После чего не забудьте проверить правильность конфигурации и обновить конфигурацию запущенного Apache (мягкий перезапуск):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl configtest&lt;br /&gt;
apachectl -k graceful&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или, в зависимости от конкретного UNIX,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создаем базу данных umi и одноименного пользователя базы данных ==&lt;br /&gt;
&lt;br /&gt;
Имя пользователя может быть и другим. Просто мне так нравится.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE DATABASE umi;&lt;br /&gt;
CREATE USER 'umi'@'localhost' IDENTIFIED BY 'password';&lt;br /&gt;
GRANT ALL PRIVILEGES ON umi.* TO 'umi'@'localhost' WITH GRANT OPTION;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если база на другом хосте, то вместо localhost надо указать адрес хоста, например, 'db.example.com'.&lt;br /&gt;
&lt;br /&gt;
== Добавляем домен в локальный файл hosts ==&lt;br /&gt;
&lt;br /&gt;
И последний шаг. Конечно, у нас нет в собственности домена umi.example.com. Но это не значит, что мы не можем видеть свой сайт, набрав этот домен в браузере. Для этого достаточно на локальном компьютере в файле C:\Windows\System32\drivers\etc\hosts добавить строку&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
umi.example.com    IP_адрес_вашего_сервера&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Файл системный, и чтобы его поправить, редактор, скажем, Notepad, надо запускать от имени администратора.&lt;br /&gt;
&lt;br /&gt;
Если создать хост именно с таким именем, а потом прописать его локально с нужным адресом, то все ссылки, приведенные мной в дальнейшем, будут работать и у вас, только вести они будут уже на ваш сервер и сайт.&lt;br /&gt;
&lt;br /&gt;
== Запускаем инсталлятор UMI ==&lt;br /&gt;
&lt;br /&gt;
В браузере набираем адрес umi.example.com/install.php&lt;br /&gt;
&lt;br /&gt;
Если хост был настроен правильно, то увидим:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Смело жмем на &amp;quot;Получить бесплатный ключ&amp;quot;, заполняем появившуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмем &amp;quot;Далее&amp;quot;, смотрим в почту, и вводим полученный ключ в форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И - о чудо! - переходим наконец к шагу 2, где вводим доступы к нашей базе данных:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Заполняем параметры доступа к базе данных, жмем &amp;quot;Далее&amp;quot;, получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 5 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Вообще у инсталлятора есть все возможности проверить, пустая база или нет, и не заставлять нас ставить эту глупую галку, ну да ладно... После чего сидим и любуемся процессом установки. Процесс не слишком быстрый. &lt;br /&gt;
&lt;br /&gt;
В процессе установки могут возникнуть какие-либо ошибки в настройках хостинга, они подробно описаны в документации UMI CMS. Отображение всех возможных вариантов выходит за рамки этой статьи. У меня ошибок не возникло, и вот что получилось:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 6 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
По порядку:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Мои покупки&amp;quot; не рассматриваем вообще, ибо их нет. Покупать готовый шаблон мы и не планировали.&lt;br /&gt;
* &amp;quot;Бесплатные готовые решения&amp;quot; - это набор старых шаблонов на других шаблонизаторах, не PHP. Нам не подходят.&lt;br /&gt;
* &amp;quot;Демо-сайт&amp;quot; - это интересный вариант, там присутствует несколько PHP-шаблонов для разных редакций системы, написанных непосредственно разработчиками UMI CMS, хорошо документированных (в комментариях) и экономящих массу времени при разработке сайта. Но придется много копаться в чужом коде.&lt;br /&gt;
* &amp;quot;Без шаблона&amp;quot; - вот это наш вариант&lt;br /&gt;
&lt;br /&gt;
Опять любуемся на процесс установки. После чего вводим параметры нашего суперадминского доступа:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 7 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И получаем красивую картинку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot8 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмём на кнопку и - о ужас! - получаем вот это:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Ошибка Шаблон дизайна не найден.png]]&lt;br /&gt;
&lt;br /&gt;
Да, мы выбрали вариант без шаблона. Но это не значит, что должны сразу увидеть ошибку! Нажмем на ссылку, и что же? Все стало понятно?&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS ошибка 16005.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', так нельзя! Для исправления ситуации я вижу несколько путей:&lt;br /&gt;
# Создавать пустой шаблон, как это сделано во всех нормальных системах, типа надписи &amp;quot;It works!&amp;quot;&lt;br /&gt;
# Выдавать сообщение (не ошибку!), что шаблона нет, с кнопкой для перехода в админку и ссылкой на инструкцию, как этот шаблон создавать&lt;br /&gt;
# Информация о том, что шаблона нет, в инсталляторе имеется, и в этом случае давайте сразу переходить в админку в форму создания шаблона! Тем более, что админка работает и доступна по ссылке http://umi.example.com/admin/. Вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Структура сайта.png]]&lt;br /&gt;
&lt;br /&gt;
== Создаем шаблон ==&lt;br /&gt;
&lt;br /&gt;
Задача для начинающего разработчика очень сложная, и даже я сверяюсь с собственной инструкцией каждый раз при создании нового сайта. Именно поэтому создание пустого шаблона при инсталляции кажется мне очень привлекательным решением с точки зрения юзабилити.&lt;br /&gt;
&lt;br /&gt;
Самое главное: '''ни в коем случае не следуйте инструкции, предлагаемой по ссылке в сообщении об ошибке'''! -100500 в карму тому, кто ее писал!&lt;br /&gt;
&lt;br /&gt;
Заходим в админку, введя свой суперпароль, и попадаем в раздел &amp;quot;Структура&amp;quot;, который нам пока что не нужен. Вместо этого находим в левом верхнем углу бабочку и жмём не нее. В открывшейся панели выбираем &amp;quot;Шаблоны сайта&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Список модулей.png|без]]&lt;br /&gt;
&lt;br /&gt;
Шаблонов там пока нет, но над пустым списком есть черный кружок с плюсом - это волшебная кнопка создания нового шаблона. Жмём её:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Список шаблонов.png|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Список шаблонов.png]]&lt;br /&gt;
&lt;br /&gt;
И - voila! - шаблон появляется в нашем списке. Конечно, этого недостаточно, надо в директории templates/default/php/ создать файл common.phtml, например, такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще один удивительный факт: директория default создалась автоматически при создании шаблона, а вот поддиректория php - нет. '''Вопрос разработчикам''': может, стоит все это делать автоматически???&lt;br /&gt;
&lt;br /&gt;
Все сделали, находим вверху на черном фоне белую ссылку &amp;quot;На сайт&amp;quot;, жмём, и, наконец, видим что-то осмысленное:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь можно переходить непосредственно к [[Структура сайта|разработке сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=330</id>
		<title>Установка UMI CMS Trial</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_UMI_CMS_Trial&amp;diff=330"/>
		<updated>2020-11-05T14:35:04Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;На странице https://www.umi-cms.ru/downloads/full/ нажимаем &amp;quot;Скачать&amp;quot; и получаем файл umi-cms.zip, в котором содержится единственный файл install.php.&lt;br /&gt;
&lt;br /&gt;
Можно установить систему на локальном хостинге, но я сразу установлю UMI CMS на сервере. Для этого требуется некоторая подготовка. На сервере обычно есть интерфейс для создания хостов и баз данных, в этом случае следующие 2 раздела можно пропустить. Все используемые ниже имена, конечно, надо заменить на требуемые.&lt;br /&gt;
&lt;br /&gt;
== Создаем хост umi.example.com ==&lt;br /&gt;
&lt;br /&gt;
Системные требования можно посмотреть [http://help.docs.umi-cms.ru/vvedenie/ustanovka_i_nastrojka/sistemnie_trebovaniya/ здесь].&lt;br /&gt;
&lt;br /&gt;
В них нет ничего необычного, внимательно прочесть можно будет, если не заработает. А пока заходим на свой сервер по ssh и заводим корневую директорию для нашего хоста:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd www&lt;br /&gt;
mkdir umi.example.com&lt;br /&gt;
scp имя_файла_на_локальном_компьютере имя_пользователя_на_сервере@ip_сервера:/home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где 'имя_файла_на_локальном_компьютере' - путь к распакованному файлу install.php. В зависимости от настроек конкретного сервера поддиректории хостов могут быть расположены в другом месте. Создать директорию и залить файл инсталлятора можно также, используя любой ftp или scp клиент.&lt;br /&gt;
&lt;br /&gt;
Создаем новый хост, для чего в конфигурацию Apache добавляем строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DocumentRoot /home/имя_пользователя_на_сервере/www/umi.example.com&lt;br /&gt;
ServerName umi.example.com&lt;br /&gt;
# Адрес администратора и файлы логов можно указать другие, но для начала сойдет&lt;br /&gt;
ServerAdmin admin@localhost&lt;br /&gt;
ErrorLog /var/log/apache2/error.log&lt;br /&gt;
CustomLog /var/log/apache2/access.log combined&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options +FollowSymLinks -Indexes +SymLinksIfOwnerMatch&lt;br /&gt;
&amp;lt;Directory /home/имя_пользователя_на_сервере/www/umi.example.com&amp;gt;&lt;br /&gt;
RewriteEngine on&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;
RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;
RewriteRule . index.php&lt;br /&gt;
DirectoryIndex index.php&lt;br /&gt;
Options -Indexes +FollowSymLinks +SymLinksIfOwnerMatch&lt;br /&gt;
AllowOverride All&lt;br /&gt;
Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
# Это запуск Apache от имени пользователя, чтобы не париться с правами на файлы&lt;br /&gt;
&amp;lt;ifmodule mpm_itk_module&amp;gt;&lt;br /&gt;
AssignUserID имя_пользователя_на_сервере имя_группы_на_сервере&lt;br /&gt;
&amp;lt;/ifmodule&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После чего не забудьте проверить правильность конфигурации и обновить конфигурацию запущенного Apache (мягкий перезапуск):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apachectl configtest&lt;br /&gt;
apachectl -k graceful&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или, в зависимости от конкретного UNIX,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создаем базу данных umi и одноименного пользователя базы данных ==&lt;br /&gt;
&lt;br /&gt;
Имя пользователя может быть и другим. Просто мне так нравится.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE DATABASE umi;&lt;br /&gt;
CREATE USER 'umi'@'localhost' IDENTIFIED BY 'password';&lt;br /&gt;
GRANT ALL PRIVILEGES ON umi.* TO 'umi'@'localhost' WITH GRANT OPTION;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или, если база на другом хосте, то вместо localhost надо указать адрес хоста, например, 'db.example.com'.&lt;br /&gt;
&lt;br /&gt;
== Добавляем домен в локальный файл hosts ==&lt;br /&gt;
&lt;br /&gt;
И последний шаг. Конечно, у нас нет в собственности домена umi.example.com. Но это не значит, что мы не можем видеть свой сайт, набрав этот домен в браузере. Для этого достаточно на локальном компьютере в файле C:\Windows\System32\drivers\etc\hosts добавить строку&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
umi.example.com    IP_адрес_вашего_сервера&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Файл системный, и чтобы его поправить, редактор, скажем, Notepad, надо запускать от имени администратора.&lt;br /&gt;
&lt;br /&gt;
Если создать хост именно с таким именем, а потом прописать его локально с нужным адресом, то все ссылки, приведенные мной в дальнейшем, будут работать и у вас, только вести они будут уже на ваш сервер и сайт.&lt;br /&gt;
&lt;br /&gt;
== Запускаем инсталлятор UMI ==&lt;br /&gt;
&lt;br /&gt;
В браузере набираем адрес umi.example.com/install.php&lt;br /&gt;
&lt;br /&gt;
Если хост был настроен правильно, то увидим:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Смело жмем на &amp;quot;Получить бесплатный ключ&amp;quot;, заполняем появившуюся форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмем &amp;quot;Далее&amp;quot;, смотрим в почту, и вводим полученный ключ в форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И - о чудо! - переходим наконец к шагу 2, где вводим доступы к нашей базе данных:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 4 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Заполняем параметры доступа к базе данных, жмем &amp;quot;Далее&amp;quot;, получаем:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 5 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Вообще у инсталлятора есть все возможности проверить, пустая база или нет, и не заставлять нас ставить эту глупую галку, ну да ладно... После чего сидим и любуемся процессом установки. Процесс не слишком быстрый. &lt;br /&gt;
&lt;br /&gt;
В процессе установки могут возникнуть какие-либо ошибки в настройках хостинга, они подробно описаны в документации UMI CMS. Отображение всех возможных вариантов выходит за рамки этой статьи. У меня ошибок не возникло, и вот что получилось:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 6 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
По порядку:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Мои покупки&amp;quot; не рассматриваем вообще, ибо их нет. Покупать готовый шаблон мы и не планировали.&lt;br /&gt;
* &amp;quot;Бесплатные готовые решения&amp;quot; - это набор старых шаблонов на других шаблонизаторах, не PHP. Нам не подходят.&lt;br /&gt;
* &amp;quot;Демо-сайт&amp;quot; - это интересный вариант, там присутствует несколько PHP-шаблонов для разных редакций системы, написанных непосредственно разработчиками UMI CMS, хорошо документированных (в комментариях) и экономящих массу времени при разработке сайта. Но придется много копаться в чужом коде.&lt;br /&gt;
* &amp;quot;Без шаблона&amp;quot; - вот это наш вариант&lt;br /&gt;
&lt;br /&gt;
Опять любуемся на процесс установки. После чего вводим параметры нашего суперадминского доступа:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 7 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
И получаем красивую картинку:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot8 Установка UMI CMS.png]]&lt;br /&gt;
&lt;br /&gt;
Жмём на кнопку и - о ужас! - получаем вот это:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Ошибка Шаблон дизайна не найден.png]]&lt;br /&gt;
&lt;br /&gt;
Да, мы выбрали вариант без шаблона. Но это не значит, что должны сразу увидеть ошибку! Нажмем на ссылку, и что же? Все стало понятно?&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS ошибка 16005.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
'''Господа разработчики''', так нельзя! Для исправления ситуации я вижу несколько путей:&lt;br /&gt;
# Создавать пустой шаблон, как это сделано во всех нормальных системах, типа надписи &amp;quot;It works!&amp;quot;&lt;br /&gt;
# Выдавать сообщение (не ошибку!), что шаблона нет, с кнопкой для перехода в админку и ссылкой на инструкцию, как этот шаблон создавать&lt;br /&gt;
# Информация о том, что шаблона нет, в инсталляторе имеется, и в этом случае давайте сразу переходить в админку в форму создания шаблона! Тем более, что админка работает и доступна по ссылке http://umi.example.com/admin/. Вот так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Структура сайта.png]]&lt;br /&gt;
&lt;br /&gt;
== Создаем шаблон ==&lt;br /&gt;
&lt;br /&gt;
Задача для начинающего разработчика очень сложная, и даже я сверяюсь с собственной инструкцией каждый раз при создании нового сайта. Именно поэтому создание пустого шаблона при инсталляции кажется мне очень привлекательным решением с точки зрения юзабилити.&lt;br /&gt;
&lt;br /&gt;
Самое главное: '''ни в коем случае не следуйте инструкции, предлагаемой по ссылке в сообщении об ошибке'''! -100500 в карму тому, кто ее писал!&lt;br /&gt;
&lt;br /&gt;
Заходим в админку, введя свой суперпароль, и попадаем в раздел &amp;quot;Структура&amp;quot;, который нам пока что не нужен. Вместо этого находим в левом верхнем углу бабочку и жмём не нее. В открывшейся панели выбираем &amp;quot;Шаблоны сайта&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 UMI CMS - Список модулей.png|без]]&lt;br /&gt;
&lt;br /&gt;
Шаблонов там пока нет, но над пустым списком есть черный кружок с плюсом - это волшебная кнопка создания нового шаблона. Жмём её:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2 UMI CMS - Список шаблонов.png|без]]&lt;br /&gt;
&lt;br /&gt;
Заполняем форму:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 3 UMI CMS - Список шаблонов.png]]&lt;br /&gt;
&lt;br /&gt;
И - voila! - шаблон появляется в нашем списке. Конечно, этого недостаточно, надо в директории templates/default/php/ создать файл common.phtml, например, такой:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Еще один удивительный факт: директория default создалась автоматически при создании шаблона, а вот поддиректория php - нет. '''Вопрос разработчикам''': может, стоит все это делать автоматически???&lt;br /&gt;
&lt;br /&gt;
Все сделали, находим вверху на черном фоне белую ссылку &amp;quot;На сайт&amp;quot;, жмём, и, наконец, видим что-то осмысленное:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Screenshot 2020-10-28 Screenshot.png|обрамить|без]]&lt;br /&gt;
&lt;br /&gt;
Теперь можно переходить непосредственно к [[Структура сайта|разработке сайта]].&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=329</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=329"/>
		<updated>2020-11-05T14:32:59Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобиться добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Но нам хватит и одного.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=328</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=328"/>
		<updated>2020-11-05T14:23:08Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобиться добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Но нам хватит и одного.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
	<entry>
		<id>http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=327</id>
		<title>Расширение функциональности модулей</title>
		<link rel="alternate" type="text/html" href="http://wiki.adt.ru/w/index.php?title=%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9&amp;diff=327"/>
		<updated>2020-11-05T14:22:08Z</updated>

		<summary type="html">&lt;p&gt;Olga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Некоторые методы UMI CMS оставляют желать лучшего. Например, метод lastlist модуля news не возвращает значение поля anons новости, который может понадобиться в списке новостей. Можно ли с этим что-то сделать?&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы стандартных модулей ==&lt;br /&gt;
&lt;br /&gt;
Открываем директорию /classes/components/news и видим там файлы macros.php и customMacros.php. В файле macros.php находим функцию lastlist(), копируем её и целиком вставляем в customMacros.php после строки public $module;.&lt;br /&gt;
&lt;br /&gt;
Находим там кусок кода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
$line_arr = [];&lt;br /&gt;
$line_arr['attribute:id'] = $element_id;&lt;br /&gt;
$line_arr['node:name'] = $element-&amp;gt;getName();&lt;br /&gt;
$line_arr['attribute:link'] = $umiLinksHelper-&amp;gt;getLinkByParts($element);&lt;br /&gt;
$line_arr['xlink:href'] = 'upage://' . $element_id;&lt;br /&gt;
$line_arr['void:header'] = $lines_arr['name'] = $element-&amp;gt;getName();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Там и правда не добавляется анонс. Поэтому вставляем одну строчку:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$line_arr['attribute:anons'] = $element-&amp;gt;anons;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти ''node:'' и ''attribute:'' предназначены для других шаблонизаторов, но лучше их сохранить для общности.&lt;br /&gt;
&lt;br /&gt;
Открываем главную страницу нашего сайта - и видим ошибку &amp;quot;Ошибка (Error): Class 'Service' not found&amp;quot;! Правда, с этим понятно, что делать, надо в начале файла customMacros.php вставить &amp;quot;use UmiCms\Service;&amp;quot;, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских макросов */&lt;br /&gt;
    class NewsCustomMacros {&lt;br /&gt;
&lt;br /&gt;
        /** @var news $module */&lt;br /&gt;
        public $module;&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Больше ошибок не возникнет, и теперь при вызове метода lastlist() получим также и элемент массива 'anons'. Если изменим в файле content/home/news.phtml код цикла вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if (!empty($newsList['items'])):&lt;br /&gt;
    foreach ($newsList['items'] as $item):&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
                            &amp;lt;li class=&amp;quot;list-group-item&amp;quot;&amp;gt;&lt;br /&gt;
                                &amp;lt;em&amp;gt;&amp;lt;?= date(&amp;quot;d.m.Y&amp;quot;, $item['publish_time']) ?&amp;gt;&amp;lt;/em&amp;gt;&lt;br /&gt;
                                &amp;lt;a href=&amp;quot;&amp;lt;?= $item['link'] ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;h3 umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;name&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_page_name') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['name'] ?&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
                                &amp;lt;div umi:element-id=&amp;quot;&amp;lt;?= $item['id'] ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;anons&amp;quot; umi:empty=&amp;quot;&amp;lt;?= $this-&amp;gt;translate('empty_news_anons') ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;?= $item['anons'] ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                            &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    endforeach;&lt;br /&gt;
endif;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
то увидим также и текст анонсов. Можно просто набрать в браузере http://umi.example.com/udata://news/lastlist/7/.json и увидеть изменения.&lt;br /&gt;
&lt;br /&gt;
Что будет, если внести исправления сразу в файл macros.php? Очевидно, что все исправления будут потеряны при очередном обновлении системы.&lt;br /&gt;
&lt;br /&gt;
Сразу замечу, что переопределять стандартные методы - '''ОЧЕНЬ ДУРНАЯ ПРАКТИКА'''. Если с сайтом будет работать другой программист, ему придется потратить кучу сил и времени на поиск ошибки, ведь он будет уверен, что вызывается стандартный метод. Поэтому '''ВСЕГДА''', скопировав код стандартного метода, '''ПЕРЕИМЕНОВЫВАЙТЕ ЕГО'''! Пусть этот метод будет целиком и полностью кастомным, и это будет видно уже при вызове. И тогда возникает следующая задача - настройка разрешений.&lt;br /&gt;
&lt;br /&gt;
=== Настройка разрешений для выполнения метода ===&lt;br /&gt;
&lt;br /&gt;
Да, переопределение метода - нехороший поступок, но когда мы так делаем, автоматически избегаем множества проблем. Дело в том, что в UMI CMS есть сложная система разрешений, для каждого модуля существует собственный набор, посмотреть его можно в папке модуля в файле permissions.php.&lt;br /&gt;
&lt;br /&gt;
Когда мы создаем метод с новым именем, то он не будет выполняться, т к отсутствует в файле permissions.php. Но это можно исправить, создав в той же папке модуля файл permissions.custom.php.&lt;br /&gt;
&lt;br /&gt;
Предположим, по аналогии с методом lastlist() мы создали метод newslist(), куда внесли все необходимые нам изменения. Если посмотреть содержимое файла permissions.php, увидим, что это массив:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    /** Группы прав на функционал модуля */&lt;br /&gt;
    $permissions = [&lt;br /&gt;
        /** Права на просмотр новостей */&lt;br /&gt;
        'view' =&amp;gt; [&lt;br /&gt;
            'lastlist',&lt;br /&gt;
            'listlents',&lt;br /&gt;
            'rubric',&lt;br /&gt;
        /** ... и так далее, не буду приводить его целиком */&lt;br /&gt;
        ]&lt;br /&gt;
    ];&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По логике, нам надо добавить один элемент в массив $permissions['view'], поэтому в файле permissions.custom.php пишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересный факт: даже если название метода содержит буквы с разной капитализацией, в этом массиве все нужно писать маленькими буквами. Не спрашивайте, почему.&lt;br /&gt;
&lt;br /&gt;
Пока всё просто? Это только кажется. В каждом модуле структура и ключи массива разрешений разные, и в них нет никакой системы. Хорошо, если метод должен быть общедоступным, как правило, можно угадать, в какой именно массив его добавлять. Сложнее, если доступ можно давать только авторизоваанным пользователям, и то не всем. Так что - удачи!&lt;br /&gt;
&lt;br /&gt;
=== Использование кастомного метода в шаблона ===&lt;br /&gt;
&lt;br /&gt;
Теперь меняем в файле content/home/news.phtml имя метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$newsList = $this-&amp;gt;macros('news', 'newslist', [$newsPageId]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и увидим то, что планировали. И даже есть вызовем этот метод просто в строке URL, на пример, так: &lt;br /&gt;
&lt;br /&gt;
http://umi.example.com/udata://news/newslist/7/.json&lt;br /&gt;
&lt;br /&gt;
(где 7 - это id ленты новостей, на других сайтах может быть другой), то получим json-массив с элементом anons.&lt;br /&gt;
&lt;br /&gt;
== Кастомные методы внутри шаблона ==&lt;br /&gt;
&lt;br /&gt;
Описанный выше способ хорош, но добавленный код находится вне нашего шаблона default. А нам бы хотелось, во-первых, при установке системы на другом хостинге просто закинуть туда готовый шаблон и получить готовый сайт, больше ничего не трогая, особенно системные директории. И во-вторых, хотелось бы для разных сайтов на разных щаблонах использовать разные кастомные методы.&lt;br /&gt;
&lt;br /&gt;
И что приятно, начиная с версии 2.8.5 системы [http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/razrabotka_sobstvennyh_makrosov_i_modulej/novyj_format_rasshireniya_funkcionala/ это можно сделать]! Для этого создаем внутри нашего шаблона папку classes, внутри неё папку modules, в ней папку с именем модуля, например, news, а там - файл class.php, где создаем отдельный класс. Имя класса должно быть 'имямодуля_custom', а имена методов не должны совпадать с именами стандартных методов модуля. Таким образом, получим файл classes/modules/news/class.php с кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Класс пользовательских методов */&lt;br /&gt;
    class news_custom extends def_module {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этот файл можно добавлять свои методы, которые могут быть использованы в шаблоне при помощи вызова $this-&amp;gt;macros('news', 'имя_метода', [массив_параметров_метода] ). Что приятно, в class.php уже не нужно подключать 'use UmiCms\Service;', его уже подключает def_module.&lt;br /&gt;
&lt;br /&gt;
=== Добавление разрешения на выполнение метода ===&lt;br /&gt;
&lt;br /&gt;
Тут тоже понадобиться добавлять разрешения. К счастью, для этого достаточно в той же директории classes/modules/news/ создать файл permissions.php, куда внести тот же код, что ранее использовали в permissions.custom.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$permissions['view'][] =  'newslist';&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомного метода ===&lt;br /&gt;
&lt;br /&gt;
Перенесём наш метод newslist() из кастомных макросов в этот новый класс. Не буду приводить тут его код, он в точности тот же. &lt;br /&gt;
&lt;br /&gt;
Из кастомных макросов этот метод можно убрать, можно также удалить файл /classes/components/news/permissions.custom.php, ведь мы уже добавили разрешения в классы шаблона. В нашем фрагменте шаблона content/home/news.phtml ничего не меняем.&lt;br /&gt;
&lt;br /&gt;
Если набрать в браузере ту же ссылку http://umi.example.com/udata://news/newslist/7/.json (не забываем поменять id ленты новостей, это только у меня он 7), то увидим массив новостей с анонсом, да и на сайте все прекрасно выводится.&lt;br /&gt;
&lt;br /&gt;
=== Создание кастомных событий внутри шаблона ===&lt;br /&gt;
&lt;br /&gt;
До создания собственных событий ещё очень далеко. Просто для общности надо отметить, что события тоже можно создать внутри шаблона, в той же папке /classes/components/news/ в файле events.php.&lt;br /&gt;
&lt;br /&gt;
=== Вызов метода из &amp;quot;чужого&amp;quot; шаблона ===&lt;br /&gt;
&lt;br /&gt;
Шаблонов на сайте может быть несколько, и в одном шаблоне сайта получить доступ к методу из другого шаблона, вообще говоря, нельзя. Но есть хитрый хак. Если запрашивать данные, например, AJAXом через udata:, то можно в строке запроса в конце добавить параметр '?template_id={id шаблона}', и всё получится.&lt;br /&gt;
&lt;br /&gt;
== Собственный класс сайта ==&lt;br /&gt;
&lt;br /&gt;
До сих пор мы рассматривали очень правильный с точки зрения MVC путь создания своих методов. Однако есть более простой и быстрый, но немного менее &amp;quot;канонический&amp;quot; способ, доступный только для PHP-шаблонизатора. Это создание класса расширения шаблонизатора.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим в директории php папку library. В данном случае название может быть любым. А в ней файл PhpExtension.php с вот таким кодом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Далее, открываем файл config.ini, который перед этим создали в папке шаблона, там уже есть настройки для &amp;quot;причёсывания&amp;quot; отдаваемых методами массивов, и добавляем туда 2 строчки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[php-templater]&lt;br /&gt;
extensions[] = &amp;quot;/templates/default/php/library/PhpExtension&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Важно!''' Имя класса в принципе может быть любым, но имя файла, содержащего этот класс, а также путь к файлу, прописанный в конфиге, должны в точности его повторять, вплоть до капитализации.&lt;br /&gt;
&lt;br /&gt;
Поскольку extensions - это массив, понятно, что таких классов расширений можно добавить сколько угодно. Но нам хватит и одного.&lt;br /&gt;
&lt;br /&gt;
Все публичные методы этого класса теперь будут доступны в шаблоне при помощи волшебной переменной $this. Но лучше это посмотреть на примере.&lt;br /&gt;
&lt;br /&gt;
=== Добавление глобальных переменных ===&lt;br /&gt;
&lt;br /&gt;
Ранее мы сделали одну не очень красивую вещь - добавили полученные прямо в шаблоне настройки к массиву $variables, и вынуждены были и дальше передавать их в методе render(), чтобы не потерялись. Значительно лучше было бы создать какие-то глобальные переменные, которые были бы доступны в любом фрагменте нашего шаблона.&lt;br /&gt;
&lt;br /&gt;
Итак, добавляем в наш класс расширения следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
    /** Сервисные классы, которые понадобятся для выполнения методов */&lt;br /&gt;
    use UmiCms\Classes\System\Utils\Captcha\Strategies\GoogleRecaptcha;&lt;br /&gt;
    use UmiCms\Service;&lt;br /&gt;
&lt;br /&gt;
    /** Расширение php шаблонизатора для шаблона default */&lt;br /&gt;
    class PhpExtension extends ViewPhpExtension {&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Инициализирует общие переменные для шаблонов.&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         */&lt;br /&gt;
        public function initializeCommonVariables($variables) {&lt;br /&gt;
            $templateEngine = $this-&amp;gt;getTemplateEngine();&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('domain', $variables['domain']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('lang', $variables['lang']);&lt;br /&gt;
            $templateEngine-&amp;gt;setCommonVar('settings', $this-&amp;gt;requestSettingsContainer($variables));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
         * Запрашивает актуальный объект настроек и возвращает его&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|iUmiObject&lt;br /&gt;
         */&lt;br /&gt;
        public function requestSettingsContainer($variables) {&lt;br /&gt;
            $set = new selector('objects');&lt;br /&gt;
            $set-&amp;gt;types('object-type')-&amp;gt;name('umiSettings', 'settings');&lt;br /&gt;
            $set-&amp;gt;where('domain_id')-&amp;gt;equals($variables['domain-id']);&lt;br /&gt;
            $set-&amp;gt;where('lang_id')-&amp;gt;equals($variables['lang-id']);&lt;br /&gt;
            $set-&amp;gt;limit(0, 1);&lt;br /&gt;
            $settings = $set-&amp;gt;result(); &lt;br /&gt;
            if (is_array($settings)) return $settings[0];&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь использовали методы базового класса ViewPhpExtension для работы с глобальными переменными. Вставим вызов метода initializeCommonVariables() в файл common.phtml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$this-&amp;gt;initializeCommonVariables($variables);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/head') ?&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/header') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/main') ?&amp;gt;&lt;br /&gt;
&amp;lt;?= $this-&amp;gt;render($variables, 'layout/footer') ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь для получения значения этих переменных в любом фрагменте шаблона достаточно написать $this-&amp;gt;getCommonVar('имя переменной'). Например, файл footer.phtml приобретет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$settings = $this-&amp;gt;getCommonVar('settings');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
    &amp;lt;footer&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;span umi:object-id=&amp;quot;&amp;lt;?= $settings-&amp;gt;id ?&amp;gt;&amp;quot; umi:field-name=&amp;quot;copyright&amp;quot;&amp;gt;&amp;lt;?= $settings-&amp;gt;copyright ?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;?= date(&amp;quot;Y&amp;quot;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогичным образом меняем остальные фрагменты шаблона, где используются настройки. Теперь их не надо добавлять к массиву $variables.&lt;br /&gt;
&lt;br /&gt;
=== Получение блоков для главной страницы ===&lt;br /&gt;
&lt;br /&gt;
При помощи класса PhpExtension можем улучшить код ещё одного фрагмента - content/home/index.phtml. Добавляем в класс метод getHomePageBlocks():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает информацию для главной страницы по блокам&lt;br /&gt;
         * @param array $variables глобальные переменные запроса&lt;br /&gt;
         * @return bool|array&lt;br /&gt;
         */&lt;br /&gt;
        public function getHomePageBlocks($variables) {&lt;br /&gt;
            $blocks = [];&lt;br /&gt;
            $hierarchy = umiHierarchy::getInstance(); &lt;br /&gt;
            $children = $hierarchy-&amp;gt;getChildrenTree($variables['pageId'], false, false, 1);&lt;br /&gt;
            foreach ($children as $id =&amp;gt; $val) {&lt;br /&gt;
                $element = $hierarchy-&amp;gt;getElement($id);&lt;br /&gt;
                if ($element instanceof umiHierarchyElement) {&lt;br /&gt;
                    $blocks[$id]['id'] = $element-&amp;gt;id;&lt;br /&gt;
                    $blocks[$id]['name'] = $element-&amp;gt;name;&lt;br /&gt;
                    $blocks[$id]['h1'] = $element-&amp;gt;h1;&lt;br /&gt;
                    $blocks[$id]['altName'] = $element-&amp;gt;altName;&lt;br /&gt;
                    $blocks[$id]['content'] = $element-&amp;gt;content;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return $blocks;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовало бы ещё cmsController::getInstance()-&amp;gt;getResourcesDirectory(); убрать в PhpExtension, для красоты, вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /**&lt;br /&gt;
         * Возвращает путь до директории шаблона&lt;br /&gt;
         * @return bool|string&lt;br /&gt;
         */&lt;br /&gt;
        public function getTemplateDirectory() {&lt;br /&gt;
            return cmsController::getInstance()-&amp;gt;getResourcesDirectory();&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате код content/home/index.phtml станет вполне приличным:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Главная страница:&lt;br /&gt;
 *   - Блок с вступительным текстом&lt;br /&gt;
 *   - Блок &amp;quot;Новости&amp;quot;&lt;br /&gt;
 *   - Блок &amp;quot;Контакты&amp;quot;&lt;br /&gt;
 * Для удаления блока достаточно снять&lt;br /&gt;
 * у соответствующего раздела признак &amp;quot;Отображать в меню&amp;quot;&lt;br /&gt;
 * Для добавления блока надо добавить блок в структуру&lt;br /&gt;
 * раздела и создать в папке content/home файл шаблона&lt;br /&gt;
 * с именем как в поле &amp;quot;Псевдостатический адрес&amp;quot;&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
$blocks = $this-&amp;gt;getHomePageBlocks($variables);&lt;br /&gt;
$resourcesDir = $this-&amp;gt;getTemplateDirectory();&lt;br /&gt;
&lt;br /&gt;
foreach ($blocks as $page) {&lt;br /&gt;
    if (isset($page['altName'])) {&lt;br /&gt;
        if ($resourcesDir &amp;amp;&amp;amp; file_exists($resourcesDir . 'php/content/home/' . $page['altName'] . '.phtml')) echo $this-&amp;gt;render($page, 'content/home/' . $page['altName']);&lt;br /&gt;
        else echo '&amp;lt;div class=&amp;quot;alert alert-danger&amp;quot;&amp;gt;Отсутствует шаблон: ', $resourcesDir, 'content/home/', $page['altName'], '.phtml&amp;lt;/div&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Olga</name></author>
	</entry>
</feed>