Файлы и медиа
Все загруженные файлы (изображения, документы, видео, архивы) хранятся через модель Templite\Cms\Models\File. Изображения автоматически оптимизируются, генерируются ресайзы под именованные размеры и альтернативные форматы (WebP, AVIF).
В админке управление файлами разделено на два раздела:
- Медиа (
/cms/media) — файлы, загруженные через поля блоков и настроек. - Менеджер файлов (
/cms/file-manager) — прямой доступ к публичным файлам с папочной структурой.
Модель File
| Колонка | Назначение |
|---|---|
name | Имя файла |
path | Путь к оригиналу на диске (относительно disk) |
disk | Имя Laravel filesystem disk (public, s3, и т.п.) |
size | Размер в байтах |
mime | MIME-тип |
type | Категория: image, video, document, archive |
parent_id | Для дочерних файлов (если используется) |
folder_id | FK на FileFolder — папка в файловом менеджере |
alt | Alt-текст (для изображений) |
title | Title-атрибут |
sizes | JSON-объект с ресайзами и форматами (см. ниже) |
meta | JSON: width, height, dominant_color и др. |
Структура sizes
{
"thumb": {
"width": 150,
"height": 150,
"original": "files/2026/abc-thumb.jpg",
"webp": "files/2026/abc-thumb.webp",
"avif": "files/2026/abc-thumb.avif"
},
"wide": {
"width": 1920,
"height": 1080,
"original": "files/2026/abc-wide.jpg",
"webp": "files/2026/abc-wide.webp"
}
}Каждый именованный размер содержит ширину/высоту и пути к файлам в разных форматах.
Структура meta
{
"width": 1920,
"height": 1080,
"dominant_color": "#a1b2c3",
...
}meta используется встроенным компонентом <x-cms::image> для подстановки width/height (защита от CLS) и background-color плейсхолдера.
API модели
Получение URL
$file->url; // URL оригинала
$file->url('thumb'); // URL ресайза 'thumb' (оригинальный формат)
$file->url('thumb', 'webp'); // URL ресайза 'thumb' в WebP
$file->url('wide', 'avif'); // URL в AVIFЕсли запрошенный размер/формат отсутствует — возвращается оригинал.
Проверка наличия формата
$file->hasFormat('thumb', 'webp'); // boolGenerated srcset
$file->srcset(); // 'url 150w, url 600w, url 1200w'
$file->srcset('webp'); // WebP-варианты с srcsetТип файла
$file->isImage(); // bool
$file->isVideo(); // bool
$file->isDocument(); // boolУдаление с файлами
$file->deleteWithFiles();Удаляет все ресайзы, форматы, дочерние файлы и саму запись из БД.
Использование в Blade
Компонент <x-cms::image>
Реальная сигнатура:
@props(['file', 'size' => null, 'class' => '', 'loading' => 'lazy'])| Prop | Тип | Дефолт | Назначение |
|---|---|---|---|
:file | File | — | Модель файла |
size | string | null | null | Имя размера (thumb, wide, и т.п.) |
class | string | '' | CSS-классы для <img> |
loading | 'lazy' | 'eager' | 'lazy' | Атрибут <img loading> |
Не preset
В старых версиях документации был preset="..." — это неверно. Правильное имя prop'а — size.
Что делает компонент:
- Рендерит
<picture>с<source>для AVIF и WebP (если форматы сгенерированы), fallback<img>с оригиналом. - Подставляет
width/heightиз$file->meta(защита от CLS). - Использует
$file->meta['dominant_color']какbackgroundплейсхолдера. - Подставляет
altиз$file->altиtitleиз$file->title. - Если
$fileпустой — ничего не рендерит (нет@else).
<x-cms::image :file="$fields['hero']" size="wide" />
<x-cms::image :file="$fields['avatar']" size="thumb" loading="eager" class="rounded" />Ручной рендер
@if ($fields['hero'])
<picture>
@if ($fields['hero']->hasFormat('wide', 'webp'))
<source type="image/webp" srcset="{{ $fields['hero']->url('wide', 'webp') }}">
@endif
<img
src="{{ $fields['hero']->url('wide') }}"
alt="{{ $fields['hero']->alt ?? '' }}"
>
</picture>
@endifДокументы
@if ($fields['document'])
<a href="{{ $fields['document']->url }}" download>
Скачать {{ $fields['document']->name }} ({{ number_format($fields['document']->size / 1024, 0) }} КБ)
</a>
@endifВидео
@if ($fields['promo'])
<video src="{{ $fields['promo']->url }}" controls></video>
@endifЗагрузка и обработка
Что происходит при загрузке изображения
- Файл загружается через UI или REST API в раздел медиа.
- Сохраняется на диск (по умолчанию — public, через Laravel Storage).
- Очередь
images(envCMS_IMAGE_QUEUE, по умолчаниюimages) выполняет обработку:- Intervention Image 3 — ресайз в именованные размеры.
- Spatie Image Optimizer — сжатие через jpegoptim/pngquant/gifsicle.
- Генерация WebP и AVIF (если установлены
cwebpиavifencв системе).
- Все пути ресайзов и форматов записываются в
sizesJSON. metaзаполняется размерами и dominant color.
Очередь работает в контейнере templite-queue (или прода через queue:work). Если очередь не запущена — изображения остаются без ресайзов до обработки.
Размеры по умолчанию
Из config/cms.php:
'default_image_sizes' => [
'thumb' => ['width' => 150, 'height' => 150, 'fit' => 'crop'],
'small' => ['width' => 300, 'height' => null, 'fit' => 'contain'],
'medium' => ['width' => 600, 'height' => null, 'fit' => 'contain'],
'large' => ['width' => 1200, 'height' => null, 'fit' => 'contain'],
],Дополнительные размеры для скриншотов блоков и страниц:
'block_screenshot_sizes' => [
'thumb' => ['width' => 300, 'height' => 200, 'fit' => 'cover'],
'medium' => ['width' => 600, 'height' => null, 'fit' => 'contain'],
],
'page_screenshot_sizes' => [
'thumb' => ['width' => 400, 'height' => 225, 'fit' => 'cover'],
'medium' => ['width' => 960, 'height' => null, 'fit' => 'contain'],
],Для конкретного поля типа img размеры можно переопределить в JSON data поля.
Форматы
'default_image_formats' => ['original', 'webp'],
'default_image_quality' => 85,AVIF включается, если установлен системный avifenc. Без него генерируется только оригинал + WebP.
Пересоздание ресайзов
После изменения настроек размеров или добавления новых форматов — пересоздать ресайзы для всех изображений:
docker exec templite-app php artisan cms:resize-imagesПоддерживаемые форматы
Из config/cms.php:
'allowed_file_types' => [
'image' => ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'],
'video' => ['mp4', 'webm', 'avi'],
'document' => ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'csv'],
'archive' => ['zip', 'rar', '7z', 'tar', 'gz'],
],Максимальный размер загрузки — CMS_MAX_UPLOAD_SIZE в .env (по умолчанию 50 МБ).
Безопасность
Блокировка опасных расширений
'blocked_file_extensions' => [
'php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar',
'sh', 'bash', 'csh', 'ksh', 'zsh',
'exe', 'com', 'bat', 'cmd', 'msi', 'scr', 'pif',
'pl', 'cgi', 'py', 'rb', 'jsp', 'asp', 'aspx',
'htaccess', 'htpasswd',
],Эти расширения блокируются независимо от MIME-типа. Загрузка .php файла с заголовком Content-Type: image/jpeg всё равно отклоняется.
Санитизация SVG
'sanitize_svg' => env('CMS_SANITIZE_SVG', true),По умолчанию включена. При загрузке .svg файла из него удаляются скрипты и event-handler'ы (предотвращение XSS).
Файловая структура
В админке файлы организованы в папки через модель FileFolder (поле folder_id в File). Папки используются для группировки в файловом менеджере, на путях хранения это не отражается (path — это реальный путь к файлу на диске).
Подводные камни
Подводные камни
- Prop в
<x-cms::image>—size, неpreset. Старые версии документации могут содержать неверный prop. - Возможен временной разрыв между загрузкой и обработкой. Очередь
imagesобрабатывает ресайзы асинхронно. Если очередь не запущена — изображение видно как оригинал без ресайзов. Запуск worker'а —php artisan queue:work --queue=images(в production это делает контейнерtemplite-queue). - WebP/AVIF требуют системные утилиты:
cwebp(libwebp) иavifenc(libavif). В Docker-образе Templite они уже установлены. Для bare-metal установок нужно поставить вручную. - SVG санитизируется, что может сломать SVG-анимации или интерактивные элементы. Отключить санитизацию глобально —
CMS_SANITIZE_SVG=falseв.env. File::deleteWithFiles()удаляет все ресайзы и оригинал с диска необратимо. Просто$file->delete()удаляет только запись в БД, оставляя файлы на диске сиротами.- Глобальные настройки и поля шаблонов хранят img/file как ID, не модель. Для рендера через
<x-cms::image>нужно загрузить модель:File::find($global['header_logo']). - Размер
meta['width']/meta['height']— реальные размеры оригинала, не ресайза. Если выводите ресайз — width/height изsizes['<size>'].widthбудут точнее.
Связанные разделы
- Поля — поля
img,file,gallery - Блоки —
<x-cms::image>в шаблонах блоков - Компоненты и библиотеки — встроенный
<x-cms::image> - Глобальные настройки —
$global['logo']как ID файла - Artisan и безопасность —
cms:resize-images