/ Wordpress / PostMeta

PostMeta

HIT

07.03.2016

2798

PostMeta — это функционал произвольных полей. В данной статье будет рассматриваться тема использования PostMeta без плагина Advanced Custom Fields.

Включаем в интерфейсе настроек записи Произвольные поля. В поле имя вписываем название поля (!только латинские и желательно одним словом), в значение вписываем содержимое поля. Если в одном поле несколько значений, нужно создавать несколько полей с одним и тем же полем, но разными значениями.

Данный стандартный функционал сильно уступает плагину Advanced Custom Fields. Целеснообразнее использовать его.

Спустя время убедился в обратном, что в простых случая лучше использовать стандартный функционал PostMeta. ACF конечно мощный инструмент, но и создает кучу лишнего кода и засоряет базу данных (на одно поле создает 2 записи).

Правильное создание дополнительного поля (PostMeta)

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

// Произвольное поле
add_action('add_meta_boxes', 'link_box');
function link_box() { add_meta_box('testfield_box', 'Ссылка слайда', 'atb_box_func', 'post', 'normal', 'high'); }

function atb_box_func($post){
$testfield = get_post_meta($post->ID, 'testfield', 1);
?>
<label><input style="width:100%;" type="text" name="extra[testfield]" value="<?php if($testfield){echo $testfield;}?>" /></label>
<input type="hidden" name="atb_nonce" value="<?php echo wp_create_nonce(__FILE__); ?>" />
<?php 
}

add_action('save_post', 'atb_box_update');
function atb_box_update($post_id){
	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)) { delete_post_meta($post_id, $key); }
		else { update_post_meta($post_id, $key, $value); }
	}
}

Последний блок сохранения может быть общим для нескольких полей — надо подумать об этом.

Если у остальных записей поля не создаются, то при сортировке по этому произвольному полю они выводиться не будут. В этом случае, все же, их нужно заводить с условно нулевым значением, изменив проверку при сохранении.

Пользовательские типы записей

Включение произвольных полей в пользовательских типах записей. track — это название произвольного типа записей.

// Произвольные поля для пользовательского типа записей

function true_custom_fields() {
	add_post_type_support( 'track', 'custom-fields'); // в качестве первого параметра укажите название типа поста
}
 
add_action('init', 'true_custom_fields');

Вывод данных

Вывести все метаданные записи

<?php the_meta(); ?>

Вывести конкретное поле (если значение единственное)

<?php echo get_post_meta($post->ID, 'film', true); ?>

Вывести конкретное поле (если значений несколько)

<?php $items = get_post_meta($post->ID, 'film', false); ?>

<?php foreach ( $items as $item) {
echo "<p>$item</p>";
} ?>

Вывести поле с данными содержащими тэги html (например если поле заполняется в редакторе wysiwyg)

<?php print htmlspecialchars_decode(get_post_meta($post->ID, 'tehparam', true)); ?>

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

<?php if(get_post_meta($post->ID, 'film', true)): ?>
<?php echo get_post_meta($post->ID, 'film', true); ?>
<?php endif; ?>

Парсим значение метаполя по запятым

Предположим что у нас текстовое поле и мы вводим несколько значений через запятую, например ссылки для youtube (7f2wg1pqQDs, 75TLVk_yxS4, StZcUAPRRac). И чтобы вывести 3 ролика нужно разделить строку на массив:

<?php $videos = preg_replace("/\s+/", "", get_post_meta($post->ID, 'video', 1));
if (!empty($videos)) : ?>
	<div class="posts-archive">
	<?php $videos_array = explode(",", $videos); 
	foreach ($videos_array as $video) : ?>
		<div class="hentry"><div class="youtube" data-embed="<?php echo $video; ?>"><div class="play-button"></div></div></div>
	<?php endforeach; ?>
	</div>
<?php endif; ?>

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

preg_replace(«/\s+/», «», $stroke); — удаление из строки пробелов

Вывод списка метаполей для произвольных типов записей

Создаем функцию

function generate_meta_keys(){
    global $wpdb;
    $post_type = 'shop_order';
    $query = "
        SELECT DISTINCT($wpdb->postmeta.meta_key) 
        FROM $wpdb->posts 
        LEFT JOIN $wpdb->postmeta 
        ON $wpdb->posts.ID = $wpdb->postmeta.post_id 
        WHERE $wpdb->posts.post_type = '%s' 
        AND $wpdb->postmeta.meta_key != '' 
        AND $wpdb->postmeta.meta_key NOT RegExp '(^[_0-9].+$)' 
        AND $wpdb->postmeta.meta_key NOT RegExp '(^[0-9]+$)'
    ";
    $meta_keys = $wpdb->get_col($wpdb->prepare($query, $post_type));
    return $meta_keys;
}

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

echo '<pre>';
print_r (generate_meta_keys()); 
echo '</pre>';

Альтернативный способ вывода метаполей

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

В цикле вывода записи добавляем следующий вызов (код позаимствовал на сайте wp-kama.ru):

$meta = new stdClass;
foreach( (array) get_post_meta( $post->ID ) as $k => $v ) $meta->$k = $v[0];

Теперь любое метаполе можно вывести по слагу так:

echo $meta->book;

Тоже решение, но с другим (более понятным) синтаксисом:

$current_post_meta = get_post_meta($post_id);
foreach ($current_post_meta as $meta_key => $meta_value) {
      $current_post_meta[$meta_key] = $meta_value[0];
}

Выводиться так:

echo $current_post_meta['aname'];

Есть один недостаток, если при выводе в цикле у какой-либо записи не будет данного поля то последует предупреждение Undefined index: aname in. Чтобы этого избежать можно делать такой вывод:

echo @$current_post_meta['aname'];

@ — символ экранирования подобных предупреждений.

Проверка пустое поле или нет:

<?php if (empty($current_post_meta['aname'])) {
echo 'пустое';
} else {
echo 'не пустое';
} ?>

Мета поле только для определенной категории

Чтобы выводить мета поле для определенной категории, нужно первую функцию (внутри) обернуть в условие:

function myplugin_add_price_box() {  
	$categories = get_the_category();
	if ($categories[0]->term_id == '2' ) {
		add_meta_box( 'myplugin_section_price', 'Цена', 'wp_editor_price_box', 'post' ); 
	}
}

Метабоксы обязательно должны добавляться хуком add_meta_boxes

add_action('add_meta_boxes', 'wysiwyg_register_params_meta_box');

Если, например, добавлять метабокс с так:

add_action('admin_init', 'wysiwyg_register_params_meta_box');

то условие по категории работать не будет, т.к. в тот момент эта глобальная еще не определена.

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

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

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

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

PostMeta
Эффекты с border
Рекомендации для васЭффекты с borderOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.