Делаем адаптивные изображения для своего сайта WordPress

Сегодня создание адаптивного веб-дизайна является последним писком моды в области веб-разработки. Можно бесконечно смотреть за тем, как веб-сайт плавно меняет свою разметку при изменении размеров браузера – этот процесс гипнотизирует и завораживает.

Однако до сих пор существует один проблемный аспект адаптивного веб-дизайна  – адаптивные изображения. Если вы будете просто использовать атрибут CSS «max-width: 100%;», мобильные сайты все равно будут загружать полные изображения. Именно в этом и заключается главная проблема: если на вашем регулярном сайте есть изображения с шириной 920px, то мобильная версия этого сайта все равно будет загружать эти объемные изображения, что замедлит загрузку страниц.

featured-image

Используем Picturefill

Picturefill – это Javascript-библиотека, которая изначально загружает самое маленькое изображение и затем обновляет его в зависимости от разрешения экрана используемого устройства.

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

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

Синтаксис

К сожалению, синтаксис для этого достаточно многословный:

<div data-picture data-alt="Image alt text">
  <div data-src="mobile.png"></div>
  <div data-src="tablet.jpg"        data-media="(min-width: 768px)"></div>
  <div data-src="desktop.jpg"       data-media="(min-width: 920px)"></div>
  <div data-src="large-desktop.jpg" data-media="(min-width: 1140px)"></div>
 
  <!-- Fallback content for non-JS browsers. -->
  <noscript>
    <img src="mobile.png" alt="Image alt text">
  </noscript>
</div>

Весь этот код предназначен всего для одного изображения! К счастью, мы можем создать шорткод для этого; таким образом, нам придется написать код всего один раз.

Допустим, что мы будем заменять миниатюру каждой записи с помощью адаптивного шорткода. Даже если вы до этого загружали изображения определенной ширины — ничего страшного. Мы можем использовать Regenerate Thumbnails для приведения их к корректному размеру. Я рассмотрю этот аспект чуть позже.

Настройка

Вы можете применить библиотеку к любому существующему сайту. Я сделаю дочернюю тему TwentyTwelve на новой сборке с несколькими изображениями, загруженными в размере 920px в демонстрационных целях. В теории код будет работать с любыми сайтами.

twentytwelve-with-images-700x604

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

image-too-large-700x378

Мы впустую расходуем ресурсы на изображение, видимое лишь на 1/3 от своего реального размера.

Решить проблему можно с помощью Picturefill. Однако мы хотим создать что-то такое, где человеку не понадобится всякий раз вводить размер изображения, чтобы сделать его адаптивным.

Таким образом, мы будем использовать шорткоды. В идеале структура шорткода будет следующей:

 [rimg src="http://link-to-the-image.png" caption="This is the caption"] 

Ничего сложного. Единственный недостаток такого подхода – возможность «Insert into post» (Вставить в запись) будет практически бесполезной. Решить проблему можно с помощью хаков, однако я не буду их сейчас рассматривать.

Размеры наших изображений и контрольные точки

Для своего сайта TwentyTwelve я буду использовать три размера изображений:

  • 740px – вариант изображения для настольных компьютеров
  • 540px – вариант изображения для планшетов
  • 340px – вариант изображения для мобильных устройств

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

Откроем файл functions.php своей темы (или создадим его в новой теме) и добавим к нему следующие строки:

<?php
 
/*
 *  Custom image sizes for responsivity.
 */
 
add_image_size('resp-large', 720, 9999);
add_image_size('resp-medium', 520, 9999);
add_image_size('resp-small', 320, 9999);

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

Что делать со старыми изображениями?

Regenerate Thumbnails находится в меню Tools
Regenerate Thumbnails находится в меню Tools
Никаких проблем. Воспользуемся плагином Regenerate Thumbnails. Этот удобный плагин берет каждое изображение, которое было загружено вами, и создает миниатюры на основе размеров изображений, установленных для вашего сайта в настоящий момент.

Перейдите к странице плагина и щелкните по кнопке «Regenerate All Thumbnails». Вы увидите индикатор выполнения, который будет отражать процесс создания миниатюр в новых форматах. Если изображений много, процесс может быть длительным.

Плагин обладает довольно неплохим интерфейсом!
Плагин обладает довольно неплохим интерфейсом!

Теперь у нас есть изображения с корректными размерами. Самое время их использовать!

Установка Picturefill

Как и в случае с любой другой Javascript-библиотекой, устанавливаемой в теме, мы должны добавить скрипт Picturefill к хуку wp_enqueue_scripts(). Загружаем Picturefill и помещаем ее в папку с темой.

Вставляем код, представленный ниже, в файл functions.php сразу под функцией add_image_size():

/*
 *  Enqueue Picturefill to the front-end
 */
 
function add_picturefill(){
  wp_enqueue_script(
    'picturefill',
    get_bloginfo('stylesheet_directory').'/picturefill.js' );
}
 
add_action('wp_enqueue_scripts', 'add_picturefill');

Наша функция add_picturefill() подключает скрипт. Чтобы использовать его, нужно сцепиться с wp_enqueue_scripts через add_action().

Если вы сохраните файл и обновите страницу, то в ее исходнике в разделе head увидите подключение скрипта picturefill.

picturefill-embedded-700x428

Теперь самое время создать что-то, что поможет нам автоматически генерировать адаптивные изображения без необходимости постоянного написания слишком длинного кода.

Шорткод для адаптивных изображений

Шорткоды приходят на помощь! Наш шорткод будет иметь следующий вид:

 [ rimg src="http://link-to-full.size/image.png caption="This will be the alt and caption" ] 

Довольно просто, верно? Функция для нашего шорткода будет выполнять следующие действия:

  1. Проверить, есть ли адрес исходного изображения.
  2. Получить ID изображения из адреса.
  3. Получить ссылки на различные размеры изображения из ID.
  4. Возвратить корректную HTML-структуру для Picturefill с адресом изображения
  5. Проверить, есть ли заголовок (caption), и если есть, то выдать его.

Код

Теперь осталось решить одну большую проблему – как мы получим все различные размеры изображения из URL-адреса? В идеале можно использовать ID, однако имеет больше смысла ввести URL, верно?

Хорошо. Я написал небольшую функцию, которая вернет ID изображения при вводе URL оригинального изображения. Если вы попытаетесь передать миниатюру, функция не будет работать. Ниже приведен фрагмент кода, который вы должны разместить в файле functions.php:

/*
 *  Get image ID from URL
 */
 
function get_attachment_id_from_src($url) {
  global $wpdb;
  $prefix = $wpdb->prefix;
  $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM " . $prefix . "posts" . " WHERE guid='%s';", $url ));
    return $attachment[0];
}

Жаль, что в WP нет встроенной функции для данного действия. Этот код выглядит ужасно — по существу он представляет собой запрос к базе данных, который «заглядывает» в таблицу записей (где хранятся прикрепленные изображения) для получения ID, и возвращает первый результат.

Вернемся к шорткодам. Чтобы убедиться в том, что наша функция работает, мы запустим наш шорткод и затем поместим его в запись. Разместите следующий код в файле functions.php после функции get_attachment_id_from_src():

/*
 *  Responsive shortcode
 */
 
function responsive_image($atts){
  extract( shortcode_atts( array(
    'src' => '',
    'caption' => '',
  ), $atts ) );
 
  return get_attachment_id_from_src($src);
}
 
add_shortcode('rimg', 'responsive_image');

Данный код необходим для того, чтобы создать отдельный шорткод. Функция add_shortcode() во многом подобна функции add_hook(), что облегчает ее понимание.

Функция extract() использует наши значения по умолчанию, если ничего не задано. Вообще, мы надеемся, что вы будете задавать собственные значения. Использовать пустую строку можно для тестирования, чтобы проверить, будет ли выведен код изображения.

Наконец, в строке с return используется наша функция для вывода ID по URL-адресу изображения.

На практике

Я буду использовать шорткод, который мы только что создали.

shortcode-in-there-700x604

Теперь, если мы посмотрим на фронтэнд данной записи, то вместо шорткода мы увидим ID! Прекрасно!

shortcode-to-id-700x604

Получаем URL-адреса для различных размеров

Теперь, когда у нас есть функция, которая возвращает ID изображения из URL, мы можем строить на ее основе необходимый Picturefill HTML-код.

Перепишем функцию responsive_image():

function responsive_image($atts){
  extract( shortcode_atts( array(
    'src' => '',
    'caption' => '',
  ), $atts ) );
  if($src != '')
  {
    $img_ID = get_attachment_id_from_src($src);
    $large = wp_get_attachment_image_src( $img_ID, 'resp-large' );
    $medium = wp_get_attachment_image_src( $img_ID, 'resp-medium' );
    $small = wp_get_attachment_image_src( $img_ID, 'resp-small' );
 
    $output = $src;
  }
 
  return $output;
 
}

Здесь мы получаем URL-адреса для различных размеров изображения. У нас есть следующие переменные:

  • $image_ID
  • $caption
  • $src
  • $large
  • $medium
  • $small

Теперь шорткод выведет URL, которые мы определили при его написании.

Код Picturefill

Наконец, мы готовы вывести некоторый HTML-код, который завершит создание адаптивного изображения. Поскольку мы будем использовать шорткод, нам понадобится что-то возвратить, т.е. применить return вместо echo.

Совет: для ввода длинных переменных можно использовать следующую конструкцию:

$output = "Hello ";
$output.= "World!";
 
echo $output;
 
//echos "Hello World!"

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

function responsive_image($atts){
  extract( shortcode_atts( array(
    'src' => '',
    'caption' => '',
  ), $atts ) );
  if($src != '')
  {
    $img_ID = get_attachment_id_from_src($src);
    $large = wp_get_attachment_image_src( $img_ID, 'resp-large' );
    $medium = wp_get_attachment_image_src( $img_ID, 'resp-medium' );
    $small = wp_get_attachment_image_src( $img_ID, 'resp-small' );
 
    $output = '<div class="responsive-image">';
    $output = '  <div data-picture data-alt="' . $caption . '">';
    $output.= '    <div data-src="' . $small[0] . '"></div>';
    $output.= '    <div data-src="' . $medium[0] . '" data-media="(min-width: 786px)"></div>';
    $output.= '    <div data-src="' . $large[0] . '" data-media="(min-width: 920px)"></div>';
    $output.= '    <div data-src="' . $src . '" data-media="(min-width: 1140px)"></div>';
    $output.= '    <noscript>';
    $output.= '      <img src="' . $small[0] . '" alt="' . $caption . '">';
    $output.= '    </noscript>';
    $output.= '  </div>';
    if($caption != '') $output.= '  <p class="caption">' . $caption . '</p>';
    $output.= '</div>';
  }
 
  return $output;
 
}

Довольно много кода. Правда, все, что мы сделали – это сформировали переменную $output.

Если вы вернетесь в самый верх этой записи, то заметите, что данный код напоминает синтаксис Picturefill. Единственная разница – мы заменяем URL-адреса изображения динамически созданными миниатюрами. В самом конце стоит условный оператор, который выводит заголовок в случае необходимости.

На данный момент мы имеем рабочий шорткод, который можем использовать!

Изображение размером 320px
Изображение размером 320px

Если вы будете расширять окно браузера, изучая элемент img, то увидите, что атрибут src меняется при достижении контрольных точек.

Следующий размер
Следующий размер

720px-700x454

Великолепно! Мы получили адаптивные изображения, которые  действительно помогут сохранить пропускную способность сервера.

Что про миниатюры?

Не переживайте. Вам нужно всего лишь порыться в файлах темы и найти the_post_thumbnail() или что-то похожее, что отвечает за вывод миниатюр. В случае с TwentyTwelve рыться нужно в файле content.php (который я переопределил своей дочерней темой).

Заменим

<?php the_post_thumbnail(); ?>

на

<?php
  $thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'original' );
  $url = $thumb['0'];
  echo do_shortcode( '[rimg src="' . $url . '"]' );
?>

Адаптивные миниатюры готовы.

Если код не сработает, обязательно используйте Regenerate Thumbnails для приведения изображений к верным размерам.

На этом все. Если вы хотите скачать исходники, я заархивировал дочернюю тему TwentyTwelve, с которой я работал в данном руководстве.

Адаптивные изображения – прекрасный способ сохранить пропускную способность сервера и порадовать своих посетителей быстрой загрузкой сайта. Надеюсь, что элемент picture будет наконец-то внесен в спецификацию, и тогда нам понадобится сделать небольшие изменения, чтобы оставаться в рамках стандартов.

Источник: wpmu.org

Блог про WordPress
Комментарии: 4
  1. Сергей

    Подскажите, а как быть с галереями, а не единичными картинками?

    1. Дмитрий (автор)

      Галереи — набор изображений, должно затрагивать их тоже.

  2. roose

    «Этот код выглядит ужасно», ну можно сделать так:

    $args = array( 'post_type' => 'attachment', ... 'post_parent' => $post->ID);
    $attachments = get_posts($args);

    и потом foreach, вытаскивать айди картинки.

  3. Саша

    Доброго времени суток!
    Не могли бы Вы подсказать как сделать изображение заголовка темы адаптивным? А то на мобильных гаджетах картинка обрезается по бокам:(
    Спасибо.

Добавить комментарий

Получать новые комментарии по электронной почте.