Jetpack Related Posts: настраиваем отображение связанных записей под себя

Не секрет, что мой блог крутится на платформе WordPress. Платформа WordPress штука очень мощная и на текущий момент, по праву, является номером первым среди всего многообразия выбора средств для ведения блогов. Популярность WordPress кроется, во-первых, в его бесплатности, а во-вторых, в 100% кастомизации. Например, для блога я использую сильно модифицированную типовую тему. В ней поменяно так много всего, чтобы результат выглядел и работал именно так как мне нужно, что ее впору рассматривать как самостоятельный продукт для платформы WordPress. Но помимо ковыряния в исходных кодах, расширять и настраивать функции, а заодно и внешний вид блога в WordPress можно посредством дополнительно устанавливаемых плагинов, благо на платформе работает неплохой маркетплейс, где можно выбрать наиболее подходящий вариант плагина для выполнения именно той функции, которая вам нужна. Именно так и поступает большинство пользователей платформы. Ведь для установки плагина не требуется иметь знания о языках программирования, а настройка обычно происходит через понятные и доступные меню.

wordpress query monitor

QueryMonitor здорового человека. 128 запросов к базе данных за 0.05 секунды и выдача всего материала за 1/3 секунды

Но недавно, проводя регулярную инспекцию, я внезапно обнаружил, что QueryMonitor (очень полезный плагин, позволяющий оптимизировать работу платформы) выдает мне желтенький сигнал, означающий, что с моим блогом есть какая-то, не серьезная, но требующая внимания проблема. Источником проблемы оказался SQL-запрос плагина Zemanta Related Posts. Запрос от плагина длился 0.08 секунды и существенно замедлял работу всей платформы. Замедление началось, как только ядро WordPress обновилось до очередной версии. Казалось бы, запрос занял всего 8 сотых секунды, разве это можно заметить? Но платформа WordPress очень активно работает с базой данных (мне пришлось потратить немало времени на ее оптимизацию), так для отображения этой статьи к базе данных осуществляется более 120 запросов. Длительный запрос к базе данных не только загружает сервер, но и замедляет все остальное. Пока запрос не будет отработан, страничка до конца не прогрузится. Я начал разбираться, почему плагин работает так не оптимально и оказалось, что сам плагин удален с маркетплейса WordPress, так как авторы перестали его поддерживать.

Наличие уже неподдерживаемого и устаревшего плагина — явная угроза безопасности. Вообще любой плагин, особенно который не поддерживается открытым сообществом, по своей сути может нести потенциальную угрозу безопасности для блога. А устаревший и неподдерживаемый плагин удваивает вероятность либо взлома, либо порчи данных. Поэтому неподдерживаемый плагин был удален и после непродолжительного выбора был выбран плагин-заменитель, выполняющий ту же функцию. Им стал плагин Jetpack от разработчиков самого WordPress. Jetpack уже используется в моей системе, поэтому для нормальной работы мне осталось только включить функцию отображения связанных записей.

jetpack related posts включен.

Jetpack Related Posts на максималках

Функция Jetpack Related Posts практически не грузит сервер, на котором установлен WordPress, так как вся обработка осуществляется на серверах Jetpack. С одной стороны это плюс, с другой появляется некоторая зависимость от разработчиков. И вдруг если что, придется искать замену многим функциям. При использовании плагина от Zemanta у меня в ряд помещалось 5 плашечек с картинками и подписями. Но Jetpack предлагает всего три плашки, причем растягивает их по всей ширине экрана с текстом. Что совсем не то, что мне нужно. Более того, некоторые ссылки отображались текстом из тега Alt. Это происходило по причине невозможности нахождения в соответствующем посте картинки адекватного размера для плашки. И вот с этими проблемами мне необходимо разобраться.

Хочу 5 плашек, а не 3

В ядре WordPress реализован очень интересный механизм фильтров, который позволяет модифицировать поведение некоторых компонентов, в первую очередь плагинов, посредством изменения соответствующих функций. Да, для изменения количества плашек необходимо лезть в код используемой темы и вставлять туда немножечко исходного кода. Изменять исходный код самого плагина Jetpack — идея не самая лучшая, так как при следующем обновлении плагина из маркетплейса все внесенные изменения будут затерты обновленной версией. У меня используемая тема не будет ни откуда обновляться, если требуются изменения, то я вношу их руками, поэтому вполне благоразумно могу внести код для фильтра прямо в файл functions.php расположенный в каталоге моей темы.

function jetpackme_more_related_posts( $options ) {
     $options['size']=5;
     return $options;
}

add_filter( 'jetpack_relatedposts_filter_options', 'jetpackme_more_related_posts' );

Здесь цифра 5 задает количество плашек, которые генерирует плагин. Казалось бы, все хорошо и просто, но радоваться мало. Эти 5 плашек начинают вести себя на экране не совсем так как задумано. Если для них нет места, то плашки начинают переноситься на новую строку, при этом не заполняя пространство слева направо, а образуя разнообразные композиции. Такое действие вызывают примененные к плашкам CSS-стили оформления, которые поставляются вместе с плагином. Исправить их можно изменив CSS.

.jp-relatedposts-items .jp-relatedposts-post {
     width: unset !important;
}

#jp-relatedposts .jp-relatedposts-items .jp-relatedposts-post:nth-child(5n+6), #jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post:nth-child(5n+6) {
     clear: both !important;
}

#jp-relatedposts .jp-relatedposts-items .jp-relatedposts-post:nth-child(3n+4), #jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post:nth-child(3n+4) {
     clear: none !important;
}

Данным набором стилей мы переопределяем поведение плашек в случаях, когда их количество доходит до определенного количества. Такое поведение определяется псевдоклассом nth-child. В приведенном примере параметр 5n+6 означает, что 6-я плашка должна получить свойство отключения обтекания плашки с двух сторон (слева и справа). Справедливости ради тут можно использовать clear: left, а не both, да и параметр указать как просто 6, а не мудрить с 5n+6. Другими словами, 6-я плашка перенесется на новую строку. Следующий стиль, где применяется 3n+4 отключает функцию переноса в поставляемом стиле Jetpack. Данные изменения вносятся не в стиль Jetpack, а в стиль темы style.css. Тема у меня своя, поэтому нет опасения, что они затрутся.

.jp-relatedposts-post-title {
     width: 340px !important;
}

.jp-relatedposts-post-img {
     border-radius: 5px !important;
}

#jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post {
     opacity: 1 !important;
}

.jp-relatedposts-post-title {
     margin-top: 5px !important;
     margin-left: 1px !important;
}

Следующие изменения приводят внешний вид плашек тому, что я привык видеть в своем блоге. А именно: ограничивается 340 пикселями длинна заголовка (с учетом того, что картинки для плашек используют размерность 350х200 пикселей), отключается бледный вид картинок, добавляются закругления углов и делаются необходимые отступы от краев для элементов. Особое внимание следует уделить модификатору !important, благодаря ему я могу в другом, подконтрольном мне, CSS-файле переопределить уже заданные кем-то и где-то CSS-стили.

Не хочу слишком длинный текст, если Jetpack не нашел картинку

В случае, если Jetpack не обнаружил в оригинальной записи, на которую он создает плашку, картинки из которой можно сделать изображение 350х200, то он поступает следующим образом. Формирует HTML-код для вывода картинки, прописывает в нем тег Alt и добавляет туда некий текст, который был экстрагирован из записи. Таким образом получается, что браузер, не найдя картинки, а она ему и не предлагалась, просто выводит текст из тега Alt. Текст длинный и обычно портит весь вид и форматирование.

#jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post-nothumbs {
     max-width: 370px !important;
}

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

Хочу заменить отсутствующие картинки на заглушки

Но, а что если заставить Jetpack подставлять картинку-заглушку, если он не может получить нормальную картинку? Данный вопрос решается при помощи фильтра. Некий Jeremy Herve предложил аж два варианта фильтров. В одном варианте вместо отсутствующей картинки подставляется картинка-заглушка, во втором все сложнее. В рекомендации просто не попадают статьи, где нет нормальных картинок. Разумеется, такой вариант неприемлем, и я пошел по первому пути, но слегка его модифицировал.

function jeherve_custom_image( $media, $post_id, $args ) {
     if ( $media ) {
          return $media;
     } else {
          $permalink = get_permalink( $post_id );
          $pic_url = '/wp-content/uploads/2022/05/350x200-'.rand(0,19).'.jpg';
          $url = apply_filters( 'jetpack_photon_url', $pic_url );
     return array( array(
          'type' => 'image',
          'from' => 'custom_fallback',
          'src' => esc_url( $url ),
          'href' => $permalink,
     ) );
   }
}

add_filter( 'jetpack_images_get_images', 'jeherve_custom_image', 10, 3 );

Следующий код добавляем в functions.php и он подставляет одну из 20 картинок-заглушек, что я загрузил традиционным путем на мой сервер WordPress. Картинки называются 350x200-x.jpg и располагаются в каталоге загрузки по относительному пути /wp-content/uploads/2022/05/, где вместо x у меня используются цифры от 0 и до 19. Таким образом появляется возможность немного разнообразить картинки-заглушки, так как оказалось, что у меня довольно много записей, сделанных по книгам с куцыми картинками. Разумеется, можно было навернуть фильтр куда сильнее, например, добавить автоматический поиск всех картинок-заглушек, когда-либо загруженных в медиа-библиотеку блога, а потом уже выбирать из них, но подобные навороты будут кушать дополнительные ресурсы на сервере, хоть и небольшие, а заодно потребуют куда большего времени на доработку. А добавленная одна строка и измененная вторая обошлись примерно в 5 минут времени, включая поиск в документации по PHP как там производится конкатенация строк и каким образом можно получить случайное число.

Надо поправить размеры плашек на мелких экранах

Если просматривать блог на экранах не совсем больших мониторов, либо использовать окно браузера не на полный экран, то возникает новая проблема с плашками. Они перестают влезать на экран по ширине. Исправить вопрос можно изменяя максимальный размер плашек опираясь на разрешение экрана.

@media screen and (max-width: 3000px) {
     .jp-relatedposts-post-title {
          width: 230px !important;
     }

     #jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post-nothumbs {
          max-width: 250px !important;
     }

     #jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post {
          max-width: 240px !important;
     }
}

@media screen and (max-width: 1900px) {
     .jp-relatedposts-post-title {
          width: 140px !important;
     }

     #jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post-nothumbs {
          max-width: 155px !important;
     }

     #jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post {
          max-width: 150px !important;
     }
}

В данном примере используется две группы стилей, рассчитанные на размеры до 3000 пикселей и на размеры до 1900 пикселей. Соответственно, если размер экрана в браузере меньше указанного размера по ширине, то размер плашек и наиболее чувствительных элементов соответственно уменьшается.

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

В результате

По результатам корректировки стилей и добавления фильтров плагин заработал именно так, как мне того хотелось. Да, пришлось потратить немного времени, но результат того стоил.

jetpack related posts tuning

Результат после всех модификаций. Красочные пейзажи и есть те самые заглушки.

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

.jp-relatedposts-items .jp-relatedposts-post {
     width: unset !important;
}

.jp-relatedposts-post-title {
     width: 340px !important;
}

#jp-relatedposts .jp-relatedposts-items .jp-relatedposts-post:nth-child(6), #jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post:nth-child(6) {
     clear: both !important;
}

#jp-relatedposts .jp-relatedposts-items .jp-relatedposts-post:nth-child(3n+4), #jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post:nth-child(3n+4) {
     clear: none !important;
}

.jp-relatedposts-post-img {
     border-radius: 5px !important;
}

#jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post {
     opacity: 1 !important;
     max-width: 20% !important;
}

.jp-relatedposts-post-title {
     margin-top: 5px !important;
     margin-left: 1px !important;
}

#jp-relatedposts .jp-relatedposts-items-visual .jp-relatedposts-post-nothumbs {
     max-width: 370px !important;
}

@media screen and (max-width: 1100px) {
     #jp-relatedposts {
          display: none !important;
     }
}

И в качестве рекомендации по ускорению работы всего WordPress. Чем меньше отдельных файлов, в том числе и стилей, будет подгружаться, тем быстрее будет отклик от сервера, так как каждый файл браузером скачивается в виде отдельной сессии. Поэтому лучше не плодить отдельных файлов там, где можно обойтись их меньшим количеством. Именно по этой причине я добавляю изменения в CSS в основной CSS-файл моей темы, а не подключаю еще один CSS-файл. Ситуация со скоростью обработки отдельных файлов изменилась в HTTP/2, но далеко не все серверы настроены на использование данного протокола, да и не все клиенты умеют с ним работать.

PS. Изменения и улучшения Jetpack Related Posts я проводил на версии WordPress 5.9.3 и Jetpack 10.9.



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