К содержанию

MODX Revolution · практика

Как вывести изображение из TV в MODX Revolution

Как вывести TV-изображение в MODX: путь к файлу, pThumb, кадрирование, srcset, обложки в pdoResources и проверка результата.

Для вывода TV-изображения нужны три проверки: поле заполнено, путь ведёт к файлу, а подготовленный размер соответствует месту в макете. Разберём полный путь от создания TV до обложки, карточки и адаптивного srcset.

Загруженная фотография может быть шириной 4000 пикселей, а карточка в каталоге — всего 400. Если отправлять посетителю оригинал, браузер загрузит лишние данные. При этом простая обрезка подходит не всем изображениям: у схемы или скриншота важные детали могут оказаться у края.

Примеры рассчитаны на MODX Revolution с pdoTools, включённым Fenom и установленным pThumb. TV preview_img и чанки с учебными именами нужно создать. Документация компонента — в репозитории pThumb. Эти примеры не требуют пользовательских сниппетов.

Широкое изображение обрезается под карточку или уменьшается с сохранением всего кадра
Для фотографии в карточке и для схемы могут понадобиться разные способы уменьшения.

Создайте TV и заполните поле

В разделе «Элементы» создайте TV preview_img с типом ввода «Изображение». Привяжите его к шаблону страницы, назначьте подходящий источник медиа, затем откройте ресурс и выберите файл. Тип ввода помогает редактору выбрать изображение, но сам по себе не задаёт разметку на странице.

В шаблоне текущего ресурса проверяйте значение перед открытием тега:

{if $_modx->resource.preview_img?}
  <img src="{$_modx->resource.preview_img | escape}" alt="">
{/if}

Этот минимальный пример подходит, если значение TV уже является корректным URL. Проверка ? убирает пустой тег, но не выясняет, существует ли файл. Для окончательной версии понадобятся размер и атрибуты, которые разберём ниже.

Проверьте, что именно хранится в TV

У изображения могут быть разные формы значения. Посмотрите поле ресурса и настройки источника медиа, затем откройте итоговый адрес в браузере. Не добавляйте базовый путь, пока не знаете, содержится ли он в значении.

Как читать значение изображения
ЗначениеЧто проверить
/assets/images/photo.jpgПуть от корня сайта: база уже указана
assets/images/photo.jpgОтносительный URL: результат зависит от base URL страницы
blog/photo.jpgВозможно, путь относительно источника медиа: нужна его база
https://example.com/photo.jpgПолный внешний URL: локальную базу добавлять не нужно

Допустим, источник хранит файлы под /assets/images/, а TV возвращает только blog/photo.jpg. Тогда путь можно собрать явно:

{if $_modx->resource.preview_img?}
  {set $src = '/assets/images/' ~ $_modx->resource.preview_img}
  <img src="{$src | escape}" alt="">
{/if}

Этот фрагмент рассчитан именно на такой формат поля. Если база уже пришла вместе со значением, получится дубль. Не применяйте его к произвольной строке или внешнему адресу. При работе через pdoResources используйте подготовку TV и отдельно проверьте результат.

Получите производный файл через pThumb

Для фотографической обложки с пропорциями 3:2 запросим 960 × 640 пикселей. В этом примере значение TV уже содержит правильный путь:

{if $_modx->resource.preview_img?}
  {set $src = $_modx->resource.preview_img | pthumb : 'w=960&h=640&zc=1&q=80'}
  <img src="{$src | escape}" alt=""
       width="960" height="640" loading="lazy">
{/if}

w и h задают целевой размер, zc=1 включает кадрирование, q задаёт качество для поддерживающих его форматов. Исходник должен подходить по размеру; проверьте фактический результат обработки. Оригинал остаётся исходником, а производные файлы можно использовать для разных мест в макете.

Вычисленный URL сохраняется в $src, а при выводе в HTML-атрибут экранируется. Если адрес пустой или файл не создан, смотрите исходный путь, доступность компонента, права на каталог кэша и журнал ошибок MODX.

Когда обрезать, а когда сохранить весь кадр

Кадрирование удобно для сетки фотографий: карточки сохраняют одинаковую высоту. Для скриншотов, схем и документов обрезка может убрать часть смысла. Когда весь кадр важен, начните с уменьшения только по ширине:

{if $_modx->resource.preview_img?}
  {set $src = $_modx->resource.preview_img | pthumb : 'w=960&q=80'}
  <img src="{$src | escape}"
       alt="Схема подключения оборудования" loading="lazy">
{/if}

Высота такого файла зависит от пропорций оригинала. Не ставьте ему height="640" только потому, что это значение использовалось у соседней обложки. Для стабильного макета добавьте размеры по известным пропорциям или используйте подходящий контейнер, сохраняя весь кадр.

Две ширины для разных экранов

srcset перечисляет варианты файла, а sizes сообщает браузеру, сколько места изображение занимает в макете. В примере ниже картинка на узком экране занимает ширину окна, а на широком — 640 пикселей. Исходник должен быть не меньше 1280 пикселей по ширине.

{if $_modx->resource.preview_img?}
  {set $small = $_modx->resource.preview_img | pthumb : 'w=640&q=80'}
  {set $large = $_modx->resource.preview_img | pthumb : 'w=1280&q=80'}
  <img src="{$small | escape}"
       srcset="{$small | escape} 640w, {$large | escape} 1280w"
       sizes="(max-width: 680px) 100vw, 640px"
       alt="" loading="lazy">
{/if}

Дескрипторы 640w и 1280w должны совпадать с реальной шириной производных файлов. Для маленького оригинала нельзя просто объявить большую ширину в разметке. Подставьте sizes из своего макета: если есть боковые поля или две колонки, 100vw уже не описывает место точно.

Обложки в карточках pdoResources

В списке нужно запросить TV у выбранных ресурсов, а не брать поле открытого раздела. В шаблоне раздела:

{'pdoResources' | snippet : [
  'parents' => $_modx->resource.id,
  'depth' => 0,
  'tpl' => 'wm-image-card',
  'includeTVs' => 'preview_img',
  'prepareTVs' => 1,
  'tvPrefix' => '',
  'limit' => 12
]}

Создайте чанк wm-image-card:

<article class="wm-image-card">
  {if $preview_img?}
    {set $src = $preview_img | pthumb : 'w=640&h=480&zc=1&q=80'}
    <img src="{$src | escape}" alt=""
         width="640" height="480" loading="lazy">
  {/if}
  <h2>
    <a href="{$_modx->makeUrl($id) | escape}">
      {$pagetitle | escape}
    </a>
  </h2>
</article>

includeTVs добавляет поле, prepareTVs подготавливает значение по типу TV, пустой tvPrefix позволяет обращаться к нему как к $preview_img. Согласуйте эти параметры с чанком и источником медиа. Все карточки не должны повторять обложку страницы каталога.

Alt, размеры и отложенная загрузка

Пустой alt подходит декоративной обложке рядом с названием материала. Если изображение передаёт информацию, напишите краткое описание: например, что показывает схема или какая ошибка видна на скриншоте. Имя файла и повтор ключевых слов обычно не помогают понять изображение.

width и height позволяют браузеру заранее учесть пропорции. Указывайте их по результату обработки. loading="lazy" подходит изображениям ниже первого экрана; главную видимую обложку обычно загружают сразу, поэтому этот атрибут для неё убирают.

Те же правила действуют для галерей, но набор изображений уже потребует повторяемых данных — например, MIGX с getImageList. Начать можно с раздела о MIGX.

Что проверить после сохранения

  1. Откройте страницу с обложкой и страницу без неё. Не должно быть пустого img.
  2. Откройте итоговый URL изображения отдельно. Проверьте HTTP-ответ, размеры, резкость и края кадра.
  3. Проверьте первый и повторный запрос: обработка не должна давать ошибку или ссылку на отсутствующий файл.
  4. На узком и широком экране посмотрите выбранный вариант srcset в инструментах браузера.
  5. В списке из двух ресурсов убедитесь, что карточки получают разные обложки из своих TV.
  6. Посмотрите консоль и сетевые ошибки. Если файл не найден, сначала исправьте путь, затем разбирайтесь с обработкой.

Если поле есть в менеджере, но недоступно на странице, проверьте привязку TV к шаблону. Если изображение пропадает из-за условия, отдельно разберите проверку переменных.

Когда нужен второй взгляд

Нужна помощь с вашим сайтом?

Если задача выходит за рамки статьи, расскажите, что хотите исправить или добавить.

Обсудить задачу