WordPress. Галерея изображений

14.06.2019

Теги: CMSWeb-разработкаWordPressГалереяИзображениеПлагин

Шорткод [gallery] добавляет в запись блога или на постоянную страницу галерею изображений. При добавлении галереи из встроенного редактора, будет вставлен шорткод [gallery ids="…"] с указанием списка идентификаторов изображений. Если параметр ids не указан, будут показаны изображения, прикрепленные к данной записи или странице.

Если заглянуть в исходный код файла wp-includes/media.php, то можно увидеть, что WordPress обрабатывает шорткод галереи по-умолчанию, наше участие не требуется:

add_shortcode('gallery', 'gallery_shortcode');

Функия для обработки шорткода

Функция gallery_shortcode() заменяет шорткод [gallery] в тексте записи или статьи. Используя хуки из этой функции, можно частично или полностью изменить вывод галереи. Вот так можно отключить дефолтные css-стили у галереи:

add_filter('use_default_gallery_style', '__return_false');

А вот так — заменить дефолтные стили на свои:

add_filter(
    'gallery_style',
    function ($style) {
        $style =
<<<STYLE
<style type="text/css">
    .gallery-images {
        display: flex;
        flex-wrap: wrap;
        margin-top: 20px;
    }
        .gallery-images > a {
            box-sizing: border-box;
            overflow: hidden;
            width: 23%;
            margin-right: 2.66666%;
            border: 1px solid #cfcfcf;
            background-color: #f5f5f5;
            padding: 10px;
            margin-bottom: 2.66666%;
            /* для центрирования картинок */
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .gallery-images > a:nth-child(4n) {
            margin-right: 0;
        }
            .gallery-images > a > img {
                max-width: 100%;
            }
</style>
STYLE;
        return $style;
    }
);

Сами дефолтные стили галереи выглядят так:

<style type="text/css">
    /*
    посмотреть исходный код функции gallery_shortcode(), которая
    формирует эти стили, можно в файле wp-includes/media.php
    */
    #gallery-1 {
        margin: auto;
    }
    #gallery-1 .gallery-item {
        float: left;
        margin-top: 10px;
        text-align: center;
        width: 33%;
    }
    #gallery-1 img {
        border: 2px solid #cfcfcf;
    }
    #gallery-1 .gallery-caption {
        margin-left: 0;
    }
</style>

Изменяем работу галереи

Давайте создадим плагин, который изменит работу галереи WordPress. И используем для этого хук post_gallery, который позволяет либо подправить результат работы функции gallery_shortcode(), либо полностью его заменить:

<?php
/*
Plugin Name: Галерея изображений
Plugin URI: https://tokmakov.msk.ru
Description: Изменяет работу стандартной галереи WordPress
Version: 1.0
Author: Евгений Токмаков
Author URI: https://tokmakov.msk.ru
*/

add_filter(
    'post_gallery',
    function($output, $attr) {
        // $output содержит результат работы функции gallery_shortcode()
        if (!empty($attr['ids'])) {
            // были заданы идентификаторы изображений, которые надо показать
            $pictures = get_posts([
                'posts_per_page' => -1,
                'include' => $attr['ids'],
                'post_type' => 'attachment',
                'post_mime_type' => 'image',
                'orderby' => 'post__in',
            ]);
        } elseif (!empty($attr['id'])) {
            // задан идентификатор записи, показываем привязанные изображения
            $id = intval($attr['id']);
            $pictures = get_children([
                'post_parent'    => $id,
                'post_type'      => 'attachment',
                'post_mime_type' => 'image',
            ]);
        } else {
            // показываем изображения, привязанные к текущей записи или странице
            $post = get_post();
            $id = $post->ID;
            $pictures = get_children([
                'post_parent'    => $id,
                'post_type'      => 'attachment',
                'post_mime_type' => 'image',
            ]);
        }

        if (empty($pictures)) {
            return '';
        }

        // на странице может быть несколько галерей, поэтому будем их
        // подсчитывать и каждой присваивать уникальный идентификатор
        static $instance = 0;
        $instance++;
        $selector = 'gallery-images-' . $instance;

        $style =
<<<STYLE
<style type="text/css">
    #$selector {
        display: flex;
        flex-wrap: wrap;
        margin-top: 20px;
    }
        #$selector > a {
            box-sizing: border-box;
            overflow: hidden;
            width: 23%;
            margin-right: 2.66666%;
            border: 1px solid #cfcfcf;
            background-color: #f5f5f5;
            padding: 10px;
            margin-bottom: 2.66666%;
            /* для центрирования картинок */
            display: flex;
            align-items: center;
            justify-content: center;
        }
        #$selector > a:nth-child(4n) {
            margin-right: 0;
        }
            #$selector > a > img {
                max-width: 100%;
            }
</style>
STYLE;

        // выводим каждую картинку из галереи
        foreach($pictures as $picture) {
            $href = esc_url($picture->guid);
            $tmp = wp_get_attachment_image_src($picture->ID, 'thumbnail');
            $src = $tmp[0];
            $alt = esc_attr($picture->post_title);
            $items[] =
<<<ITEM
<a href="$href" target="_blank"><img src="$src" alt="$alt" /></a>
ITEM;
        }

        $items = PHP_EOL . implode(PHP_EOL, $items) . PHP_EOL;
        $html = '<div id="' . $selector . '">' . $items . '</div>';

        return PHP_EOL . $style . PHP_EOL . $html . PHP_EOL;
    },
    10,
    2
);
<div id="gallery-images-1">
    <a href="http://www.server.com/wp-content/uploads/2019/04/123.jpg">
        <img src="http://www.server.com/wp-content/uploads/2019/04/123-200x200.jpg" alt="Восход солнца" />
    </a>
    <a href="http://www.server.com/wp-content/uploads/2019/04/456.jpg">
        <img src="http://www.server.com/wp-content/uploads/2019/04/456-200x200.jpg" alt="Закат солнца" />
    </a>
    <a href="http://www.server.com/wp-content/uploads/2019/04/789.jpg">
        <img src="http://www.server.com/wp-content/uploads/2019/04/789-200x200.jpg" alt="Полдень в лесу" />
    </a>
</div>

Добавляем lightbox для галереи

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

Если на странице несколько галерей, то для каждой из них будет добавлен элемент <style>. Давайте вместо этого создадим в директории плагина один файл стилей и подключим его в коде плагина. CSS-правила, описанные в этом файле, будут использовать все галереи на странице.

Файл wp-content/plugins/tokmakov-gallery/tokmakov-gallery.php:

<?php
/*
Plugin Name: Галерея изображений
Plugin URI: https://tokmakov.msk.ru
Description: Изменяет работу стандартной галереи WordPress
Version: 1.0
Author: Евгений Токмаков
Author URI: https://tokmakov.msk.ru
*/

/*
 * Подключаем наш файл стилей для галереи и подключаем css и js
 * файлы lightbox-a для показа изображений в модальном окне
 */
add_action(
    'wp_enqueue_scripts',
    function () {
        /*
         * Подключаем наш файл стилей для галереи
         */
        wp_enqueue_style(
            'tokmakov-gallery-css', // будет зарегистрирован под этим именем
            plugin_dir_url(__FILE__) . 'tokmakov-gallery.css'
        );

        /*
         * Подключаем css и js файлы lightbox-a
         */
        wp_enqueue_style(
            'tokmakov-swipebox-css', // будет зарегистрирован под этим именем
            plugin_dir_url(__FILE__) . 'swipebox/css/swipebox.min.css'
        );
        wp_enqueue_script(
            'tokmakov-swipebox-js', // будет зарегистрирован под этим именем
            plugin_dir_url(__FILE__) . 'swipebox/js/jquery.swipebox.min.js',
            array('jquery'), // должен быть подключен после jquery
            null, // версии нет, поэтому null
            true // подключаем перед закрывающим тегом body
        );

        /*
         * Подключаем js-файл инициализации lightbox-a
         */
        wp_enqueue_script(
            'tokmakov-gallery-js', // будет зарегистрирован под этим именем
            plugin_dir_url(__FILE__) . 'tokmakov-script.js',
            array( // должен быть подключен после jquery и tokmakov-swipebox-js
                'jquery',
                'tokmakov-swipebox-js'
            ),
            null, // версии нет, поэтому null
            true // подключаем перед закрывающим тегом body
        );
    }
);

add_filter(
    'post_gallery',
    function($output, $attr) {
        // $output содержит результат работы функции gallery_shortcode()
        if (!empty($attr['ids'])) {
            // были заданы идентификаторы изображений, которые надо показать
            $pictures = get_posts([
                'posts_per_page' => -1,
                'include' => $attr['ids'],
                'post_type' => 'attachment',
                'post_mime_type' => 'image',
                'orderby' => 'post__in',
            ]);
        } elseif (!empty($attr['id'])) {
            // задан идентификатор записи, показываем привязанные изображения
            $id = intval($attr['id']);
            $pictures = get_children([
                'post_parent'    => $id,
                'post_type'      => 'attachment',
                'post_mime_type' => 'image',
            ]);
        } else {
            // показываем изображения, привязанные к текущей записи или странице
            $post = get_post();
            $id = $post->ID;
            $pictures = get_children([
                'post_parent'    => $id,
                'post_type'      => 'attachment',
                'post_mime_type' => 'image',
            ]);
        }

        if (empty($pictures)) {
            return '';
        }

        /*
         * На странице может быть несколько галерей, поэтому будем их нумеровать.
         * В этом случае мы сможем указать разные значения атрибута rel для каждой
         * галереи на странице. Наш lightbox работает так, что позволяет просмотреть
         * все картинки на странице с css-классом swipebox в модальном окне. Т.е.
         * lightbox создает как бы одну большую галерею, даже если их несколько.
         * С помощью атрибута rel мы сможем разделить все картинки с css-классом
         * swipebox на отдельные галереи, что нам и нужно.
         */
        static $instance = 0;
        $instance++;
        $rel = 'gallery-images-' . $instance;

        // выводим каждую картинку из галереи
        foreach($pictures as $picture) {
            $href = esc_url($picture->guid);
            $tmp = wp_get_attachment_image_src($picture->ID, 'medium');
            $src = $tmp[0];
            $title = esc_attr($picture->post_title);
            $items[] =
<<<ITEM
<a href="$href" class="swipebox" title="$title" rel="$rel">
    <img src="$src" alt="" />
</a>
ITEM;
        }

        $items = PHP_EOL . implode(PHP_EOL, $items) . PHP_EOL;
        $html = '<div class="gallery-images">' . $items . '</div>';

        return PHP_EOL . $html . PHP_EOL;
    },
    10,
    2
);

Файл wp-content/plugins/tokmakov-gallery/tokmakov-style.css:

.gallery-images {
    display: flex;
    flex-wrap: wrap;
    margin-top: 20px;
}
    .gallery-images > a {
        box-sizing: border-box;
        overflow: hidden;
        width: 23%;
        margin-right: 2.66666%;
        border: 1px solid #cfcfcf;
        background-color: #f5f5f5;
        padding: 10px;
        margin-bottom: 2.66666%;
        /* для центрирования картинок */
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .gallery-images > a:nth-child(4n) {
        margin-right: 0;
    }
        .gallery-images > a > img {
            max-width: 100%;
        }

Файл wp-content/plugins/tokmakov-gallery/tokmakov-script.js:

jQuery(document).ready(function($) {
    $('.swipebox').swipebox();
});

Функции для работы с шорткодом галереи

Функция get_post_gallery()

Получает первую галерею из текста указанной записи/поста. Ищет шорткод [gallery] в тексте, обрабатывает его и возвращает массив данных картинок галереи.

Функция get_post_galleries()

Получает все галереи из текста указанной записи/поста. Ищет шорткоды [gallery] в тексте, обрабатывает их и возвращает массив данных картинок галерей.

Функция get_post_gallery_images()

Получает все URL картинок первой галереи из указанного текста записи/поста, если галерея в тексте есть.

Функция get_post_galleries_images()

Получает все URL картинок галерей из указанного текста записи/поста, если галереи в тексте имеются.

Поиск: CMS • Web-разработка • WordPress • Галерея • Плагин • Шорткод • Shortcode • gallery_shortcode • Gallery • Изображение • Image

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.