В плагинах OctoberCMS обычно мы имеем дело с моделями. Допустим, есть у нас вот такой список моделей как на картинке. Это список моделей Photo
, принадлежащих одной модели Album
. Сделать такой список легко — пара строчек в контроллере и он создастся автоматически.
Как можно заметить, список в данном случае не сильно удобный: у многих фотокарточек нет названия. Через это вообще невозможно понять, где какая фотография находится. В общем, хотелось бы, чтобы в таблице были картинки. Ну и заодно чтоб можно было отметить ту картинку, которая выбрана обложкой альбома.
Список столбцов задается (по умолчанию) в файле columns.yaml
для отображаемой модели. Туда можно добавлять новые столбцы, но их набор довольно ограничен. Зато, как написано на этой же странице документации, можно добавлять свои типы столбцов. И сейчас мы рассмотрим эту возможность, чуть-чуть подробнее, чем в доках.
Начнем со столбца Is Front, в котором мы отметим фотокарточку, выбранную обложкой альбома. Зарегистрируем новый тип столбца в Plugin.php
:
public function registerListColumnTypes() {
return [
'is_front' => [$this, 'evalIsFrontListColumn'],
];
}
Метод registerListColumnTypes()
регистрирует новые типы столбцов и должен возвращать массив с их описанием. В данном случае для нового типа is_front
мы возвращаем массив, в котором указано что значение столбца вычисляется методом evalIsFrontListColumn
, который мы реализуем здесь же, в Plugin.php
. Также вместо массива можно передать инлайн-функцию.
В любом случае, функция-обработчик принимает 3 аргумента и выглядит вот так:
public function evalIsFrontListColumn($value, $column, $record) {
return ($value == $record->id) ? 'Yes' : '';
}
Здесь $value
— это значение поля модели для данной строки списка, $column
— настройки столбца, а $record
— объект модели, для которой вычисляется значение.
Чтобы использовать этот столбец, добавим его в columns.yaml
модели вот так:
front:
label: Front
relation: album
select: front_id
type: is_front
Здесь мы говорим, что добавляем столбец front
, который в качестве значения должен взять поле front_id
из отношения album
(то есть из модели Album
, с которой фотокарточка связана через belongsTo
). Именно значение front_id
и попадет в $value
обработчика столбца. То есть в коде мы сравниваем front_id
и id данной модели фотографии, и если они равны — значит эта фотография и есть обложка альбома.
Теперь посмотрим на реализацию столбца для картинки. Зарегистрируем новый тип столбца:
public function registerListColumnTypes() {
return [
'is_front' => [$this, 'evalIsFrontListColumn'],
'image' => [$this, 'evalImageListColumn'],
];
}
И вот его обработчик:
function evalImageListColumn($value, $column, $record) {
if ($record->has('image')) {
$thumb = $record->image->getThumb(
isset($column->config['width']) ? $column->config['width'] : 200,
isset($column->config['height']) ? $column->config['height'] : 200,
['mode' => 'auto']
);
} else {
// in case the file attachment was manually deleted for some reason
$thumb = '';
}
return "<img src=\"$thumb\" />";
}
Тут все просто: поскольку $record
— это готовая модель фотографии, мы берем картинку, генерируем thumbnail и возвращаем тег <IMG>
. Нам даже не нужны данные из $value
. Стоит обратить внимание на использование объекта $column
, в котором содержатся все настройки столбца. В частности, в $column->config
попадут все поля, которые мы захотим добавить в описание столбца в yaml-файле (мы добавили настройки для ширины и высоты уменьшенной картинки):
id:
label: Photo
type: image
width: 100
height: 100
Обратите внимание, что мы создали столбец с именем id
. Тут есть такой нюанс: все столбцы в списках моделей должны быть реальными полями либо в отображаемой модели, либо в одной из связанных с ней (как в предыдущем столбце is_front
). В данном случае, нам не нужно в обработчике ничего делать со значением столбца, так как картинку мы получаем из самой модели. Поэтому можно просто указать id модели.
И вот что получится в результате:
Так уже удобнее. Все описанное здесь можно увидеть живьём в плагине PhotoAlbums.