Галерея изображений для кастомного типа записи WordPress

3 комментария
5
Галерея изображений для кастомного типа записи WordPress

В данной статье мы рассмотрим PHP-скрипт, предназначенный для расширения функциональности административной панели WordPress. Он добавляет возможность прикреплять и управлять несколькими изображениями (галереей) к определённому типу записей (в данном случае — objects). Ниже приведено подробное объяснение его содержимого и назначения:В

Галерея изображений для кастомного типа записи WordPress

Регистрация метабокса (add_meta_box)

PHP
add_action( 'add_meta_boxes', 'thumbnail_add_custom_box' );
function thumbnail_add_custom_box() {
    $post_name = 'objects';  // ИЗМЕНИТЕ НА СВОЙ SLUG ТИПА ЗАПИСИ
    add_meta_box('thumbnail_sidebar', __( 'Фотографии объекта', 'wordplace' ), 'thumbnail_render_images', $post_name, 'side', 'default');
}
  • add_action('add_meta_boxes', ...) — хук, который добавляет новый блок (метабокс) в интерфейс редактирования записи.
  • add_meta_box() — функция, создающая новый блок в правой части редактора (в данном случае в колонке side).
  • Блок будет отображаться только для типа записей objects.
  • Название блока: «Фотографии объекта» (переводится с локализованной строки).

Отображение содержимого метабокса

PHP
function thumbnail_render_images() {
    global $wpdb;
    global $post;
    wp_nonce_field( plugin_basename( __FILE__ ), 'thumbnail_noncename' );
  • Функция wordplace_thumbnail_render_images() выводит содержимое блока.
  • wp_nonce_field() — добавляет скрытое поле для защиты от CSRF-атак (проверка подлинности запроса при сохранении).

Получение и отображение ранее загруженных изображений

PHP
$value = get_post_meta($post->ID, '_thumbnails_id', true);
$temp = explode(",", $value);
  • Получает строку с ID изображений, сохранённых в метаполе _thumbnails_id (например: 12,15,23).
  • Разделяет строку на массив по запятым.
PHP
foreach ( $temp as $img_id ) {
    $image_attributes = wp_get_attachment_image_src( $img_id , array(66,66) );
    echo '<img ... data-id="'.$img_id.'">';
}

Для каждого ID изображения:

  • Получает ссылку на миниатюру размером 66×66 пикселей.
  • Выводит тег <img> с атрибутом data-id, чтобы можно было идентифицировать изображение.

Интерфейс управления изображениями

PHP
echo "<input type='hidden' name='image_upload_val' id='image_upload_val' value='".$value."' />";
echo "<button class='button button-primary' id='thumbnail_image_upload'>Загрузить фотографии</button>";

JavaScript для работы с медиа-библиотекой

  • При клике на кнопку открывается встроенная медиа-библиотека WordPress.
  • При выборе изображения:
    • Его ID добавляется в скрытое поле image_upload_val.
    • Создаётся превью изображения (тег <img>) перед кнопкой.

Удаление изображения по клику

При клике на любое изображение в блоке оно:

  • Удаляется из DOM.
  • Удаляется из списка ID в скрытом поле.

Сохранение данных при обновлении записи

PHP
add_action( 'wp_insert_post', 'thumbnail_insert_postdata' );
function thumbnail_insert_postdata( $post_id ) {
    if ( ! current_user_can( 'edit_page', $post_id ) || ! current_user_can( 'edit_post', $post_id ) )
        return;

    if ( ! isset( $_POST['thumbnail_noncename'] ) || ! wp_verify_nonce( $_POST['thumbnail_noncename'], plugin_basename( __FILE__ ) ) )
        return;

    $post_ID = $_POST['post_ID'];
    $mydata = $_POST['image_upload_val'];
  • Хук wp_insert_post срабатывает при сохранении записи.
  • Проверки:
    • Пользователь имеет право редактировать запись.
    • Данные пришли с проверкой nonce.
  • Получает значение из image_upload_val (строка ID изображений, разделённых запятыми).

Логика сохранения/обновления метаполя

PHP
if($mydata == '') {
    delete_post_meta($post_ID, '_thumbnails_id', $mydata);
} else {
    $cur_data = get_post_meta($post_ID, '_thumbnails_id', true);
    if(!(empty($cur_data))) {
        update_post_meta($post_ID, '_thumbnails_id', $mydata);
    } else {
        add_post_meta($post_id, '_thumbnails_id', $mydata, true);
    }
}
  • Если поле пустое — удаляет метаполе.
  • Иначе:
    • Если метаполе уже существует — обновляет его.
    • Если нет — создаёт новое.

Пример получения и использования галереи в шаблоне

PHP
$gallery_ids = get_post_meta( $post->ID, '_thumbnails_id' ); // Получаем данные в виде строки.
$img_ids = explode(",", $gallery_ids); // Разбиваем строку на массив, через разделитель запятая.
//Далее мы можем использовать массив в цикле
foreach( $img_ids as $id ){
  echo '<img src="'.get_the_post_thumbnail_url( $id, 'full' ).'">'
}

Полный код скрипта

Данный код можно вставить в functions.php , но так как он довольно объемный, лучше поместить его в отдельный файл, например: gallery_images.php и уже созданный файл подключить в functions.php строкой:

PHP
require_once get_stylesheet_directory() . '/gallery_images.php';

А вот и полный скрипт:

PHP
/* Создаем поле с возможностью добавления картинок */
add_action( 'add_meta_boxes', 'thumbnail_add_custom_box' );
function thumbnail_add_custom_box() {
	$post_name = 'objects';  // указываем тип записи, можно post, page или custom_post_type
	add_meta_box('thumbnail_sidebar', __( 'Фотографии объекта', 'nsr' ), 'thumbnail_render_images', $post_name, 'side', 'default');
}

/* Выводим содержимое блока с миниатюрками в созданном поле */
function thumbnail_render_images() {
	global $wpdb;
	global $post;
	// Используем nonce для проверки
	wp_nonce_field( plugin_basename( __FILE__ ), 'thumbnail_noncename' );

	// Поле для ввода данных
	// Используем get_post_meta, чтобы получить существующее значение из базы данных и использовать значение для формы
	$value = get_post_meta($post->ID, '_thumbnails_id', true);
	$temp = explode(",", $value);
	 
	if ( $temp && $value != '' ) {
		foreach ( $temp as $t_val ) {
			
			$image_attributes = wp_get_attachment_image_src( $t_val , array(66,66) );
			echo '<img ret src="'.$image_attributes[0].'" width="'.$image_attributes[1].'" height="'.$image_attributes[2].'" data-id="'.$t_val.'">';
		}
	}
	
	echo "<style type='text/css'>
		#thumbnail_sidebar {padding: 10px;} #thumbnail_sidebar .inside{padding: 5px; border: 2px dashed #e5e5e5;} #thumbnail_sidebar .inside img{margin:5px; border: 2px solid #e5e5e5;} #thumbnail_sidebar .inside img:hover{cursor: pointer; border: 2px solid #ff0000;} #thumbnail_image_upload{width: 100%;}
		</style>";
	echo "<input type='hidden' name='image_upload_val' id='image_upload_val' value='".$value."' />";
	echo "<button class='button button-primary' id='thumbnail_image_upload'>" . __( 'Загрузить фотографии', 'nsr' ) . "</button>";
	// скрипт можно вывести в отдельный js файл и подключить в админке, но для удобства привожу его сразу здесь
	echo "<script type='text/javascript'> 

	jQuery(document).ready(function(jQuery){
		var _custom_media = true,
				_orig_send_attachment = wp.media.editor.send.attachment;

		jQuery('#thumbnail_image_upload').click(function(e) {
			var send_attachment_bkp = wp.media.editor.send.attachment;
			var button = jQuery(this);
			var id = button.attr('id').replace('_button', '');
			_custom_media = true;
			wp.media.editor.send.attachment = function(props, attachment){
				if ( _custom_media ) {
				console.log(attachment);
				 
						//jQuery('#'+id).val(attachment.url);
				
				if(jQuery('#image_upload_val').val() == '')
					jQuery('#image_upload_val').val(attachment.id);
				else
				{
					oldVal = jQuery('#image_upload_val').val();
						jQuery('#image_upload_val').val(oldVal+','+attachment.id);
				}
				
				var src_str = attachment.url;
				jQuery('#image_upload_val').before('<img width=66 height=66 src='+src_str+' data-id='+attachment.id+' class=attachment-66x66 />');
				//jQuery('#post').submit();
				} else {
					return _orig_send_attachment.apply( this, [props, attachment] );
				};
			}

			wp.media.editor.open(button);
			return false;
		});

		jQuery('.add_media').on('click', function(){
			_custom_media = false;
		});
		
		jQuery(document).on('click', '#thumbnail_sidebar img',function(){
			valArr = jQuery('#image_upload_val').val().split(',');
			console.log(valArr);
			//alert(jQuery(this).attr('data-id'));
			var index = valArr.indexOf(jQuery(this).attr('data-id'));
			if (index > -1) 
			{
				valArr.splice(index, 1);
				jQuery(this).remove();
			}
			console.log(valArr);
			jQuery('#image_upload_val').val(valArr.toString());
		});
	});
	</script>";	
}

/* Когда мы сохраняем запись, сохраняем данные произвольного поля */
add_action( 'wp_insert_post', 'thumbnail_insert_postdata' );
function thumbnail_insert_postdata( $post_id ) {
	global $wpdb;
		
	if ( ! current_user_can( 'edit_page', $post_id ) ) return;
	 
		
	if ( ! isset( $_POST['thumbnail_noncename'] ) || ! wp_verify_nonce( $_POST['thumbnail_noncename'], plugin_basename( __FILE__ ) ) )	return;

	// Теперь мы можем сохранить значение поля в базе данных

	// если сохраняем произвольно поле, get post_ID
	$post_ID = $_POST['post_ID'];
	// санирование введенных пользователем данных
	// $mydata = sanitize_text_field( $_POST['myplugin_priceCode'] );
	global $mydata;
	$mydata = $_POST['image_upload_val'];
		
	// если значение пустое, то удаляем содержимое из бд
	if($mydata == '') {
		delete_post_meta($post_ID, '_thumbnails_id', $mydata);
	}
		
	if($mydata) {
		$cur_data = get_post_meta($post_ID, '_thumbnails_id', true);
		if(!(empty($cur_data)))
		{
			//$cur_data .=",".$mydata;
			update_post_meta($post_ID, '_thumbnails_id', $mydata);
		}
		else
		{
			add_post_meta($post_id, '_thumbnails_id', $mydata, true);
		}
	}
		 
}
Открыть
guest
3 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии