Как изменить/модифицировать HTML-вывод функции the_post_thumbnail()?

9 февр. 2014 г., 22:45:07
Просмотры: 32.1K
Голосов: 11

Я работаю над созданием пользовательской темы и уже некоторое время борюсь с этой проблемой. Я пытаюсь модифицировать 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', а также любые другие атрибуты в этом массиве.

Заранее спасибо за любую помощь. В интернете действительно не так много информации на эту тему, и я решил, что мой вопрос достаточно отличается, чтобы создать дополнительный пост в этом сообществе. Пожалуйста, дайте знать, если у вас есть какие-либо мысли, решения и/или нужны какие-либо уточнения.

0
Все ответы на вопрос 3
0
11

Хорошо, кажется, я нашел решение. Оно не выглядит таким простым и элегантным, как хотелось бы, но серьезные изменения стандартной функциональности 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 в свою тему. Без использования плагинов!

Вот несколько ссылок, которые помогут вам разобраться в теме, если вам это интересно!

10 февр. 2014 г. 01:52:21
1

Хакерское решение:

Поскольку 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 и заменять это; если подумать, я полагаю, это должно быть немного безопаснее.

2 апр. 2015 г. 18:16:44
Комментарии

Есть ли способ сделать это для всех изображений автоматически? Какой-нибудь хук, который может срабатывать прямо перед рендерингом HTML страницы?

vsync vsync
11 апр. 2018 г. 22:35:35
3

Возможно, вы можете использовать хук 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, который передается в фильтре (это может быть и произвольное поле).

10 февр. 2014 г. 00:09:12
Комментарии

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

kaffolder kaffolder
10 февр. 2014 г. 00:39:27

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

Simon Simon
10 февр. 2014 г. 01:05:21

Я опубликовал рабочее решение выше. Не уверен, соответствует ли оно лучшим практикам. Дай знать, если найдешь лучшее/альтернативное решение. Спасибо!

kaffolder kaffolder
10 февр. 2014 г. 01:53:14