Если вы реально устали от поисков плагина для загрузки ваших галерей из такого популярного фотохостинга как Flickr, повторяюсь — именно галереи (вставка отдельных фото по умолчанию включена в WP), то добро пожаловать под кат.

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

Для приготовления облегчения нам понадобятся следующие ингредиенты:

  • Замечательная JavaScript библиотека Galleria
  • Открытая и общедоступная CDN jsDelivr
  • Немного знаний Shortcode API или инструмент GenerateWP
  • Надежная связка руки+голова (опционально)


Файл functions.php


Открываем "волшебный" файл functions.php нашей темы и подключаем скрипты Galleria с CDN jsDelivr:
wp_register_script( 'galleria', '//cdn.jsdelivr.net/g/galleria@1.4.2(galleria.min.js+plugins/flickr/galleria.flickr.js)', false, false, false );

Чтобы понимать как это сделать я приведу пример файла functions.php действующей по умолчанию темы twentyfifteen со строки 220:

Пример файла functions.php
/**
 * Enqueue scripts and styles.
 *
 * @since Twenty Fifteen 1.0
 */
function twentyfifteen_scripts() {
    // Add custom fonts, used in the main stylesheet.
    wp_enqueue_style( 'twentyfifteen-fonts', twentyfifteen_fonts_url(), array(), null );

    // Add Genericons, used in the main stylesheet.
    wp_enqueue_style( 'genericons', get_template_directory_uri() . '/genericons/genericons.css', array(), '3.2' );

    // Load our main stylesheet.
    wp_enqueue_style( 'twentyfifteen-style', get_stylesheet_uri() );

    // Load the Internet Explorer specific stylesheet.
    wp_enqueue_style( 'twentyfifteen-ie', get_template_directory_uri() . '/css/ie.css', array( 'twentyfifteen-style' ), '20141010' );
    wp_style_add_data( 'twentyfifteen-ie', 'conditional', 'lt IE 9' );

    // Load the Internet Explorer 7 specific stylesheet.
    wp_enqueue_style( 'twentyfifteen-ie7', get_template_directory_uri() . '/css/ie7.css', array( 'twentyfifteen-style' ), '20141010' );
    wp_style_add_data( 'twentyfifteen-ie7', 'conditional', 'lt IE 8' );

    wp_enqueue_script( 'twentyfifteen-skip-link-focus-fix', get_template_directory_uri() . '/js/skip-link-focus-fix.js', array(), '20141010', true );

    if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
        wp_enqueue_script( 'comment-reply' );
    }

    if ( is_singular() && wp_attachment_is_image() ) {
        wp_enqueue_script( 'twentyfifteen-keyboard-image-navigation', get_template_directory_uri() . '/js/keyboard-image-navigation.js', array( 'jquery' ), '20141010' );
    }

    wp_enqueue_script( 'twentyfifteen-script', get_template_directory_uri() . '/js/functions.js', array( 'jquery' ), '20150330', true );
    wp_localize_script( 'twentyfifteen-script', 'screenReaderText', array(
        'expand'   => '<span class="screen-reader-text">' . __( 'expand child menu', 'twentyfifteen' ) . '</span>',
        'collapse' => '<span class="screen-reader-text">' . __( 'collapse child menu', 'twentyfifteen' ) . '</span>',
    ) );
    
    wp_register_script( 'galleria', '//cdn.jsdelivr.net/g/galleria@1.4.2(galleria.min.js+plugins/flickr/galleria.flickr.js)', false, false, false ); // эта сточка кода подключает Galleria
}
add_action( 'wp_enqueue_scripts', 'twentyfifteen_scripts' );


Если вы хотите, чтобы скрипты подключались только по вызову шорткода, то добавляете условие:
// Add Shortcode scripts
function custom_shortcode_scripts() {
	global $post;
	if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'flickr') ) {
		wp_enqueue_script( 'galleria' ); 
		}
}
add_action( 'wp_enqueue_scripts', 'custom_shortcode_scripts');


Далее вставляем в конец файла сам Shortcode, который я сгенерировал с помощью инструмента Shortcodes Generator сервиса GenerateWP:
Shortcode
// Add Shortcode
function flickr_gallery_shortcode( $atts ) {

    // Attributes
    extract( shortcode_atts(
        array(
            'set' => '',
        ), $atts )
    );

    // Code
return '<div style="position: relative; padding-bottom: 71%; height: 0; overflow: hidden;">
<div id="galleria"></div>
</div>
<script>
var speed = 5000;
var clickNext = true;
Galleria.loadTheme("//cdn.jsdelivr.net/galleria/1.4.2/themes/classic/galleria.classic.js");
Galleria.on("image", function(e) {
	var img = e.imageTarget;
	var picSource = $(img).attr("src");
	if (picSource == undefined) {
		picSource = $("img:first").attr("src");
	}
	var slashPieces = picSource.split("/");
	var lastSlash = (slashPieces[slashPieces.length - 1]);
	var lastPieces = lastSlash.split("_");
});
Galleria.run("#galleria", {
	responsive: true,
	preload: 4,
	initialTransition: "fade",
	debug: true,
	idleMode: false,
	pauseOnInteraction: true,
	fullscreenDoubleTap: true,
	backlink: false,
	transition: "fadeslide",
	showInfo: true,
	showCounter: true,
	clicknext: clickNext,
	thumbnails: true,
	flickr: "set:' . $set . '",
	height: 0.7,
	flickrOptions: {
		description: true,
		max: 100,
		imageSize: "big",
		sort: "interestingness-desc",
		thumbSize: "thumb",
	},
	extend: function() {
		var gallery = this;
		this.$("image-nav-right").click(function() {
			if (speed) {
				if (!gallery.isPlaying() && !clickNext) {
					gallery.play();
				} else if (clickNext) {
					if (!gallery.isPlaying()) {
						gallery.play();
					}
				}
			}
		});
		this.$("thumb-nav-left, thumb-nav-right").click(function() {
			if (gallery.isPlaying()) {
				gallery.pause();
			}
		});
		$("#flick").click(function() {
			gallery.pause();
		});
	}
});
$(document).ready(function() {
	var iOS = (navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false);
	var layout = "responsive";
});
</script>';

}
add_shortcode( 'flickr', 'flickr_gallery_shortcode' );



И наконец сам шорткод: [flickr set="id_вашей_галереи"]


Возможные проблемы


Единственная проблема с которой я столкнулся это jQuery.noConflict(). Оказывается по умолчанию в Wordpress библиотека jQuery идет с функцией jQuery.noConflict(), то есть к конце файла jquery.js (wp-includes/js/jquery/jquery.js) добавлена строчка jQuery.noConflict(); которую можно или удалить, — что будет не совсем правильно, или же переподключить jQuery из CDN с помощью кода:
	wp_deregister_script( 'jquery' );
	wp_register_script( 'jquery', '//cdn.jsdelivr.net/jquery/1.11.3/jquery.min.js', false, '1.11.3', false );
	wp_enqueue_script( 'jquery' );

	wp_deregister_script( 'jquery-migrate' );
	wp_register_script( 'jquery-migrate', '//cdn.jsdelivr.net/jquery.migrate/1.2.1/jquery-migrate.min.js', array( 'jquery' ), '1.2.1', false );
	wp_enqueue_script( 'jquery-migrate' );

Плюсы


Самый, на мой взгляд, решающий фактор в данном решении — это легкость. Не нужно писать тысячи строк кода, когда можно обойтись всего несколькими. Более тонкие настройки вы можете найти в официальной документации Galleria.

Минусы


Вы не сможете внедрить в галерею мкроразметку http://schema.org/ImageGallery.
 
Считаете ли вы полезным данное решение?

Проголосовало 34 человека. Воздержалось 17 человек.

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

Комментарии (14)


  1. MetaDone
    07.06.2015 23:19

    Для справки — код вида

    return '<div style="position: relative; padding-bottom: 71%; height: 0; overflow: hidden;"><div id="galleria"></div></div><script>var speed=5000;var clickNext=true;Galleria.loadTheme("//cdn.jsdelivr.net/galleria/1.4.2/themes/classic/galleria.classic.js");Galleria.on("image",function(e){var img=e.imageTarget;var picSource=$(img).attr("src");if(picSource==undefined){picSource=$("img:first").attr("src");}
    var slashPieces=picSource.split("/");var lastSlash=(slashPieces[slashPieces.length-1]);var lastPieces=lastSlash.split("_");});Galleria.run("#galleria",{responsive:true,preload:4,initialTransition:"fade",debug:true,idleMode:false,pauseOnInteraction:true,fullscreenDoubleTap:true,backlink:false,transition:"fadeslide",showInfo:true,showCounter:true,clicknext:clickNext,thumbnails:true,flickr:"set:' . $set . '",height:0.7,flickrOptions:{description:true,max:100,imageSize:"big",sort:"interestingness-desc",thumbSize:"thumb",},extend:function(){var gallery=this;this.$("image-nav-right").click(function(){if(speed){if(!gallery.isPlaying()&&!clickNext){gallery.play();}
    else if(clickNext){if(!gallery.isPlaying()){gallery.play();}}}});this.$("thumb-nav-left, thumb-nav-right").click(function(){if(gallery.isPlaying()){gallery.pause();}});$("#flick").click(function(){gallery.pause();});}});$(document).ready(function(){var iOS=(navigator.userAgent.match(/(iPad|iPhone|iPod)/g)?true:false);var layout="responsive";});</script>';
    

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


    1. jemali_m Автор
      07.06.2015 23:57
      -1

      То есть скинуть на новую строку в PHP коде )) Вы же понимаете?


      1. MetaDone
        08.06.2015 08:11

        ?>
        <div style="position: relative; padding-bottom: 71%; height: 0; overflow: hidden;">
        <div id="galleria"></div>
        </div>
        <script>
        var speed=5000;
        var clickNext=true;
        Galleria.loadTheme("//cdn.jsdelivr.net/galleria/1.4.2/themes/classic/galleria.classic.js");
        Galleria.on("image",function(e){
        var img=e.imageTarget;
        var picSource=$(img).attr("src");if(picSource==undefined){picSource=$("img:first").attr("src");
        }
        var slashPieces=picSource.split("/");
        var lastSlash=(slashPieces[slashPieces.length-1]);
        var lastPieces=lastSlash.split("_");});
        Galleria.run("#galleria",{responsive:true,preload:4,initialTransition:"fade",debug:true,idleMode:false,pauseOnInteraction:true,fullscreenDoubleTap:true,backlink:false,transition:"fadeslide",showInfo:true,showCounter:true,clicknext:clickNext,thumbnails:true,flickr:"set:<?php echo $set ?>",height:0.7,flickrOptions:{description:true,max:100,imageSize:"big",sort:"interestingness-desc",thumbSize:"thumb",},extend:function(){var gallery=this;this.$("image-nav-right").click(function(){if(speed){if(!gallery.isPlaying()&&!clickNext){gallery.play();}
        else if(clickNext){if(!gallery.isPlaying()){gallery.play();}}}});this.$("thumb-nav-left, thumb-nav-right").click(function(){if(gallery.isPlaying()){gallery.pause();}});$("#flick").click(function(){gallery.pause();});}});
        $(document).ready(function(){var iOS=(navigator.userAgent.match(/(iPad|iPhone|iPod)/g)?true:false);var layout="responsive";});
        </script>
        <?php
        


        В таком виде если отформатировать то уже лучше смотрится


        1. jemali_m Автор
          08.06.2015 08:15

          Исправил.


          1. MetaDone
            08.06.2015 08:17

            не совсем так как я имел в виду, но теперь хоть читабельно


  1. kovalevsky
    08.06.2015 10:34

    Простите, а зачем переподключать jQuery или что-то править?

    (function ($) {
        // $ = jQuery
    }(jQuery));
    

    или
    jQuery(document).ready(function ($) {
        // $ = jQuery
    });
    

    Вас такое чем конкретно не устраивает, чтоб второй раз jQuery загружать?

    Собственно в документации ф-ции, которую Вы приводите в коде это и так написано — codex.wordpress.org/%D0%A1%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D1%87%D0%BD%D0%B8%D0%BA_%D0%BF%D0%BE_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F%D0%BC/wp_enqueue_script


    1. jemali_m Автор
      08.06.2015 11:19

      Нет, вы не поняли. В любом, том или ином случае необходимо править jQuery, то бишь вносить свои дополнения. В моем случае я остановился на переподключении jQuery и jQuery.migrate из CDN, так как считаю данное решение для себя более приемлемым относительно других подключаемых библиотек.
      В начале поста было написано, что делалось на скорую руку. Доработок или настроек данного решения можно перечислять сколько угодно, каждому свое. Не судите строго )


      1. kovalevsky
        08.06.2015 11:34

        Честно — вообще не вижу случаев, тем более здесь, чтоб править jQuery.

        Я бы Ваш код поправил. Например, у Вас там галерея по ID. А что если Вы вставите несколько галерей на страницу? Скорее всего не будет работать, так ещё и кашу из JS и HTML продублирует в кол-ве вставленных шорткодов.

        У Вас там две переменных, speed и clickNext, которыми Вы засоряете window, их любой другой плагин может перезаписать.
        Если бы Вы обернули код, как я предложил выше — (function ($) {}(jQuery));, то, как минимум, не нужно было бы мутить с jQuery и не пихали бы всё в глобальный скоуп.

        Далее — раз уже у вас захардкорено всё в куче, то и ID у галереи можно хоть чем-нибудь разбавить, чтоб можно было вставить несколько шорткодов.


        1. jemali_m Автор
          08.06.2015 12:14

          Не спорю, так и есть! Я же говорю — «доработок или настроек данного решения можно перечислять сколько угодно, каждому свое».
          А вот на счет «разбавить», то я готов выслушать ваше предложение.


          1. kovalevsky
            08.06.2015 14:54

            Ну смотрите, Вы можете к ID блока с галереей добавлять timestamp, пропускать название через uniqid(), таким образом у Вас не 100% не будет 2х одинаковых ID на странице, соответственно Вы сможете загрузить две или более галереи на страницу.

            Всё это дело всё равно в PHP забито, так что Вы просто можете сделать что-то подобное:

            // ...
            $id = uniqid('galleria');
            // ...
            // <div id="galleria"></div> меняем на:
            <div id="$id"></div>
            // в JS части 
            // Galleria.run("#galleria", { меняем на
            Galleria.run("$id", {
            

            Вот по примеру такого псевдокода должно решить проблему.


            1. kovalevsky
              08.06.2015 14:58

              А вообще, в идеале конечно к этому всему добавить класс, JS в отдельный файл, а там уже что-то вроде:

              $('.galleria').each(
                 Galleria.run(this.id, // ...
              );
              

              Было бы куда лучше. У Вас бы весь этот код не дублировался бы на каждый вызов шорткода.


              1. jemali_m Автор
                08.06.2015 15:18

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


                1. kovalevsky
                  08.06.2015 16:33

                  Я этими плагинами на хлеб зарабатываю :)
                  Так что если думаете релизить его на вп.орг, то Вам ещё много работы предстоит


                  1. jemali_m Автор
                    08.06.2015 16:43

                    Нет нет нет..., это просто мелочь. Я увлекаюсь разными CMS и CMF, а ВордПресс действительно неплох со своим API. Что касается плагинов, то более или менее нужные — все из них здорово грузят сервер. К примеру, в своем первом посте я уже описывал громоздкость Jetpack.
                    Так что плагины плагинами, а вот такие мелочи вроде описанной в данном посте никогда не помешают.