С версии 2.8.5 в системе появился новый способ организации php-скриптов, расширяющих функционал системы. Теперь для каждого шаблона на сайте можно писать свои кастомные макросы, расширяющие функционал стандартных модулей. При этом не нужно писать все макросы в один файл customMacros.php - можно распределять их по отдельным скриптам, подключая в один главный, так же как это сделано в стандартных модулях. Потом эти скрипты можно легко переносить в другие шаблоны, подключать, поддерживать и вносить необходимые правки.
Структура файлов
Новый формат расположения папок и файлов, относящихся к шаблонам и расширению функциональности сайта, предполагает наличие в корне сайта папки ~/templates/
, в которой, в свою очередь, находятся директории шаблонов (их количество не ограничено) ~/templates/{имя_шаблона}/
. В каждой из них может находиться собственная папка /classes/modules/
, содержащая папки с именами модулей (/content/
, /catalog/
и т.д.), в которые необходимо поместить файл class.php
, который будет подключаться автоматически.
Пример скрипта
Рассмотрим новый формат расширения функциональности на примере модуля Структура:
Для начала, создадим файл class.php
в папке модуля content
того шаблона, который используется на нашем сайте - ~/templates/newTemplate/classes/modules/content/class.php
. В этом файле нам нужно указать, что наш класс будет расширять стандартный класс "def_module
". Имя создаваемого класса должно быть имямодуля_custom.
Важно:
Нельзя использовать в качестве имен классов и методов названия системных классов и методов!Добавим новый макрос:
<?php
class content_custom extends def_module {
public function testMenu() {
$temp = [
'foo' => 'foo',
'bar' => 'bar'
];
return def_module::parseTemplate('', $temp);
}
};
?>
Обратите внимание, что файлы ~/classes/components/custom.php
и ~/classes/components/{имя_модуля}/customMacros.php
продолжают подключаться как и прежде.
Права доступа
Теперь мы можем использовать макрос content::testMenu
в нашем шаблоне. Пока что он доступен только супервайзеру. Для того чтобы открыть макрос всем пользователям - создаём стандартную запись в файле permissions.php
(рекомендуем ознакомиться с Cистемой прав доступа UMI.CMS), в той же директории что и class.php
:
<?php
$permissions['content'][] = 'testMenu';
?>
Обратите внимание на порядок подключения файлов с правами: Первым делом система производит поиск в файле ~/classes/components/{имя_модуля}/permissions.custom.php
, затем в файле ~/classes/components/{имя_модуля}/permissions.php
, и только потом в ~/templates/{имя_шаблона}/classes/modules/{имя_модуля}/permissions.php
.
События
Работа с "Событиями" теперь также доступна в файле ~/templates/{имя_шаблона}/classes/modules/{имя_модуля}/events.php
. Обратите внимание на порядок подключения файлов с перехватчиками событий: Первым делом система производит поиск в файле ~/templates/{имя_шаблона}/classes/modules/{имя_модуля}/events.php
, затем в файле ~/classes/components/{имя_модуля}/custom_events.php
, и затем в ~/classes/components/{имя_модуля}/events.php
.
Такая последовательность подключения файлов даёт разработчику возможность прервать цепочку событий (для этого используется специальное системное исключение (throw new breakException();
), что позволяет "перебить" системные события пользовательскими.
Распределение кода
Теперь, для удобной работы с кодом, мы рекомендуем распределить его по нескольким php-файлам. Допустим, мы создали файл temp.php
в той же директории, что и class.php
. Внесли в него некий код (ещё один макрос):
<?php
class content_custom_temp {
public function testMenu2() {
$temp = [
'foo' => 'foo',
'bar' => 'bar',
'baz' => 'baz'
];
return def_module::parseTemplate('', $temp);
}
};
?>
Затем мы подключаем новый класс content_custom_temp
в файле class.php
- создаём функцию __construct
, в которой принимаем экземпляр класса (в данном случае - экземпляр класса "content
") из переменной $self
:
<?php
class content_custom extends def_module {
public function __construct($self) {
$self->__loadLib("/temp.php", (dirname(__FILE__)));
$self->__implement("content_custom_temp");
}
public function testMenu() {
$temp = [
'foo' => 'foo',
'bar' => 'bar'
];
return def_module::parseTemplate('', $temp);
}
};
?>
И прописываем второй созданный макрос в файле permissions.php
:
<?php
$permissions['content'][] = 'testMenu';
$permissions['content'][] = 'testMenu2';
?>
Теперь оба наших макроса можно использовать в шаблоне сайта.
Обратите внимание, что при использовании на сайте шаблонов нового формата, работа расширений функциональности (PHP) происходит следующим образом: при вызове вашего макроса через протокол udata (site.ru/udata://content/testMenu
) и "напрямую" (site.ru/content/testMenu
), отрабатывать будут те php-скрипты, которые находятся в той же директории (~/templates/{имя_шаблона}/
), что и шаблон, назначенный "Основным" для данного домена.
В случае необходимости вызвать напрямую макрос из шаблона, не назначенного основным - следует добавить к строке вызова параметр "?template_id={идентификатор шаблона в админ-панели}
".
При вызове же макроса на странице, будут отрабатывать php-скрипты, принадлежащие шаблону данной страницы.