когда нечего делать, а творческая душа требует реализации и хочется что-то сделать или написать, то я пишу сюда или делаю что-то на этом сайте. Кому интересна web-разработка, wordpress и то что рядом с этим, то заходите на мой сайт и читайте всякое...
Очумелые ручки! Строим галерею с «бэком» на Wordpress и фронтом на fancybox 3
Йоу-йоу! Работал я над сайтом компании, которая занимается производством домов из древисины. Им очень хотелось сделать сайт с огромным количеством фоторгафии и сделать это на одной странице с разделением на несколько галлерей. Дело это всё «крутиться» на WordPress’е. А сейчас уже работает как часики) Так, что погнали
Нам понадобиться
Да-да! Всё как в очумелых ручках! Так вот, нам понадобитья:
Рабочий сайт на WordPress
Плагин real.PostImages (для добавления картинок к записи)
Подключенный jQuery 3
Подключенный fancybox 3
Подготовка
Нужно создать папку в которой будет хранится весь наш код внутри темы. Я у себя создал папку modiles > fancy-gallery. А там создал файлы: index.php и app.js. И подключил в function.php
О том как правильно подключать скрипты в wordpress вы можете прочитать в моей статье в моей статье.
Шаг 1. Создание произвольного типа записи
Это нужно для того, чтобы можно было в аднимке создавать несколько галлерей. Так что в 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 );
}
Шаг 2. Выводим в цилке записи на странице.
Для вывода на странице нужно вызвать событие и повесить на него хук. На странице на которой вывожим пищем 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
}
Шаг 3. JS
Вы уже увидел, что мы коснулись в предудущем шаге и чтобы внести ясность, что за скрипт в итогре будет я вам напишу пример кода.
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 пришлось вчитываться)
Финиш
Все готово! Можете пользоваться. В итоге у вас получиться примерно это:
Поддержи Xakplant
Я давно хочу развить видеоверсию, но пока этого не получается из-за нехватки ресурсов. Сейчас я собираю деньги на новый компьютер и микрофон. Поддержи xaklant и ты увидишь полезные видео быстрее.