/ Wordpress / Принцип создания нескольких метаполей

Принцип создания нескольких метаполей

19.03.2022

538

Рассмотрим способы более удобного и быстрого принципа добавления полей.

Создание любого поля состоит из 2-х частей: добавление поля и сохранение поля.

Добавление полей (строка)

Добавления поля включает в себя 2 функции: создание метабокса и вывод элементов управления полем (самого поля в админке). Пример:

// Произвольное поле Идентификатор тура
add_action('add_meta_boxes', 'tourid_box');
function tourid_box() { add_meta_box('tourid_block', 'Идентификатор тура', 'tourid_box_func', 'post', 'normal', 'high'); }

function tourid_box_func($post){
	$tourid = get_post_meta($post->ID, 'tourid', 1);
	?>
	<input type="text" name="extra[tourid]" id="post_tourid" value="<?php if($tourid){echo $tourid;}?>" style="width: 100%;" />
	<?php 
}

Чтобы добавить еще одно поле, мы должны скопировать эти 2 функции и заменить tourid на другой идентификатор, ну и также поменять наименование поля.

Также нужно упомянуть, что можно в одном метабоксе вывести несколько полей (и любых других элементов управления и оформления), если это обусловлено логикой. Пример:

// Произвольное поле Адрес и Координаты
add_action('add_meta_boxes', 'address_box');
function address_box() { add_meta_box('address_block', 'Адрес и координаты точки', 'address_box_func', 'post', 'normal', 'high'); }

function address_box_func($post){
	$coordinates = get_post_meta($post->ID, 'coordinates', 1);
	$address = get_post_meta($post->ID, 'address', 1);
	?>
	<input required class="geo-source" type="text" name="extra[address]" value="<?php if($address){echo $address;}?>" style="width:100%;" placeholder="Адрес" />
	<input required class="geo-target" type="text" name="extra[coordinates]" value="<?php if($coordinates){echo $coordinates;}?>" placeholder="Координаты" />
	<div class="btn geo-start">Найти координаты</div>
	<?php
}

Сохранение полей (строка)

За счет того что при передаче полей для сохранения мы передаем их в массиве extra, функция сохранения полей будет единая для всех.

// Сохранение полей (общий для всех полей)
add_action('save_post', 'fields_box_update');
function fields_box_update($post_id){
	if (!wp_verify_nonce($_POST['atb_nonce'], __FILE__)) return false; // Проверка, что сохраняется нужное поле
	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return false; // Проверка, что это не автосохранение
	if (!current_user_can('edit_post', $post_id)) return false; // Проверка, что пользователь может изменять этот пост
	if(!isset($_POST['extra']) ) return false;    // Проверка, что нам пришли все поля
	foreach($_POST['extra'] as $key=>$value){ // Циклом добавляем поля. Можно и в ручную это делать... Но так проще добавить новое поле
		if(empty($value) AND $value != 0){ // Если значение пустое и не равно 0
			delete_post_meta($post_id, $key); // Удаляем это поле из мета-данных
			continue; // Продолжаем
		}
		update_post_meta($post_id, $key, $value); // Обновляем или добавляем мета-данные
	}
	return $post_id;
}

Другие типы полей (кроме TyniMCE)

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

Чекбокс:

// Произвольное поле Менеджер
add_action('add_meta_boxes', 'manager_box');
function manager_box() { add_meta_box('manager_block', 'Менеджер', 'manager_box_func', 'post', 'normal', 'high'); }

function manager_box_func($post){
	
    $managers = get_post_meta($post->ID, 'manager', 1);
	
    $elements = array(
	'Денис',
        'Дарья',	
    );
	
    // Провести цикл через массив и установить флажок для каждого элемента
    foreach ( $elements as $element) {

        if ( in_array( $element, $managers ) ) { $checked = 'checked="checked"'; } 
		else { $checked = null; }
        ?>

        <label>
		<input  type="checkbox" name="extra[manager][]" value="<?php echo $element; ?>" <?php echo $checked; ?> /><?php echo $element; ?>
		</label>

        <?php
    }
	
}

Принцип сохранения чекбоксов: сохраняется значение атрибута value. И если просто отключить чекбокс и сохранить, то чекбокс останется активным. Чтобы этого избежать, нужно либо добавлять скрипт который будет менять значение value в зависимости от активности:

<script>jQuery('#thumb_active').on('click', function(){
	if (jQuery('#thumb_active').is(':checked')) {
		jQuery(this).attr('value', 'active');
	} else {
		jQuery(this).attr('value', 'unactive');
	}
});</script>

И выводить активность чекбокса в зависимости от значения поля. Но минус этого способа заключается в том что значение поля будет сохранятся в любом случае. Чтобы не сохранять значение поля в БД при отключенном чекбоксе нужно добавлять условие в функцию сохранения:

if ( !empty($_POST['thumb_active']) ) {
	update_post_meta($post_id, 'thumb_active', $_POST['thumb_active']);
} else {
	delete_post_meta($post_id, 'thumb_active');
}

При этом одиночный чекбокс будет выглядить так:

<?php $thumb_config = get_post_meta($post->ID, 'thumb_config', 1); ?>

<label>
	<input id="thumb_active" type="checkbox" name="thumb_active" <?php if( $thumb_active ){ echo 'checked="checked"'; } ?> />
	Показывать в плитке
</label>

Список:

// Произвольное поле Статус точки
add_action('add_meta_boxes', 'condition_box');
function condition_box() { add_meta_box('condition_block', 'Статус точки', 'condition_box_func', 'post', 'normal', 'high'); }

function condition_box_func($post){
	
	$condition = get_post_meta($post->ID, 'condition', 1);
	?>
	<select id="condition" required name="extra[condition]">
		<option></option>
		<option id="dot_working" value="Работающая торговая точка" <?php if($condition == 'Работающая торговая точка'){echo 'selected';}?>>Работающая торговая точка</option>		
		<option id="dot_potential" value="Потенциальный клиент" <?php if($condition == 'Потенциальный клиент'){echo 'selected';}?>>Потенциальный клиент</option>
		<option id="dot_discontinued" value="Отгрузка прекращена" <?php if($condition == 'Отгрузка прекращена'){echo 'selected';}?>>Отгрузка прекращена</option>		
	</select>
	<?php	
}

Добавление и сохранение полей TyniMCE

Добавления полей TyniMCE (с визуальным редактором) немного отличается функцией создания поля:

// Поле Характеристики
add_action('add_meta_boxes', 'params_box');
function params_box() {
	add_meta_box('params_box', 'Характеристики', 'params_box_func', 'post', 'normal', 'high');
}

function params_box_func( $post ) {
	wp_nonce_field( plugin_basename( __FILE__ ), 'atb_nonce' );
	$params = get_post_meta( $post->ID, 'params', false );
	wp_editor( $params[0], 'params' );
}

Есть проблема в том что в функции wp_editor мы не можем указать массив extra а только прописать сам идентификатор, т.к. в этот параметр можно указать только строчные латинский буквы и больше никаких символов. Но мы будем решать эту проблему в функции сохранения.

Подобные поля также можно копировать только заменяя идентификатор (в данном случае params).

Особенности в функции сохранения

Мы должны немного изменить общую функцию сохранения.

Изменить строку

if (!wp_verify_nonce($_POST['atb_nonce'], __FILE__)) return false;

на

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

И еще добавить в массив extra созданные поля TyniMCE

// Добавляем поля TyniMCE в массив extra
$_POST['extra']['descript'] = $_POST['descript'];
$_POST['extra']['features'] = $_POST['features'];
$_POST['extra']['params'] = $_POST['params'];

Функция сохранения будет выглядеть так:

add_action('save_post', 'fields_box_update');
function fields_box_update($post_id){
	
	if ( ( isset ( $_POST['atb_nonce'] ) ) && ( ! wp_verify_nonce( $_POST['atb_nonce'], plugin_basename( __FILE__ ) ) ) )
		return; // Проверка, что передаются нужные поля
	
	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return false; // Проверка, что это не автосохранение
	if (!current_user_can('edit_post', $post_id)) return false; // Проверка, что пользователь может изменять этот пост	
	
	// Добавляем поля TyniMCE в массив extra
	$_POST['extra']['descript'] = $_POST['descript'];
	$_POST['extra']['features'] = $_POST['features'];
	$_POST['extra']['params'] = $_POST['params'];
	
	if(!isset($_POST['extra']) ) return false;    // Проверка, что нам пришли все поля
	foreach($_POST['extra'] as $key=>$value){ // Циклом добавляем поля. Можно и в ручную это делать... Но так проще добавить новое поле
		if(empty($value) AND $value != 0){ // Если значение пустое и не равно 0
			delete_post_meta($post_id, $key); // Удаляем это поле из мета-данных
			continue; // Продолжаем
		}
		update_post_meta($post_id, $key, $value); // Обновляем или добавляем мета-данные
	}
	
	return $post_id;
}

Поделиться в соц. сетях:

  • Комментарии
  • Вложения

Добавить комментарий

Пока нет комментариев. Будь первым!

Принцип создания нескольких метаполей
Письма Woocommerce
Рекомендации для васПисьма WoocommerceOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.