Doit CMS имеет возможности для некоторой кастомизации и переопределения стандартного поведения системы администрирования: столбцы в списке объектов, свои собственные элементы управления, настройка сортировки и так далее.
В большинстве случаев данные возможности не нужны, однако в некоторых случаях они могут пригодиться.
Для настроек в большинстве случаев используется файл ini в папке fields, привязанный к таблице. Например, для таблицы pages это файл /app/fields/pages.ini. Также этот файл можно редактировать на странице добавления объекта при помощи меню Скаффолдинг → Текущий шаблон.
Для указания столбцов, отображаемых в списке элементов, выделен раздел опций [admin.columns]
.
В этом разделе указываются столбцы в виде столбец=Название столбца для администратора
. Несколько столбцов настраиваются на нескольких строках. Например:
[admin.columns]
url=Адрес страницы
title=Заголовок страницы
или
[admin.columns]
title=Название
color=Цвет
price=Стоимость
По умолчанию система сортирует по полю sort
, от меньшего значения к большему. Если необходимо инвертировать направление сортировки, следует указать файле следующее:
[admin.list]
sort_direction=asc
sort_direction
может принимать два значения: asc
и desc
. Эта опция автоматически прикрепляется также к странице сортировки порядка элементов. Следует обратить внимание, что установка опции никак не повлияет на поведение объектов модели и контроллера на самом сайте, для этого есть метод order_by
объекта ActiveRecord
.
Для переопределения поля, по которому производится сортировка (например, по алфавиту), используется параметр sort_field
. При указании это поля сортировка порядка элементов потеряет смысл, так как она основана на манипуляции значениями поля sort
.
К слову, именно эти поля использует система для сортировки путём щелчков по заголовкам таблицы.
Например:
[admin.list]
sort_field=title
Также доступно использование обеих параметров:
[admin.list]
sort_field=title
sort_direction=asc
Эта опция бесполезна в некоторых случаях, например, когда поле стоимости является текстовым (в данном случае сортировка произойдёт по алфавиту) или по текстовому полю даты формата userdate
, в данном случае сортировка
также произойдёт по алфавиту. Эту опцию можно использовать например для того, чтобы вывести непромодерированные записи в верху списка (sort_field=is_active
) или отсортировать по дате последнего изменения (sort_field=updated_at
).
Для сортировки по более сложным полям (даты, цены в текстовых строках, сортировка по нескольким столбцам) необходимо использовать опцию source
с заданными параметрами сортировки.
Также поля в системе администрирования могут сортироваться при помощи GET запросов. Например, параметр /admin/list/pages?sort_field=title
заставит сортироваться по полю title
. Также можно указать направление сортировки при помощи параметра sort_direction
, принимающего значения asc
или desc
.
Администратор может указать, какие столбцы выводить в таблице. Однако иногда нам необходимо переопределить их вывод (допустим, вывести картинку). Для этого используется параметр list=yes
:
[admin.use_model]
list=yes
Данная опция сообщает системе, что для страницы со списком объекто необходимо использовать модель, не отображать данные в чистом виде, а использовать класс ActiveRecord
, описывающий эту таблицу. То есть мы можем вывести в таблице несуществующее столбце link
, а его значение задать в модели:
<?php
class Page extends ActiveRecord
{
function link()
{
if($this->get('link')!=''){
return $this->get('link');
}
if($this->get('url')=='index'){
return '/';
}
return '/' . $this->get('url');
}
}
Другой пример - вывод превью картинки прямо в таблице. Допустим, мы храним изображение в поле image
.
Прописываем в списке столбцов поле image_mini
(не существующее):
[admin.columns]
title=Название
image_mini=Картинка
created_at=Дата создания
[admin.use_model]
list=yes
Далее создаём метод image_mini
в классе модели этой таблицы:
<?php
class Page extends ActiveRecord
{
function image_mini()
{
if($this->get('image')){
return '<img src="' . d()->preview(array($this->get('image'), '200', '100')) . '">';
}
return 'Нет изображения';
}
}
После этого в таблице с результатами будет отображаться картинка. Разумеется, можно указывать и переопределять и существующие поля, и вымышленные, также как это делается для основного сайта и вывода данных в шаблонах.
source
: привязка источника данныхДля сложных случаев (например, необходимо вывести в систему администрирования сильно отфильтрованный список или отсортировать по дате) есть параметр source
, который указывает модель-источник данных.
Он используется следующим образом:
[admin.use_model]
source=d()->News->where('`is_activated` = 1 and `user_id` IS NULL')->order_by_userdate
Также это позволяет делать альтернативные списки, например, создав файл banned_users.ini
в папке fields, и прописав там:
[admin.use_model]
source=d()->User->only('banned')
К подобному файлу можно обращаться по адресу /admin/list/banned_users
, а сами данные будут браться из таблицы users
.
Постраничная навигация появляется в списке объектов автоматически, начиная с 100-го элемента. Однако можно переопределить это число, используя опцию paginator
:
[admin.use_model]
paginator=10
Если система автоматически перебивает пагинатор, заданный в параметре source
, то можно указать paginator=yes
, или другое нечисловое значение. Это нужно для того, чтобы автоматический метод paginate()
, который применит система к этой модели, не был вызван.
[admin.use_model]
source=d()->User->paginate(3)
paginator=yes
На странице редактирования объектов вставлены элементы управления. ini-файл позволяет вставить поля типа small
, rich
, checkbox
и так далее. Иногда бывает нужно вставить свой собственный элемент, например, раскрывающийся
список с собственными элементами или поле выбора цвета.
Система при запросе поля small
вызывает функцию admin_small
. Сама функция не существует в явном виде, зато есть соответствующий шаблон в папке /cms/mod_admin
: _small.html
.
Нам остаётся взять заготовку (small
, select
или что нам ближе), и скопировать её в папку app
или папку нашего модуля в папке app
. Разумеется, его надо переименовать (начинаться он должен на admin_
. Если мы создадим таким образом файл admin_mysuperselect.html
, то получим возможность использовать его в ini - файле:
[admin.fields]
small title "Название"
rich text "Текст"
mysuperselect color "Выберите цвет"
Полученный файл admin_mysuperselect
можно кастомизировать для собственных элементов управления. Сам шаблон использует для этого несколько переменных, таких как d()->title
, d()->name
, d()->value
. Это позволяет сделать такие элементы, как:
Примеры использования можно посмотреть в /cms/mod_admin
, это такие поля, как small
, rich
, checkbox
, checkboxes
, select_table
, которые могут послужить основой или образцом для своих элементов.
Роутер системы Doit CMS предполагает, что при переопределении функции мы можем указать не одно, а несколько параметров.
Например (файл router.init.ini
):
[urls]
...
/news/ content news#show pages#show fosv_show
Это означает, что вместо функции content
будут выполнены несколько других функций подряд.
Применительно к системе администрирования это означает, что мы можем переопределить "родную" функцию admin_save_data
.
Например, так:
[urls]
...
/admin/edit/pages/ admin_save_data do_my_action admin_save_data
Для таблицы pages перед сохранением будет вызываться функция do_my_action()
, которая, например, сделает запись в логе или отправит письмо по электронной почте, и уже после этого выполнит своё обычное предназначение. В этой функции доступны данные $_POST
(так как массив суперглобальный).
Кроме того, можно просто переопределить полностью admin_save_data
, и тогда она вовсе не вызовется.
Аналогично можно прописать действие для конкретного объекта:
[urls]
...
/admin/edit/pages/73 admin_save_data do_my_action admin_save_data
Также можно переопределить данные из массива $_POST
до сохранения. Для этого необходимо прописать в роутере:
[urls]
...
/admin/edit/pages/ content do_my_action admin_edit
Обратите внимание, что переопределяется функция content
.
<?php
function do_my_action()
{
$_POST['data']['title'] = 'Новое значение';
}
Это может быть использовано для того, чтобы удалять изображение при создании превью на этапе сохранения изображения. Вот пример функции, которая удалит файл, сохранив превью:
<?php
function delete_original_image()
{
if(isset($_POST['data']['image'])){
if(substr($_POST['data']['image'],0,9)=='/storage/' && file_exists($_SERVER['DOCUMENT_ROOT'].$_POST['data']['image']) && is_file(($_SERVER['DOCUMENT_ROOT'].$_POST['data']['image']))){
unlink( ($_SERVER['DOCUMENT_ROOT'].$_POST['data']['image']));
}
}
}
Соответственно и вызывать её надо до сохранения.
Более сложный способ - переопределить в роутере свою собственную функцию сохранения и редактирования, со своими шаблонами, и написать свой обработчик форм. Это даст возможность свободно писать тот код, который нужен, и не вписываться в рамки системы.
/admin/edit/pages/ content my_own_code