Йоу-йоу! Работал я над сайтом компании, которая занимается производством домов из древесины. Им очень хотелось сделать сайт с огромным количеством фотографий и сделать это на одной странице с разделением на несколько галерей. Дело это всё «крутиться» на WordPress’е. А сейчас уже работает как часики) Так, что погнали
Да-да! Всё как в очумелых ручках! Так вот, нам понадобится:
Нужно создать папку, в которой будет хранится весь наш код внутри темы. Я у себя создал папку modiles > fancy-gallery. А там создал файлы: index.php и app.js. И подключил в function.php
// Подключение index.php if(file_exists(get_template_directory() . "/modules/fancy-gallery/index.php")){ require_once get_template_directory() . "/modules/fancy-gallery/index.php"; } // Подключение app.js wp_enqueue_script( 'application', get_template_directory_uri() . '/js/app.js', array('gjQuery', 'fancybox'), '0.1.0', true );
О том как правильно подключать скрипты в wordpress вы можете прочитать в моей статье в моей статье.
Это нужно для того, чтобы можно было в админке создавать несколько галерей. Так что в index.php пишем
add_action('init', 'fgb_fs_materials'); function fgb_fs_materials(){ register_post_type('x_gallery', array( 'labels' => array( 'name' => 'xGallery', // Основное название типа записи 'singular_name' => 'xGallery', // отдельное название записи типа 'add_new' => 'Add item', 'add_new_item' => 'Add item', 'edit_item' => 'Edit item', 'new_item' => 'New item', 'view_item' => 'View item', 'search_items' => 'Search', 'not_found' => 'Not found', 'not_found_in_trash' => 'No Material found in the basket', 'parent_item_colon' => '', 'menu_name' => 'xGallery' ), 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => true, 'capability_type' => 'post', 'has_archive' => true, 'hierarchical' => false, 'menu_position' => null, 'supports' => array('title','editor', 'thumbnail','excerpt') ) ); }
Проверяем появился ли новый тип записей в админке. Добавляем произвольное поле для id галереи. Мы позже будем его использовать в JS.
add_action('add_meta_boxes_fgb_fs_gallery', 'fgb_fs_gallery_add_custom_box_id'); function fgb_fs_gallery_add_custom_box_id(){ add_meta_box( 'x_id', __('ID', 'fgb'), 'fgb_fs_gallery_id_callback', 'fgb_fs_gallery' ); } // HTML код блока function fgb_fs_gallery_id_callback( $post, $meta ){ $screens = $meta['args']; // Используем nonce для верификации wp_nonce_field( plugin_basename(__FILE__), 'x_id_noncename' ); // Поля формы для введения данных echo '<label for="x_id">' . __("Put gallery id", 'fgb' ) . '</label> '; echo '<input type="text" id= "x_id" name="x_id" size="2" value="'. get_post_meta( $post->ID, '_x_id',true ) .'"/>'; } // Сохраняем данные, когда пост сохраняется add_action( 'save_post', 'x_id_save_postdata' ); function x_id_save_postdata( $post_id ) { // Убедимся что поле установлено. if ( ! isset( $_POST['x_id'] ) ) return; // проверяем nonce нашей страницы, потому что save_post может быть вызван с другого места. if ( ! wp_verify_nonce( $_POST['x_id_noncename'], plugin_basename(__FILE__) ) ) return; // если это авто-сохранение ничего не делаем if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return; // проверяем права юзера if( ! current_user_can( 'edit_post', $post_id ) ) return; // Все ОК. Теперь, нужно найти и сохранить данные // Очищаем значение поля input. $my_data = sanitize_text_field( $_POST['x_id'] ); // Обновляем данные в базе данных. update_post_meta( $post_id, '_x_id', $my_data ); }
Для вывода на странице нужно вызвать событие и повесить на него хук. На странице, на которой выкладываем, пишем do_action(‘x_gallery’); а в нашем php файле продолжаем.
add_action('x_gallery', 'x_gallery'); function x_gallery(){ $argm = [ 'post_type'=>'fgb_fs_gallery', 'orderby'=>'date', 'order'=>'ASC' ]; $query = new WP_query($argm); // Сюда в цикле собираем данные о картинках прикреплённых к записям $arr_x = []; $home_url = get_home_url(); while ( $query->have_posts() ) : $query->the_post(); $postID = get_the_ID(); // Для фансибокса $needPostMetaValue = get_post_meta($postID, '_x_id', true); // Кладём в ассоциативный массив данные о картинках $arr_x[$needPostMetaValue] = get_post_images(); ?> <!-- Вёрстка блока который мы выведем --> <!-- data-x-fancy селектор для fancybox --> <div> <a data-x-fancy="<?php echo $needPostMetaValue; ?>" data-src="<?php echo get_the_post_thumbnail_url($postID, 'full');?>" href="javascript:;"> <?php echo get_the_post_thumbnail($postID, 'x_face', ['class'=>'w-100']);?> </a> </div> <?php endwhile; // Сюда получаем будем собирать ссылки на картинки $images = []; foreach ($arr_x as $gallery=>$arr){ foreach ($arr as $item){ $el = wp_get_attachment_image_src( $item['id'], 'full'); $images[$gallery][] = $el[0]; } } ?> <!-- Печатаем скрипт с вызовам js части --> <script> window.addEventListener('load', function () { <?php foreach ($images as $key=>$value): ?> var <?php echo $key; ?> = new XSLICK({ galleryId: '<?php echo $key; ?>', images: [ <?php foreach ($value as $item): ?> <?php echo '"' . $item . '",' . PHP_EOL ?> <?php endforeach; ?> ] }, $); <?php endforeach; ?> }); </script> <?php }
Вы уже увидели, чего мы коснулись в предыдущем шаге и чтобы внести ясность что за скрипт в итоге будет, я вам напишу пример кода.
var new3 = new XSLICK({ galleryId: 'new3', images: [ "https://xakplant.ru/wp-content/uploads/2018/11/1.jpg", "https://xakplant.ru/wp-content/uploads/2018/11/2.jpg", "https://xakplant.ru/wp-content/uploads/2018/11/3.jpg", "https://xakplant.ru/wp-content/uploads/2018/11/4.jpg", ], }, $);
Это вызов моего js, который создаёт галерею во время загрузки страницы. В конструктор передан объект с моими данными и объект jquery. В объекте есть id галерея и массив с адресами всех картинок. Собственно к делу. В app.js пишем
var XSLICK = function (object, $) { this.galleryId = object.galleryId; this.images = object.images; // Создаём элементы галереи this.createGallery(); // Вставляем их на страницу this.appendeElement(); // Вызываем для них fancybox this.call($); }; XSLICK.prototype.createGallery = function () { // Создаём блок в котором будут все элементы var gallery = document.createElement('div'); gallery.id = this.galleryId; this.images.map(function (img) { // В цикле создаём ссылку, внутри которой картинка var el = new Image(); el.src = img; var link = document.createElement('a'); link.setAttribute('href', img); // Ссылке даём атрибут data-x-fancy c id галереи link.setAttribute('data-x-fancy', gallery.id); // Прячем link.style.display = 'none'; // Вставляем всё в наш блок gallery.insertAdjacentElement('beforeend', link); link.insertAdjacentElement('beforeend', el); }); this.gallery = gallery; return this; }; XSLICK.prototype.appendeElement = function () { // Вставляем всю галерею в body document.body.insertAdjacentElement('beforeend', this.gallery); }; XSLICK.prototype.call = function ($) { // Вызываем fancybox $().fancybox({selector : '[data-x-fancy="'+this.galleryId+'"]'}); }
Нужно заметить, что в fancybox3 распределении галерей несколько иначе, чем в версии 2.x и теперь инициализация разных галерей делается с помощью javascript.
$().fancybox({ selector : 'селектор' });
И теперь данный вызов будет следить за появлением новых элементов галереи. Это очень удобно. Но в документацию fancybox пришлось вчитываться)
Все готово! Можете пользоваться. В итоге у вас получиться примерно это: