Как изменить/модифицировать HTML-вывод функции the_post_thumbnail()?
Я работаю над созданием пользовательской темы и уже некоторое время борюсь с этой проблемой. Я пытаюсь модифицировать HTML-вывод функции the_post_thumbnail();
. Мне это нужно, потому что я пытаюсь добавить поддержку retina-изображений на свой сайт и предпочитаю встроить эту функциональность в тему, а не загружать плагин.
По умолчанию the_post_thumbnail();
просто вызывает get_the_post_thumbnail();
, что я нашел здесь. Моей первой мыслью было использовать фильтр 'post_thumbnail_html', но я не могу заставить его работать. Итак...
Вот как я вызываю миниатюры записей в цикле:
<?php the_post_thumbnail('custom-thumbnail-size', array('class' => 'unique-class-here', 'title' => 'unique-title-here')); ?>
Вот код, который должен выводиться при вызове the_post_thumbnail();
...
<img src="" alt="" data-src="image.png" data-alt="Alt text" class="retina unique-class-here" />
А ниже код, который у меня сейчас находится в файле functions.php:
<?php
// Модифицируем HTML вывод миниатюры
function modify_post_thumbnail_html($html, $post_id, $post_thumbnail_id, $size, $attr) {
$src = wp_get_attachment_image_src(get_post_thumbnail_id(), $size);
$html = '<img src="" alt="" data-src="' . $src['0'] . '" data-alt="" class="retina" />';
return $html;
}
add_filter('post_thumbnail_html', 'modify_post_thumbnail_html', 99, 5);
?>
Несколько моментов, которые стоит отметить. Я не уверен, как передать соответствующий текст метаданных в атрибут 'data-alt'. Также мне нужно иметь возможность передавать конкретный размер миниатюры, так как я использую пользовательские размеры миниатюр по всей теме. Наконец, как видите, массив атрибутов должен передавать классы в дополнение к классу по умолчанию 'retina', а также любые другие атрибуты в этом массиве.
Заранее спасибо за любую помощь. В интернете действительно не так много информации на эту тему, и я решил, что мой вопрос достаточно отличается, чтобы создать дополнительный пост в этом сообществе. Пожалуйста, дайте знать, если у вас есть какие-либо мысли, решения и/или нужны какие-либо уточнения.

Хорошо, кажется, я нашел решение. Оно не выглядит таким простым и элегантным, как хотелось бы, но серьезные изменения стандартной функциональности WordPress иногда требуют радикальных мер. :)
Вот мое рабочее решение для перезаписи HTML-вывода миниатюр записей на сайте, чтобы они работали с плагином Retinise.js. Конечно, этот код можно адаптировать и для других манипуляций с HTML миниатюр.
В файле functions.php я создал эту функцию:
<?php
function modify_post_thumbnail_html($html, $post_id, $post_thumbnail_id, $size, $attr) {
$id = get_post_thumbnail_id(); // получаем ID текущей миниатюры записи (в цикле)
$src = wp_get_attachment_image_src($id, $size); // получаем URL изображения для указанного размера (например, кастомного размера)
$alt = get_the_title($id); // получаем заголовок миниатюры записи
$class = $attr['class']; // получаем классы, переданные в миниатюру записи, определено здесь для удобства доступа в функции
// Проверяем наличие класса 'retina' в массиве при вызове "the_post_thumbnail()", если есть - выводим другой HTML для <img/>
if (strpos($class, 'retina') !== false) {
$html = '<img src="" alt="" data-src="' . $src[0] . '" data-alt="' . $alt . '" class="' . $class . '" />';
} else {
$html = '<img src="' . $src[0] . '" alt="' . $alt . '" class="' . $class . '" />';
}
return $html;
}
add_filter('post_thumbnail_html', 'modify_post_thumbnail_html', 99, 5);
?>
Затем, когда я вызываю the_post_thumbnail();
в цикле WordPress, я использую этот код:
<?php the_post_thumbnail('custom-thumbnail-size', array('class' => 'retina additional-class')); ?>
Этот код должен работать (с небольшими изменениями, конечно), даже если вы работаете вне цикла WordPress. Надеюсь, это сэкономит кому-то время и избавит от разочарования! Возможно, когда у меня будет время, я напишу полное руководство от начала до конца о том, как я добавил поддержку retina в свою тему. Без использования плагинов!
Вот несколько ссылок, которые помогут вам разобраться в теме, если вам это интересно!

Хакерское решение:
Поскольку WordPress по умолчанию добавляет множество классов к тегу <img>
, если вы не измените это поведение принудительно, вы всегда можете "вставить" что-то через str_replace перед строкой class=
. В коде:
$image = get_the_post_thumbnail( $post->ID, 'medium', array( 'class' => 'myclass' ) );
$moreattrs = 'data-fullimg= "full.jpg"';
$image = str_replace('class=', $moreattrs.' class=', $image );
Довольно безопасно предположить, что если что-то начинается с "class=", это именно то, что вам нужно. Конечно, это может быть нарушено странными именами файлов, содержащими class=
, но особенно в WordPress это маловероятно.
Вы также можете искать <img
и заменять это; если подумать, я полагаю, это должно быть немного безопаснее.

Возможно, вы можете использовать хук wp_get_attachment_image_attributes
:
function my_custom_image_attributes( $attr, $attachment ) {
// Удаляем фильтр, чтобы избежать рекурсии
remove_filter('wp_get_attachment_image_attributes','my_custom_image_attributes');
// Получаем URL изображения в полном размере
$image = wp_get_attachment_image_src( $attachment->ID, 'full' );
// Добавляем data-атрибуты
$attr['data-src'] = $image[0];
$attr['data-alt'] = $attachment->post_title;
// Добавляем класс retina
$attr['class'] .= ' retina';
return $attr;
}
// Добавляем фильтр для изменения атрибутов изображения
add_filter('wp_get_attachment_image_attributes','my_custom_image_attributes');
Этот код нужно протестировать и, возможно, доработать. Идея была найдена здесь: Добавление имени класса к миниатюре записи (проверьте исходный код vwp_get_attachment_image
в конце статьи).
Вам нужно добавить хук непосредственно перед вызовом the_post_thumbnail()
в вашей теме.
Также я не знаю, что именно вам нужно использовать в качестве data-alt
. На мой взгляд, вы можете использовать любое поле из объекта attachment
, который передается в фильтре (это может быть и произвольное поле).

Привет, @Simon. Спасибо за ответ!! К сожалению, у меня не получается заставить это работать. Быстрый поиск в Google показывает, что почти у всех возникают проблемы с хуком 'wp_get_attachment_image_attributes'. Может быть, есть другой хук, который сработает? Поэтому я пошел по пути 'post_thumbnail_html', но не могу понять, как правильно передать атрибуты из моего вызова the_post_thumbnail('custom-thumbnail-size', array('class' => 'unique-class'));
. Есть еще идеи?

Не сразу. Мне нужно сначала провести тесты, но думаю, это выполнимо. На первый взгляд, тебе нужно использовать $attr['class']
