Зачем
WordPress нарезает копию картинки на каждый зарегистрированный размер при загрузке, даже если размер нигде не выводится. ACH Thumbnail режет картинку в момент первого запроса из шаблона и только в тех размерах, которые реально нужны. WebP и AVIF создаются фоновой очередью, поэтому страница не ждёт медленного кодирования.
Возможности
- Кроп и ресайз через Imagick или GD.
- WebP и AVIF рядом с каждой миниатюрой, без участия редактора.
- Готовый
<picture>со всеми форматами черезach_picture(). - Retina-варианты
@2x. - Реестр размеров через
ach_register_size(). - Очередь фоновой обработки через WP-Cron — страница не блокируется.
- Если AVIF на сервере недоступен, сайт работает на WebP и исходнике.
- Кэш миниатюр удаляется вместе с вложением.
Пример
add_action('ach_thumbnail_inited', function () {
ach_register_size('PRODUCT', ['w' => 800, 'h' => 600, 'crop' => true]);
});
// в шаблоне
echo ach_picture('PRODUCT', $url, ['alt' => $title]);
Как работает плагин
ACH Thumbnail делает миниатюры по запросу из шаблона. Вы описываете размер один раз, а в шаблоне вызываете функцию с этим размером и адресом картинки. Плагин работает в три шага.
- При первом обращении плагин режет миниатюру в формате исходника (JPG, PNG, GIF или WebP) и кладёт её в папку кэша. Это происходит сразу, во время рендера страницы, через Imagick или GD.
- Сразу после этого плагин ставит в очередь задачи на WebP и AVIF. Их кодирует фоновый обработчик раз в минуту. Страница не ждёт медленного AVIF.
ach_picture()и другие функции вывода добавляют в разметку только те форматы, файлы которых уже лежат на диске. На первом показе посетитель получит JPG, через минуту в разметке появятся AVIF и WebP.
Повторные вызовы с тем же размером и тем же исходником берут готовый файл из кэша и ничего не пересчитывают.
Регистрация размеров
Размеры описывают в теме. Каждый размер получает ключ, по которому его потом зовут из шаблонов. Удобно держать все размеры в отдельном файле и подключать его из functions.php.
// wp-content/themes/my-theme/inc/thumb-sizes.php
defined( 'ABSPATH' ) || exit;
ach_register_size( 'PRODUCT_BIG', [
'w' => 800,
'h' => 600,
'crop' => true,
'quality' => 90,
'retina' => true,
] );
ach_register_size( 'PRODUCT_CARD', [
'w' => 360,
'h' => 270,
'quality_avif' => 60,
'denoise' => 0.8,
] );
ach_register_size( 'BANNER', [
'w' => 1920,
'h' => 600,
'crop' => 'top',
] );
ach_register_size( 'LOGO', [
'w' => 240,
'h' => 0,
'crop' => false,
] );
// functions.php темы
require_once __DIR__ . '/inc/thumb-sizes.php';
Плагин загружается раньше темы, поэтому ach_register_size() можно вызывать прямо в functions.php. Из другого плагина регистрируйте размеры на хуке ach_thumbnail_inited. Он срабатывает на after_setup_theme с приоритетом 1, когда плагин уже готов, а тема загружена.
add_action( 'ach_thumbnail_inited', function () {
ach_register_size( 'PARTNER_LOGO', [ 'w' => 200, 'h' => 100, 'crop' => false ] );
} );
Ключ не зависит от регистра: 'product_big' и 'PRODUCT_BIG' означают один размер, внутри плагин хранит ключи в верхнем регистре. Повторная регистрация с тем же ключом заменяет конфиг целиком. Так дочерняя тема может переопределить размер родительской.
Сигнатура
ach_register_size( string $key, array $config ): void
В $config можно передать любой параметр из таблицы ниже. Эти же параметры принимают все функции вывода, если вместо ключа размера передать массив.
Параметры размера
| Параметр | Тип | По умолчанию | Что делает |
|---|---|---|---|
w, width |
int | 0 | Ширина миниатюры в пикселях. 0 означает «считать по пропорции от высоты». |
h, height |
int | 0 | Высота миниатюры в пикселях. 0 означает «считать по пропорции от ширины». Если не задана ни ширина, ни высота, плагин делает 100×100. |
wh |
string | пусто | Обе стороны одной строкой: '800x600', '800/600', '800:600', '800-600'. |
crop |
bool, string, array | true |
Обрезать картинку точно под размер и с какой стороны. Варианты описаны ниже. |
notcrop |
bool | false |
Принудительно выключает обрезку, перекрывает crop. |
rise_small |
bool | из настроек (true) |
Увеличивать исходник, если он меньше нужного размера. При false миниатюра получится размером с исходник. |
quality, q |
int 1–100 | из настроек (90) | Качество самой миниатюры (JPG, WebP или AVIF при force_format). Для PNG через GD значение делится на 10 и уходит в уровень сжатия. |
quality_webp |
int 1–100 | из настроек (92) | Качество WebP-копии этого размера. |
quality_avif |
int 1–100 | из настроек (75) | Качество AVIF-копии этого размера. Ниже 70 кодировщик переключается на цветовую субдискретизацию 4:2:0, это заметно уменьшает вес превью. От 70 и выше остаётся 4:4:4. |
denoise |
float | 0 | Мягкое размытие после уменьшения. Радиус в пикселях готовой миниатюры, разумные значения 0.5–1. Зернистые кадры (стоп-кадры видео, съёмка на высоком ISO) после него весят в WebP и AVIF заметно меньше. В GD работает приближённо: от одного до трёх проходов сглаживания. |
retina |
bool | false |
Сделать второй вариант с удвоенными сторонами для экранов высокой плотности. Работает в ach_picture(), ach_picture_mq() и ach_picture_preload_link(). |
force_format |
string | пусто | Формат самой миниатюры: jpg, png, gif, webp, avif. Без него миниатюра сохраняется в формате исходника. |
force_lib |
string | пусто | Движок для нарезки: imagick или gd. Без него плагин берёт Imagick, а при его отсутствии GD. |
no_stub |
bool | из настроек (false) |
При пустом источнике вернуть пустую строку вместо заглушки. |
stub_url |
string | из настроек | Своя картинка-заглушка для этого размера. |
attach_id |
int | 0 | ID вложения. Если задан, плагин берёт адрес вложения и подставляет alt из медиатеки. |
post_id, post |
int, WP_Post | пусто | Пост, к которому относится картинка. На саму нарезку не влияет, значение доступно в фильтрах. |
В конфиг размера можно положить и HTML-атрибуты (class, loading и другие). Их подхватят ach_thumb_img() и ach_thumb_a_img(). Для ach_picture() атрибуты передают отдельным аргументом.
Варианты crop
true,1,'1': обрезать по центру.false,'no','none','false': не обрезать. Картинка вписывается в прямоугольникw×hс сохранением пропорций, и одна сторона получится меньше заданной.- Строка с одной стороной:
'top','bottom','left','right','center'. Вторая ось остаётся по центру. - Строка с двумя сторонами через
/,,,:,|, пробел или дефис:'top/left','right bottom'. Порядок осей не важен, плагин сам разберёт, где горизонталь, а где вертикаль. - Массив:
[ 'left', 'top' ].
Если одна из сторон равна 0, обрезка выключается сама: обрезать не под что.
Как устроена retina
С 'retina' => true плагин делает вторую миниатюру с удвоенными шириной и высотой. Это обычный отдельный файл со своим именем в кэше, и для него тоже ставятся в очередь WebP и AVIF. В разметке оба файла попадают в srcset как 1x и 2x. Пока у удвоенного варианта нет WebP или AVIF, соответствующий <source> содержит только 1x.
Чтение и удаление размеров
$config = ach_get_size( 'PRODUCT_BIG' ); // массив конфига или null
$sizes = \Ach_Thumbnail\Plugin::$sizes;
$sizes->has( 'PRODUCT_BIG' ); // bool
$sizes->all(); // [ 'PRODUCT_BIG' => [...], ... ]
$sizes->unregister( 'PRODUCT_BIG' ); // убрать размер
Что можно передать как источник
Второй аргумент всех функций вывода ($src) принимает:
- полный адрес:
https://example.com/wp-content/uploads/2026/05/photo.jpg; - адрес от корня сайта:
/wp-content/uploads/2026/05/photo.jpg; - адрес без протокола:
//example.com/wp-content/uploads/photo.jpg; - ID вложения числом или строкой из цифр;
- объект
WP_Post. Для вложения берётся его файл, для обычной записи берётся миниатюра записи (featured image).
Плагин работает только с файлами на этом же сервере. Адрес он переводит в путь от корня WordPress. Своим считается домен сайта и его поддомены. Картинки с чужих доменов плагин не скачивает, вместо них выводится заглушка.
SVG плагин не обрабатывает и отдаёт исходный адрес как есть. В <img> для SVG плагин добавляет width и height из размера, чтобы браузер знал пропорции слота.
Строковый формат параметров
Вместо ключа размера или массива можно передать строку в стиле query-строки. Этот формат оставлен для совместимости со старыми темами, где размеры хранились в константах.
define( 'THUMB_NEWS', 'w=393 &h=230 &crop=top' );
echo ach_thumb_img( THUMB_NEWS, $url, [ 'alt' => $title ] );
echo ach_picture( 'w=193 &h=112 &crop=false', $url );
Правила разбора:
- Пары разделяются символом
&, пробелы перед&убираются. - Строка считается параметрами, если в ней есть
=или&. Иначе плагин ищет зарегистрированный размер с таким ключом. - Флаги
no_stub,notcrop,rise_small,retinaстановятсяfalseпри значенияхno,0,falseили пустом значении. Любое другое значение даётtrue. Пишите флаг со значением:retina=1. Флаг без значения (&retina) плагин прочитает какfalse. cropсо значениемno,0,falseилиnoneвыключает обрезку. Остальные значения разбираются так же, как в массиве.- Работают все короткие имена:
w,h,wh,q.
Функции для шаблонов
ach_thumb_src()
ach_thumb_src( string|array $size = [], string|int $src = 'notset', ?string $format = null ): string
Создаёт миниатюру, если её ещё нет, и возвращает её адрес. При ошибке возвращает пустую строку.
$size: ключ зарегистрированного размера, массив параметров или строка параметров.$src: адрес картинки, ID вложения илиWP_Post.$format:'webp'или'avif'. Если файл в этом формате уже готов, функция вернёт его адрес. Если ещё нет, вернёт адрес миниатюры в исходном формате.
Если ключ размера не зарегистрирован, функция сделает миниатюру 100×100, а при включённом WP_DEBUG выдаст предупреждение.
$url = ach_thumb_src( 'PRODUCT_BIG', $image_url );
$url = ach_thumb_src( 'PRODUCT_BIG', get_post_thumbnail_id() );
$url = ach_thumb_src( [ 'w' => 100, 'h' => 100 ], $image_url );
$avif = ach_thumb_src( 'PRODUCT_BIG', $image_url, 'avif' );
ach_thumb_img()
ach_thumb_img( string|array $size = [], string|int $src = 'notset', array $attrs = [] ): string
Возвращает тег <img> с миниатюрой в исходном формате. WebP и AVIF эта функция не подключает, для них есть ach_picture().
$attrs сливается с параметрами размера, поэтому здесь можно и задать атрибуты тега, и поправить параметры нарезки для одного вызова. Если alt пустой, плагин берёт alt вложения из медиатеки, а если его нет, то title. Атрибуты width и height плагин не ставит (кроме SVG), чтобы не мешать стилям. Если они нужны для борьбы со сдвигом макета, добавьте их через фильтр ach_thumb__img_attrs.
echo ach_thumb_img( 'PRODUCT_CARD', $image_id, [
'class' => 'card__img',
'alt' => get_the_title(),
] );
Результат:
<img src="https://example.com/wp-content/cache/ach-thumb/3f/1c9e0b7a2d44e3f_360x270.jpg" alt="Название" loading="lazy" decoding="async" class="card__img">
Атрибуты <img>
| Ключ | По умолчанию | Что делает |
|---|---|---|
alt |
пусто | Текст alt. Пустой alt="" в теге сохраняется. |
title |
пусто | Атрибут title. |
class |
пусто | Классы. Плагин оставляет только латиницу, цифры, пробел, _ и -. |
style |
пусто | Встроенный стиль. Двойные кавычки заменяются одинарными, теги вырезаются. |
loading |
lazy |
Для картинок первого экрана передайте eager. |
decoding |
async |
async, sync или auto. |
fetchpriority |
пусто | high, low или auto. |
srcset, sizes |
пусто | Свои значения, если нужен ручной набор. |
data-src, data-srcset |
пусто | Для скриптов ленивой загрузки. |
attr |
пусто | Произвольная строка атрибутов, вставляется в тег без обработки: 'attr' => 'data-zoom="1" itemprop="image"'. |
ach_thumb_a_img()
ach_thumb_a_img( string|array $size = [], string|int $src = 'notset', array $attrs = [] ): string
Возвращает <a><img></a>. Ссылка ведёт на исходную картинку, это удобно для галерей с увеличением. Атрибуты <img> те же, что у ach_thumb_img(). Для ссылки есть свои ключи: a_class, a_style, a_attr (произвольная строка), rel, target, download.
echo ach_thumb_a_img( 'GALLERY_THUMB', $image_id, [
'alt' => $caption,
'a_class' => 'gallery__link',
'a_attr' => 'data-fancybox="gallery"',
] );
ach_picture()
ach_picture( string|array $size = [], string|int $src = 'notset', array $attrs = [], array $picture_attrs = [] ): string
Основная функция вывода. Возвращает <picture> с источниками AVIF и WebP и запасным <img>. <source> появляется только для того формата, файл которого уже есть на диске. При первом показе внутри будет один <img>, после работы очереди добавятся оба формата.
$attrs: атрибуты<img>. По умолчанию плагин ставитloading="lazy"иdecoding="async", ваши значения их перекрывают.srcплагин всегда ставит сам. Еслиaltне передан, берётся alt вложения. Атрибут со значениемtrueвыводится без значения, пустые атрибуты пропускаются (кромеalt).$picture_attrs: атрибуты самого<picture>, напримерclassилиdata-*.
Параметры нарезки здесь задаются только через $size. Если ключ размера не зарегистрирован, функция вернёт пустую строку.
echo ach_picture( 'PRODUCT_BIG', get_post_thumbnail_id(), [
'alt' => get_the_title(),
'class' => 'product__img',
], [ 'class' => 'product__picture' ] );
Результат после работы очереди (размер с retina):
<picture class="product__picture">
<source srcset=".../3f/1c9e0b7a2d44e3f_800x600.avif 1x, .../a0/77d1e2c3b4a5f60_1600x1200.avif 2x" type="image/avif">
<source srcset=".../3f/1c9e0b7a2d44e3f_800x600.webp 1x, .../a0/77d1e2c3b4a5f60_1600x1200.webp 2x" type="image/webp">
<img src=".../3f/1c9e0b7a2d44e3f_800x600.jpg" loading="lazy" decoding="async" alt="Название"
srcset=".../3f/1c9e0b7a2d44e3f_800x600.jpg 1x, .../a0/77d1e2c3b4a5f60_1600x1200.jpg 2x" class="product__img">
</picture>
Для главной картинки первого экрана отключите ленивую загрузку:
echo ach_picture( 'HERO', $hero_id, [
'alt' => $hero_title,
'loading' => 'eager',
'fetchpriority' => 'high',
] );
ach_picture_mq(): разные размеры под разные экраны
ach_picture_mq( array $sources, string|int|null $src = null, array $attrs = [], array $picture_attrs = [] ): string
Строит один <picture> из нескольких размеров с медиазапросами. Каждый элемент $sources это массив с ключами:
size: ключ размера или массив параметров (обязательный);media: медиазапрос илиnull;src: свой источник для этой записи (необязательный). Без него берётся общий$src.
Браузер выбирает первый подходящий <source>, поэтому порядок важен: узкие экраны пишите раньше. Запись с 'media' => null считается основной, её миниатюра идёт в <img>. Если такой записи нет, в <img> попадёт последняя. Для каждой записи с медиазапросом плагин выводит источники AVIF и WebP (если готовы) и ещё один <source> в исходном формате, чтобы браузеры без новых форматов тоже получили нужный размер.
echo ach_picture_mq( [
[ 'size' => 'PRODUCT_MOB', 'media' => '(max-width: 600px)' ],
[ 'size' => 'PRODUCT_BIG', 'media' => null ],
], $image_id, [ 'alt' => get_the_title() ] );
Разные исходники для телефона и компьютера, например два поля ACF:
echo ach_picture_mq( [
[ 'size' => 'HERO_MOB', 'media' => '(max-width: 768px)', 'src' => get_field( 'bg_mob' ) ],
[ 'size' => 'HERO', 'media' => null, 'src' => get_field( 'bg' ) ],
], null, [
'alt' => get_the_title(),
'loading' => 'eager',
'fetchpriority' => 'high',
] );
ach_picture_preload_link(): прелоад картинки LCP
ach_picture_preload_link( string|array $size = [], string|int $src = 'notset', array $attrs = [] ): string
Возвращает <link rel="preload" as="image"> для главной картинки первого экрана. Браузер начинает качать её сразу при разборе <head>, не дожидаясь тега в теле страницы. Функция сама выбирает лучший готовый формат в порядке AVIF, WebP, исходный и ставит правильный type. Для размеров с retina добавляется imagesrcset с 1x и 2x, если удвоенный вариант в выбранном формате уже готов.
Ключи $attrs:
media: медиазапрос, чтобы грузить разные картинки на разных экранах;imagesizes: выражение sizes, например100vw;fetchpriority: по умолчаниюhigh;crossorigin: если картинка отдаётся с другого домена.
Вызов должен попасть в <head>, поэтому его удобно повесить на wp_head:
add_action( 'wp_head', function () {
if ( ! is_front_page() ) {
return;
}
$mob = get_field( 'bg_mob', get_option( 'page_on_front' ) );
$desk = get_field( 'bg', get_option( 'page_on_front' ) );
echo ach_picture_preload_link( 'HERO_MOB', $mob, [ 'media' => '(max-width: 768px)' ] );
echo ach_picture_preload_link( 'HERO', $desk, [ 'media' => '(min-width: 769px)' ] );
}, 1 );
Размер и источник в прелоаде должны совпадать с теми, что выводятся на странице. Иначе браузер скачает две разные картинки.
ach_thumb_image_set(): фон через CSS
ach_thumb_image_set( string|array $size = [], string|int $src = 'notset' ): string
Возвращает значение для background-image. Когда готовы AVIF или WebP, это image-set() со всеми форматами и исходником в конце. Пока готов только исходный формат, функция вернёт обычный url(). Адреса внутри обёрнуты в одинарные кавычки, поэтому значение можно вставлять в атрибут style с двойными кавычками.
<section class="promo" style="background-image: <?= ach_thumb_image_set( 'BANNER', $bg_id ); ?>;">
...
</section>
Результат:
image-set(url('.../9b/4e1d..._1920x600.avif') type('image/avif'), url('.../9b/4e1d..._1920x600.webp') type('image/webp'), url('.../9b/4e1d..._1920x600.jpg'))
Если нужно подстраховать совсем старые браузеры, поставьте перед ним обычное объявление. Браузер, который не понимает image-set(), оставит первое:
<div class="hero" style="
background-image: url('<?= esc_url( ach_thumb_src( 'BANNER', $bg_id ) ); ?>');
background-image: <?= ach_thumb_image_set( 'BANNER', $bg_id ); ?>;"></div>
ach_thumb(): данные последней миниатюры
ach_thumb(): ?\Ach_Thumbnail\Make_Thumb
Возвращает объект последней созданной миниатюры. Из него можно взять реальные размеры, путь и адрес файла.
$url = ach_thumb_src( 'LOGO', $logo_id );
$thumb = ach_thumb();
printf(
'<img src="%s" width="%d" height="%d" alt="">',
esc_url( $url ),
$thumb->width,
$thumb->height
);
Полезные свойства: width, height, thumb_url, thumb_path, src (исходник), args (разобранные параметры) и metadata. В metadata->cache лежит found, если файл взят из кэша, и created, если создан сейчас. В metadata->lib записан движок, в orig_width и orig_height размеры исходника (заполняются при создании).
Служебные функции
ach_get_size( string $key ): ?array: конфиг размера илиnull.ach_thumb_opt(): текущие настройки, напримерach_thumb_opt()->quality_avifилиach_thumb_opt()->cache_dir.ach_thumb_cache(): объект для работы с кэшем (методы описаны ниже).ach_thumb_queue(): объект очереди WebP и AVIF.ach_thumbnail(): главный объект плагина.
Если тема должна работать и без плагина, объявите заглушки в functions.php:
if ( ! function_exists( 'ach_picture' ) ) {
function ach_picture( $size = [], $src = '', $attrs = [], $picture_attrs = [] ) {
$url = is_numeric( $src ) ? wp_get_attachment_url( $src ) : $src;
return $url ? '<img src="' . esc_url( $url ) . '" alt="' . esc_attr( $attrs['alt'] ?? '' ) . '">' : '';
}
}
Очередь WebP и AVIF
Когда задача попадает в очередь
Сразу после создания миниатюры плагин проверяет три условия: формат включён в настройках, сервер умеет его кодировать, файла ещё нет. Если всё сходится, задача записывается в таблицу {префикс}ach_thumb_queue. Качество берётся из quality_webp и quality_avif размера, а если их нет, из настроек плагина.
- Для миниатюр JPG и PNG ставятся обе задачи: WebP и AVIF.
- Для миниатюр WebP ставится только AVIF. Сама миниатюра уже в WebP, отдельная копия не нужна.
- Для GIF копии не делаются.
Одна пара «файл + формат» хранится в очереди один раз. Если задача когда-то упала, а миниатюру потом создали заново, задача оживает с нулём попыток.
Кто обрабатывает очередь
Обработчик висит на WP-Cron: событие ach_thumb_queue_worker с интервалом в одну минуту (ach_thumb_minute). Событие регистрируется при активации плагина и снимается при деактивации. Если расписание потерялось (например, плагин доставили на сервер копированием файлов), плагин восстановит его сам при первом заходе в админку или запуске крона.
За один запуск обработчик:
- берёт блокировку через MySQL
GET_LOCK. Если другой обработчик уже работает, этот запуск пропускается. Блокировка снимается сама, если процесс упал; - возвращает в работу задачи, которые висят в статусе
processingдольше 10 минут; - забирает задачи пачками, сначала все WebP, потом AVIF. WebP кодируется быстрее, и страница раньше получает хоть какой-то лёгкий формат;
- держит одновременно не больше
worker_max_parallelпроцессов кодирования. Закончился один, стартует следующий; - работает, пока не истратит 85% от
max_execution_time. Если ограничение не задано (как в CLI), бюджет 50 секунд; - снимает процесс кодирования, который работает дольше 120 секунд, и засчитывает задаче неудачную попытку.
Готовая задача удаляется из таблицы. Неудачная получает +1 к счётчику попыток и возвращается в очередь. После трёх неудач задача получает статус failed и больше не берётся. Текст ошибки сохраняется, его видно на вкладке «Очередь» и в wp ach-thumb queue status.
WP-Cron в WordPress запускается только при заходе посетителя. На сайте с малым трафиком или на тестовой копии очередь будет стоять. Настройте системный крон и отключите ленивый запуск:
# crontab
* * * * * curl -s "https://example.com/wp-cron.php?doing_wp_cron" > /dev/null 2>&1
# или через WP-CLI
* * * * * cd /var/www/example.com && wp cron event run --due-now > /dev/null 2>&1
// wp-config.php
define( 'DISABLE_WP_CRON', true );
Чем кодируются WebP и AVIF
Плагин пробует кодировщики по порядку.
- sharp (библиотека libvips для Node.js). Плагин запускает поставляемый с ним скрипт
tools/sharp-cli/bin/ach-encode.mjsотдельным процессом. Нужны Node.js 18 или новее, установленный модуль sharp вtools/sharp-cli/node_modulesи разрешённые в PHPexec()иproc_open(). Только с sharp обработчик кодирует несколько файлов параллельно. - Imagick, если sharp недоступен. Файлы кодируются по одному, в самом PHP-процессе обработчика. WebP работает на любой версии ImageMagick. AVIF плагин включает только на ImageMagick 7 и новее: шестая версия портит прозрачность и качество.
GD для WebP и AVIF не используется, он нужен только для нарезки самой миниатюры, когда нет Imagick. Если ни sharp, ни Imagick не умеют AVIF, плагин просто не ставит такие задачи, а на странице плагина и в списке плагинов показывает предупреждение.
Параметры кодирования:
- WebP через sharp: заданное качество, effort 6, альфа-канал без потерь, smartSubsample. Через Imagick:
webp:method=6, альфа 100. - AVIF через sharp: заданное качество, effort 7, субдискретизация 4:2:0 при качестве ниже 70 и 4:4:4 от 70. Через Imagick: те же пороги субдискретизации, скорость 2 (5 для картинок с прозрачностью).
Файл пишется во временный .tmp и переименовывается после успешной записи, поэтому недописанный файл в разметку не попадёт.
Путь к Node плагин ищет через command -v node, затем в /usr/local/bin/node и /usr/bin/node. Результат поиска кэшируется на час. Если вы поставили Node после установки плагина, нажмите «Сбросить кэш определения Node» на вкладке «Дашборд». Node, поставленный через nvm в домашнюю папку пользователя, PHP-FPM обычно не видит: ставьте системный Node или сделайте ссылку в /usr/local/bin.
Нагрузка на сервер
Три настройки управляют нагрузкой фоновой генерации. На качество файлов они не влияют.
worker_max_parallel(1–5, по умолчанию 2): сколько процессов кодирования работает одновременно.encode_threads(1–8, по умолчанию 1): сколько потоков libvips получает один процесс.encode_nice(по умолчанию включено): запускать кодировщик черезnice -n 19иionice -c3, если эти утилиты есть на сервере.
Обработчик занимает примерно «параллельных × потоков» ядер на низком приоритете.
Кэш
Где лежат файлы
По умолчанию кэш лежит в wp-content/cache/ach-thumb/. Файлы разложены по 256 подпапкам с именами от 00 до ff, чтобы в одной папке не скапливались десятки тысяч файлов.
wp-content/cache/ach-thumb/
├── 3f/
│ ├── 1c9e0b7a2d44e3f_800x600.jpg миниатюра
│ ├── 1c9e0b7a2d44e3f_800x600.webp копия WebP
│ ├── 1c9e0b7a2d44e3f_800x600.avif копия AVIF
│ └── 1c9e0b7a2d44e3f_800x600.meta служебный JSON
├── a0/
│ └── 77d1e2c3b4a5f60_1600x1200.jpg retina-вариант
└── stub_1c9e0b7a2d44e3f_800x600.jpg заглушка
Имя файла строится так: {хэш}_{ширина}x{высота}{суффиксы}.{расширение}. Суффиксы: _notcrop без обрезки, _top, _bottom, _left или _right при обрезке со стороны, _notrise при запрете увеличения. Хэш считается из пути исходника, сторон, обрезки, качества и времени изменения файла исходника. Если у размера заданы quality_webp, quality_avif или denoise, они тоже входят в хэш.
Рядом с каждой миниатюрой лежит файл .meta с адресом исходника, временем его изменения, размерами, обрезкой, качеством и временем создания. По нему плагин точно находит все файлы одной картинки.
Когда кэш обновляется сам
- Вы поменяли параметры размера (стороны, обрезку, качество). Хэш меняется, плагин создаёт новые файлы при следующем обращении.
- Вы перезалили файл исходника под тем же именем. Меняется время изменения файла, а с ним и хэш. Старые файлы остаются на диске, их убирает поиск сирот (см. ниже).
- Вы удалили вложение из медиатеки. Плагин удаляет все миниатюры этой картинки во всех размерах и форматах и снимает связанные задачи очереди.
Имя файла меняется вместе с содержимым, поэтому файлам кэша можно ставить кэширование в браузере на год. На вкладке «Дашборд» плагин проверяет заголовок Cache-Control у одного из файлов и подсказывает, если он не настроен.
# nginx
location ~* /wp-content/cache/ach-thumb/.+\.(jpe?g|png|gif|webp|avif)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
access_log off;
}
# Apache, .htaccess в папке wp-content/cache/ach-thumb/
<IfModule mod_headers.c>
<FilesMatch "\.(jpe?g|png|gif|webp|avif)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
</IfModule>
Как чистить кэш
- Поиск сирот: вкладка «Кэш», кнопка «Найти и удалить orphan-thumb’ы», или
wp ach-thumb cleanup orphans. Плагин читает все.metaи удаляет файлы картинок, исходник которых удалён или перезалит. На большом кэше это занимает время. - Одна картинка:
wp ach-thumb cache rm <адрес или ID>илиach_thumb_cache()->clear_img_cache( $url_or_id ). - Заглушки: кнопка «Удалить заглушки» или
wp ach-thumb cache rm --stubs. Удаляет все файлыstub_*. - Весь кэш: кнопка «Очистить ВЕСЬ кэш» или
wp ach-thumb cache rm --thumbs. Вместе с файлами плагин очищает и очередь. Миниатюры создадутся заново при следующем показе, WebP и AVIF снова встанут в очередь.
Удалять плагин разрешает только папку, в пути которой есть слово cache или thumb и которая лежит глубже трёх уровней от корня. Это защита от ошибки в настройках.
При удалении плагина через админку стираются его настройки, таблица очереди и папка wp-content/cache/ach-thumb.
Заглушки
Если источник пустой или файл не читается, плагин выводит заглушку. По умолчанию это no_photo.jpg из папки плагина, нарезанный под нужный размер. Файлы заглушек начинаются с stub_ и лежат в корне папки кэша. Свою заглушку задают параметром размера stub_url или опцией stub_url через фильтр ach_thumb__default_options. SVG-заглушка отдаётся как есть, без нарезки. Параметр no_stub убирает заглушку только для пустого источника: функция вернёт пустую строку.
Ограничение времени на странице
Нарезка миниатюр идёт прямо во время рендера. Чтобы страница с сотней новых картинок не упала по таймауту, у плагина есть лимит stop_creation_sec (по умолчанию 20.5 секунды от начала запроса). После него плагин перестаёт резать новые миниатюры и отдаёт адреса исходников, а в лог пишет одно предупреждение. На следующих показах оставшиеся миниатюры доделаются.
Страница настроек
Страница находится в разделе «Настройки → ACH Thumbnail» и доступна пользователям с правом manage_options. На ней шесть вкладок.
Дашборд
- версия плагина и PHP;
- диагностика sharp: есть ли скрипт, установлен ли модуль, разрешён ли
exec(), где найден Node. Здесь же кнопка «Сбросить кэш определения Node»; - Imagick: версия и поддержка WebP и AVIF;
- GD: загружен или нет;
- итоговая поддержка WebP и AVIF;
- время следующего запуска обработчика очереди;
- счётчики очереди и объём кэша;
- проверка заголовка
Cache-Controlна файлах кэша и готовые настройки для nginx и Apache.
Настройки
| Поле | Опция | По умолчанию |
|---|---|---|
| Качество JPEG | quality |
90 |
| Качество WebP | quality_webp |
92 |
| Качество AVIF | quality_avif |
75 |
| Генерировать WebP | generate_webp |
да |
| Генерировать AVIF | generate_avif |
да |
| Параллельных encode-процессов | worker_max_parallel |
2 |
| Потоков на один encode | encode_threads |
1 |
| Низкий приоритет encode | encode_nice |
да |
| Лимит синхронной генерации, сек | stop_creation_sec |
20.5 (не больше 95% от max_execution_time) |
| Период автоочистки кэша, дней | auto_clear_days |
30 |
| Увеличивать мелкие исходники | rise_small |
да |
| Не показывать заглушку при ошибке | no_stub |
нет |
| Режим отладки | debug |
нет |
Режим отладки отключает проверку кэша: миниатюра пересоздаётся при каждом обращении. Включайте его только на время разбора проблемы.
Поле «Период автоочистки кэша» в этой версии сохраняется, но плановой автоочистки нет. Для регулярной уборки поставьте в системный крон wp ach-thumb cleanup orphans.
Настройки хранятся в опции ach_thumbnail (в мультисайте в опции сети).
Настройки из кода
Настройки можно задать фильтром ach_thumb__default_options. Если фильтр подключён, плагин игнорирует сохранённые в базе значения, а вкладка «Настройки» показывает сообщение вместо формы. Плагин читает настройки при своей загрузке, раньше темы. Поэтому фильтр кладут в must-use плагин, из functions.php темы он не сработает.
// wp-content/mu-plugins/ach-thumbnail-config.php
add_filter( 'ach_thumb__default_options', function ( $opts ) {
$opts['quality'] = 88;
$opts['quality_webp'] = 90;
$opts['quality_avif'] = 70;
$opts['worker_max_parallel'] = 3;
$opts['stub_url'] = '/wp-content/themes/my-theme/img/no-photo.png';
return $opts;
} );
Через фильтр доступны и две опции, которых нет в форме: cache_dir (абсолютный путь к папке кэша) и cache_dir_url (её адрес). Если задать только путь внутри wp-content, адрес плагин вычислит сам.
Очередь
Счётчики задач по статусам, кнопки «Запустить worker сейчас», «Удалить failed-задачи» и «Очистить ВСЮ очередь», и таблица последних 50 ошибок с текстом ошибки и числом попыток.
Размеры
Таблица зарегистрированных размеров: ключ, стороны, обрезка, качество JPEG, WebP и AVIF, retina и прочие параметры. Значения из настроек плагина показаны серым, значения, заданные в размере, жирным. У каждого размера есть кнопка «Сгенерировать для всех» (см. «Массовая генерация»).
Прогрев
Запуск обхода страниц сайта с выбором типов записей, паузой и лимитом, статус текущего прогона и кнопка остановки (см. «Прогрев страниц»).
Кэш
Объём кэша и кнопки: поиск сирот, удаление заглушек, полная очистка.
Массовая генерация
Массовая генерация создаёт миниатюры одного размера для всех картинок медиатеки. Это удобно после добавления нового размера, чтобы первые посетители не ждали нарезки.
В выборку попадают вложения с типом image/jpeg, image/png и image/gif, по порядку ID. Для каждого плагин сразу режет миниатюру (и retina-вариант, если он включён в размере), а WebP и AVIF ставит в очередь. Ошибки по отдельным файлам не останавливают процесс, они попадают в отчёт.
- Из админки: вкладка «Размеры», кнопка «Сгенерировать для всех». Браузер обрабатывает картинки пачками по 10 и показывает прогресс. Закрывать вкладку до конца нельзя.
- Из консоли:
wp ach-thumb bulk PRODUCT_BIG. Флаг--batchзадаёт размер пачки (1–100, по умолчанию 10),--offsetпозволяет продолжить с места остановки.
После массовой генерации в очереди окажется много задач. Следите за ней через wp ach-thumb queue status или разберите её сразу командой wp ach-thumb queue work.
Прогрев страниц
Массовая генерация знает только медиатеку. Прогрев обходит сами страницы сайта, поэтому создаёт ровно те миниатюры, которые выводят шаблоны, включая картинки из полей и настроек темы.
Список адресов собирается так: главная, все опубликованные записи выбранных типов, архивы этих типов. Если типы не выбраны, берутся все публичные типы, кроме вложений. Свои адреса добавляются фильтром ach_thumb__warm_urls.
Для каждого адреса плагин делает GET-запрос с агентом ach-thumb-warmer/1.0 и таймаутом 30 секунд. Шаблон рендерится, функции плагина режут миниатюры и ставят WebP и AVIF в очередь. Потом плагин ищет в ответе элементы с атрибутом data-block. Это блоки, которые тема догружает через AJAX. Для каждого такого блока плагин отправляет POST на /wp-admin/admin-ajax.php с полями action=loadBlock, block и всеми остальными data-* атрибутами элемента. Имя действия меняется фильтром ach_thumb__warm_async_action.
Запуск из админки (вкладка «Прогрев») ставит разовое событие WP-Cron ach_thumb_warm_event. Обход начнётся при следующем срабатывании крона и пойдёт в его процессе, без нагрузки на запросы посетителей. Страница статуса обновляется каждые 5 секунд и показывает прогресс, число обработанных блоков, ошибки и текущий адрес. Кнопка «Прервать прогрев» останавливает обход после текущей страницы. Статус хранится в опции ach_thumb_warm_status.
Из консоли тот же обход идёт синхронно, с прогресс-баром:
wp ach-thumb warm
wp ach-thumb warm --types=page,post,product --delay=0.5
wp ach-thumb warm --limit=10
Команды WP-CLI
Все команды вызываются как wp ach-thumb ....
| Команда | Что делает |
|---|---|
wp ach-thumb info |
Версия, PHP, наличие Imagick и GD, поддержка WebP и AVIF, пути к кэшу и заглушке, качество, объём кэша, состояние очереди. |
wp ach-thumb queue work [--max=<n>] |
Обработать очередь сейчас. Без --max работает, пока есть задачи и не вышло время. Если обработчик уже запущен кроном, команда выдаст предупреждение и выйдет. |
wp ach-thumb queue status |
Число задач по статусам и десять последних ошибок. |
wp ach-thumb queue clear [--failed] |
Очистить всю очередь или, с --failed, только упавшие задачи. |
wp ach-thumb cache rm <url|id> |
Удалить все миниатюры одной картинки по адресу или ID вложения. |
wp ach-thumb cache rm --stubs |
Удалить заглушки. |
wp ach-thumb cache rm --thumbs |
Удалить весь кэш и очистить очередь. |
wp ach-thumb cache stats |
Число файлов, число картинок (по .meta), объём. |
wp ach-thumb cleanup orphans |
Удалить миниатюры, исходник которых удалён или изменён. |
wp ach-thumb sizes list |
Таблица зарегистрированных размеров. |
wp ach-thumb bulk <KEY> [--batch=<n>] [--offset=<n>] |
Массовая генерация размера для медиатеки. |
wp ach-thumb warm [--types=<list>] [--delay=<sec>] [--limit=<n>] |
Прогрев обходом страниц. --types через запятую, --delay пауза между страницами (по умолчанию 1 секунда, можно дробную), --limit ограничение числа записей. |
Типовая последовательность после добавления нового размера:
wp ach-thumb sizes list
wp ach-thumb bulk PRODUCT_CARD --batch=25
wp ach-thumb queue work
wp ach-thumb queue status
Хуки для разработчиков
Действия (actions)
| Хук | Когда срабатывает | Аргументы |
|---|---|---|
ach_thumbnail_inited |
На after_setup_theme с приоритетом 1. Место для регистрации размеров из плагинов. |
$options (объект настроек) |
ach_thumb_created |
После того как миниатюра создана и записана на диск. На этом хуке плагин сам ставит задачи WebP и AVIF. | $thumb_path, $make_thumb |
ach_thumb_worker_tick_done |
В конце каждого запуска обработчика очереди. | $processed (сколько задач готово), $elapsed (секунды), $done_srcs (массив адресов исходников, для которых за этот запуск появились новые форматы) |
ach_thumb_worker_tick_done удобен, если перед сайтом стоит страничный кэш. Пока WebP и AVIF не готовы, в сохранённую страницу попадает разметка только с JPG. Подписчик может найти страницы с этими картинками и сбросить только их:
add_action( 'ach_thumb_worker_tick_done', function ( $processed, $elapsed, $done_srcs = [] ) {
foreach ( $done_srcs as $src ) {
$attachment_id = attachment_url_to_postid( $src );
if ( ! $attachment_id ) {
continue;
}
$parent_id = wp_get_post_parent_id( $attachment_id );
if ( $parent_id ) {
my_page_cache_purge_url( get_permalink( $parent_id ) ); // функция вашего кэша
}
}
}, 10, 3 );
Ещё два хука служебные: ach_thumb_queue_worker (событие крона очереди) и ach_thumb_warm_event (событие крона прогрева). Вызывать их вручную не нужно.
Фильтры (filters)
| Фильтр | Что фильтрует | Аргументы |
|---|---|---|
ach_thumb__default_options |
Настройки плагина целиком. Отключает форму настроек в админке. Подключать из must-use плагина. | $options |
ach_thumb_default_args |
Значения параметров по умолчанию для всех вызовов. | $default_args |
ach_thumb__set_args |
Параметры одного вызова после разбора. | $args, $make_thumb, $raw_args |
pre_ach_thumbnail_src |
Перехват до нарезки. Непустая строка из фильтра становится адресом миниатюры, плагин ничего не режет. | '', $make_thumb |
ach_thumb__src |
Итоговый адрес миниатюры. | $src, $args |
ach_thumb__img_attrs |
Атрибуты <img> в ach_thumb_img() и ach_thumb_a_img(). |
$attrs, $args, $make_thumb |
ach_thumb__img |
Готовый тег <img>. |
$html, $attrs, $args |
ach_thumb__a_img_attrs |
Атрибуты ссылки в ach_thumb_a_img(). |
$attrs, $args, $make_thumb |
ach_thumb__a_img |
Готовый <a><img></a>. |
$html, $args, $attrs |
ach_thumb__make_file_name |
Имя файла миниатюры в кэше. | $file_name, $data, $make_thumb |
ach_thumb__file_sub_dir |
Подпапка в кэше (по умолчанию два последних символа хэша). | $sub_dir, $data, $make_thumb |
ach_thumb__warm_urls |
Список адресов для прогрева. | $urls, $types |
ach_thumb__warm_async_action |
Имя AJAX-действия для блоков data-block при прогреве. По умолчанию loadBlock. |
$action, $block |
Примеры:
// Всем миниатюрам по умолчанию качество 85 и декодирование auto
add_filter( 'ach_thumb_default_args', function ( $args ) {
$args['quality'] = 85;
$args['decoding'] = 'auto';
return $args;
} );
// width и height у <img> из ach_thumb_img() против сдвига макета
add_filter( 'ach_thumb__img_attrs', function ( $attrs, $args, $thumb ) {
if ( $thumb->width && $thumb->height ) {
$attrs['width'] = $thumb->width;
$attrs['height'] = $thumb->height;
}
return $attrs;
}, 10, 3 );
// Добавить в прогрев страницы рубрик
add_filter( 'ach_thumb__warm_urls', function ( $urls ) {
foreach ( get_terms( [ 'taxonomy' => 'category', 'hide_empty' => true ] ) as $term ) {
$urls[] = get_term_link( $term );
}
return $urls;
} );
Работа с кэшем и очередью из кода
Методы объекта ach_thumb_cache():
clear_img_cache( $url_or_id ): удалить все миниатюры картинки, вернёт число удалённых файлов;cleanup_orphans(): удалить сирот, вернёт[ 'checked' => N, 'deleted' => N ];clear_thumb_cache(): удалить весь кэш и очистить очередь;clear_stub_thumbs(): удалить заглушки;disk_stats():[ 'files' => N, 'bytes' => N, 'families' => N ].
Методы объекта ach_thumb_queue():
stats():[ 'pending' => N, 'processing' => N, 'failed' => N, 'total' => N ];failed_jobs( $limit = 100 ): упавшие задачи с текстом ошибки;push( $thumb_path, $format, $quality, $src = '' ): поставить задачу вручную;clear_failed()иclear_all(): очистка.
Обработать очередь из своего кода можно через \Ach_Thumbnail\Cron::process_queue( $max_jobs ). Метод вернёт число готовых задач или -1, если обработчик уже работает в другом процессе.
Плагин ищет миниатюры по адресу исходника, записанному в .meta. Поэтому при программной замене файла вложения чистите кэш до замены, пока адрес ещё старый:
$attachment_id = 1234;
ach_thumb_cache()->clear_img_cache( $attachment_id ); // старый адрес, старые миниатюры
update_attached_file( $attachment_id, $new_path );
Требования
Обязательно
- PHP 8.1 или новее. На более старой версии плагин не запустится и покажет в админке сообщение с текущей версией PHP.
- WordPress 6.0 или новее.
- MySQL или MariaDB. Плагин создаёт свою таблицу очереди и использует
GET_LOCK, чтобы обработчик очереди не запускался дважды. - Расширение Imagick или GD. Через них плагин режет миниатюры. Imagick в приоритете, GD работает как запасной вариант.
- Право записи в
wp-content/cache/. Плагин создаст там папкуach-thumb. - Работающий WP-Cron или системный крон. Без него WebP и AVIF не появятся.
Для WebP и AVIF
Копии в WebP и AVIF кодирует один из двух инструментов. Плагин выбирает сам.
- sharp на Node.js, основной вариант. Даёт лучший AVIF, корректную прозрачность и параллельное кодирование нескольких файлов. Нужно:
- Node.js 18 или новее, доступный пользователю, от которого работает PHP. Плагин ищет его через
command -v node, затем в/usr/local/bin/nodeи/usr/bin/node; - модуль sharp в папке плагина
tools/sharp-cli/node_modules. В установочном архиве он уже лежит, собранный под Linux x64; - разрешённые функции PHP
exec()иproc_open(). Проверьте, что их нет вdisable_functions.
- Node.js 18 или новее, доступный пользователю, от которого работает PHP. Плагин ищет его через
- Imagick, запасной вариант без Node. WebP работает, если ImageMagick собран с libwebp. AVIF плагин включает только на ImageMagick 7 и новее, собранном с поддержкой AVIF (libheif). ImageMagick 6 портит прозрачность в AVIF, поэтому на нём плагин делает только WebP.
GD для WebP и AVIF не используется. Если на сервере нет ни Node, ни Imagick, плагин будет выдавать миниатюры только в исходном формате.
Если Node установлен через nvm в домашнюю папку пользователя, PHP-FPM его обычно не видит. Поставьте системный Node из пакетов или сделайте ссылку:
sudo ln -sf "$(nvm which 20)" /usr/local/bin/node
sudo -u www-data node --version # проверка от имени пользователя PHP
Установка
- Скачайте архив
ach-thumbnail-<версия>.zip. Распаковывать его не нужно. - В админке откройте «Плагины → Добавить новый» и нажмите «Загрузить плагин».
- Выберите архив и нажмите «Установить».
- Нажмите «Активировать плагин».
При активации плагин создаёт таблицу очереди {префикс}ach_thumb_queue и событие WP-Cron, которое раз в минуту обрабатывает очередь. Если вы разворачиваете сайт копированием файлов и базы, где плагин уже числится активным, активация не срабатывает. В этом случае плагин сам создаст таблицу и событие при первом заходе в админку или первом запуске крона.
Можно поставить плагин и вручную: распакуйте архив и загрузите папку ach-thumbnail в wp-content/plugins/, затем активируйте плагин на странице «Плагины».
После установки
1. Зарегистрируйте размеры в теме
Сам по себе плагин ничего на сайте не меняет. Он работает только там, где тема вызывает его функции. Опишите размеры в functions.php темы или в отдельном файле:
// functions.php темы
ach_register_size( 'POST_CARD', [
'w' => 400,
'h' => 260,
'crop' => true,
] );
ach_register_size( 'POST_HERO', [
'w' => 1200,
'h' => 600,
'crop' => true,
'retina' => true,
] );
2. Выведите картинки через функции плагина
// карточка записи
echo ach_picture( 'POST_CARD', get_post_thumbnail_id(), [
'alt' => get_the_title(),
'class' => 'card__img',
] );
// главная картинка записи на первом экране
echo ach_picture( 'POST_HERO', get_post_thumbnail_id(), [
'alt' => get_the_title(),
'loading' => 'eager',
'fetchpriority' => 'high',
] );
Все параметры размеров и функции описаны на вкладке «Использование».
3. Настройте крон
Стандартный WP-Cron запускается только при заходе посетителя. На сайте с небольшим трафиком очередь WebP и AVIF может стоять часами. Добавьте задачу в системный крон сервера и отключите ленивый запуск:
# crontab -e
* * * * * curl -s "https://example.com/wp-cron.php?doing_wp_cron" > /dev/null 2>&1
// wp-config.php
define( 'DISABLE_WP_CRON', true );
4. Включите долгое кэширование файлов в браузере
Имя файла миниатюры меняется вместе с содержимым, поэтому файлы из wp-content/cache/ach-thumb/ можно кэшировать в браузере на год. Готовые настройки для nginx и Apache есть на вкладке «Дашборд» страницы плагина. Там же плагин проверяет, какой заголовок Cache-Control сервер отдаёт сейчас.
5. Проверьте настройки
Откройте «Настройки → ACH Thumbnail → Настройки». Значения по умолчанию подходят большинству сайтов: JPEG 90, WebP 92, AVIF 75, два параллельных процесса кодирования на низком приоритете. На слабом сервере уменьшите число параллельных процессов до 1.
Как проверить, что WebP и AVIF создаются
- Откройте «Настройки → ACH Thumbnail», вкладка «Дашборд». В строке «Sharp (Node CLI)» должно стоять «Sharp активен», в строке «Поддержка форматов» отметки у WebP и AVIF. Если Node не найден, там же перечислено, чего не хватает. Если вы поставили Node только что, нажмите «Сбросить кэш определения Node»: результат поиска хранится час.
- Там же в строке «Cron-расписание» должно быть время следующего запуска. Если вместо него сообщение об ошибке, деактивируйте и снова активируйте плагин.
- Откройте на сайте страницу, где тема выводит картинки через
ach_picture(). Первый показ создаст миниатюры и поставит WebP и AVIF в очередь. - На вкладке «Очередь» появятся задачи в статусе Pending. Через минуту-две они исчезнут. Чтобы не ждать, нажмите «Запустить worker сейчас».
- Обновите страницу сайта и посмотрите код картинки. Внутри
<picture>должны появиться<source type="image/avif">и<source type="image/webp">. Во вкладке «Сеть» инструментов разработчика браузер должен загружать файл.avif. - Если задачи попали в Failed, текст ошибки виден в таблице «Последние ошибки» на вкладке «Очередь». Каждой задаче даётся три попытки.
То же самое из консоли:
wp ach-thumb info # движки, поддержка форматов, пути, очередь
wp ach-thumb queue work # обработать очередь сейчас
wp ach-thumb queue status # статусы и последние ошибки
Если плагин показывает предупреждение «Генерация AVIF отключена», значит ни sharp, ни Imagick на этом сервере не умеют AVIF. Установите Node.js 18 или новее, либо обновите ImageMagick до 7, либо выключите AVIF в настройках. WebP при этом продолжит работать.
Обновления
Новые версии плагина приходят в админку сайта сами, так же как обновления плагинов из каталога WordPress. Когда выходит новая версия, на странице «Плагины» появляется уведомление. Обновление ставится кнопкой «Обновить», настройки, размеры и кэш при этом сохраняются. Если в новой версии меняется структура таблицы очереди, плагин обновит её сам при первом заходе в админку.
-
v1.3.3 последняя
Изменено 1
- Тик воркера очереди не дольше 50 секунд, сколько бы ни разрешал PHP. Если другой плагин ставит set_time_limit(3600) на каждую загрузку WordPress, тик растягивался до 51 минуты: форматы догенерировались часами, а сигналы тика (сброс кэша, массовая нарезка) приходили раз в час.
-
v1.3.2
Изменено 2
- Массовая нарезка: если в очереди форматов больше 200 задач (фильтр
ach_thumb_backlog_threshold), сигналach_thumb_worker_tick_doneотдаёт пустой список картинок и четвёртым параметромtrue, а когда очередь опустеет, один раз срабатываетach_thumb_backlog_drained. Раньше точечные сбросы кэша по тысячам картинок сливались в полный сброс кэша страниц каждую минуту. - Папки и файлы кэша, созданные процессом от root (крон контейнера), отдаются владельцу папки кэша — веб-процесс больше не получает «Permission denied» в папках, созданных кроном.
- Массовая нарезка: если в очереди форматов больше 200 задач (фильтр
-
v1.3.1
Новое 1
- Обновления плагина приходят в админку сайта с alekseychikun.ru: новая версия появляется в списке плагинов и ставится одной кнопкой.
Исправлено 1
- Адреса миниатюр, собранные вне веб-запроса (крон, WP-CLI, прокси без HTTPS=on), получали
http://на https-сайте: схема бралась изis_ssl(). Теперь — из настройки адреса сайта. Касается папки кэша, адреса заглушки и адресов вида//host/path.