/ Wordpress / Продвинутые metabox

Продвинутые metabox

HIT

21.08.2016

2492

3

Существую станданртные metabox: text, textarea (область текста), checkbox, radiobutton, selectbox (выпадающий список). Но помимо этих существуют более сложные metabox’ы, рассмотрим их.

Metabox редактор WYSIWYG (старый способ)

define('WYSIWYG_META_BOX_ID', 'my-editor');
define('WYSIWYG_EDITOR_ID', 'myeditor'); //Important for CSS that this is different
define('WYSIWYG_META_KEY', 'extra-content');

add_action('admin_init', 'wysiwyg_register_meta_box');
function wysiwyg_register_meta_box(){
	add_meta_box(WYSIWYG_META_BOX_ID, __('WYSIWYG Meta Box', 'wysiwyg'), 'wysiwyg_render_meta_box', 'post');
}

function wysiwyg_render_meta_box(){
	global $post;

	$meta_box_id = WYSIWYG_META_BOX_ID;
	$editor_id = WYSIWYG_EDITOR_ID;

	//Add CSS & jQuery goodness to make this work like the original WYSIWYG
	echo "
	<style type='text/css'>
	#$meta_box_id #edButtonHTML, #$meta_box_id #edButtonPreview {background-color: #F1F1F1; border-color: #DFDFDF #DFDFDF #CCC; color: #999;}
	#$editor_id{width:100%;}
	#$meta_box_id #editorcontainer{background:#fff !important;}
	#$meta_box_id #$editor_id_fullscreen{display:none;}
	</style>

	<script type='text/javascript'>
	jQuery(function($){
		$('#$meta_box_id #editor-toolbar > a').click(function(){
			$('#$meta_box_id #editor-toolbar > a').removeClass('active');
			$(this).addClass('active');
		});

		if($('#$meta_box_id #edButtonPreview').hasClass('active')){
			$('#$meta_box_id #ed_toolbar').hide();
		}

		$('#$meta_box_id #edButtonPreview').click(function(){
			$('#$meta_box_id #ed_toolbar').hide();
		});

		$('#$meta_box_id #edButtonHTML').click(function(){
			$('#$meta_box_id #ed_toolbar').show();
		});
		
		//Tell the uploader to insert content into the correct WYSIWYG editor
		$('#media-buttons a').bind('click', function(){
			var customEditor = $(this).parents('#$meta_box_id');
			if(customEditor.length > 0){
				edCanvas = document.getElementById('$editor_id');
			}
			else{
				edCanvas = document.getElementById('content');
			}
		});
	});
	</script>
	";

	//Create The Editor
	$content = get_post_meta($post->ID, WYSIWYG_META_KEY, true);
	the_editor($content, $editor_id);

	//Clear The Room!
	echo "<div style='clear:both; display:block;'></div>";
}

add_action('save_post', 'wysiwyg_save_meta');
function wysiwyg_save_meta(){

	$editor_id = WYSIWYG_EDITOR_ID;
	$meta_key = WYSIWYG_META_KEY;

	if(isset($_REQUEST[$editor_id]))
	update_post_meta($_REQUEST['post_ID'], WYSIWYG_META_KEY, $_REQUEST[$editor_id]);

}

Metabox редактор WYSIWYG (новый способ)

Есть более быстрый (простой, современный) способ вывести метабокс в виде редактора WYSIWYG:

add_action('admin_init', 'wysiwyg_register_custom_meta_box');
function wysiwyg_register_custom_meta_box() {
	add_meta_box('WYSIWYG_META_BOX_ID', __('Ответ', 'wysiwyg') , 'custom_wysiwyg', 'quest');
}
 
function custom_wysiwyg($post) {
	$content = get_post_meta($post->ID, 'answer', true);
	wp_editor(htmlspecialchars_decode($content) , 'answer', array(
	"media_buttons" => true
	));
}
 
function custom_wysiwyg_save_postdata($post_id) {
	if (!empty($_POST['answer'])) {
		$data = htmlspecialchars($_POST['answer']);
		update_post_meta($post_id, 'answer', $data);
	}
}
 
add_action('save_post', 'custom_wysiwyg_save_postdata');

quest — тип записи
answer — слаг метаполя

WYSIWYG_META_BOX_ID — для каждого отдельного поля должен различаться.

Также в данном решении стоит декодер тэгов — htmlspecialchars_decode. При выводе поля он будет выводить тэги в виде текста. По сути он не нужен, т.к. мы используем редактор wysiwyg с целью форматирования. Необходимо убрать в двух местах htmlspecialchars_decode и htmlspecialchars и их круглые скобки (вокруг $content и вокруг $_POST[‘answer‘])

Вот правильные функции по созданию поля WYSIWYG. При добавлении поля необходимо поиском и заменой поменять все название specifications на актуальное, так же убрал лишние декодеры:

add_action('admin_init', 'specifications_register_custom_meta_box');
function specifications_register_custom_meta_box() {
	add_meta_box('specifications_metabox', 'Технические характеристики', 'specifications', 'post');
}
 
function specifications($post) {
	$content = get_post_meta($post->ID, 'specifications', true);
	wp_editor($content , 'specifications', array(
	"media_buttons" => true
	));
}
 
function specifications_save_postdata($post_id) {
	if (!empty($_POST['specifications'])) {
		$data = $_POST['specifications'];
		update_post_meta($post_id, 'specifications', $data);
	}
}
 
add_action('save_post', 'specifications_save_postdata');

Metabox Загрузчик Media (Media Uploader)

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

jQuery(function($){
	//действие при нажатии на кнопку загрузки изображения
	//вы также можете привязать это действие к клику по самому изображению
	$('.upload_image_button').click(function(){
		var send_attachment_bkp = wp.media.editor.send.attachment;
		var button = $(this);
		wp.media.editor.send.attachment = function(props, attachment) {
			$(button).parent().prev().attr('src', attachment.url);
			$(button).prev().val(attachment.id);
			wp.media.editor.send.attachment = send_attachment_bkp;
		}
		wp.media.editor.open(button);
		return false;    
	});
	
	// удаляем значение произвольного поля
	// если быть точным, то мы просто удаляем value у input type="hidden"
	$('.remove_image_button').click(function(){
		var r = confirm("Уверены?");
		if (r == true) {
			var src = $(this).parent().prev().attr('data-src');
			$(this).parent().prev().attr('src', src);
			$(this).prev().prev().val('');
		}
		return false;
	});
});

Подключаем функционал

function true_include_myuploadscript() {
	if ( ! did_action( 'wp_enqueue_media' ) ) {
		wp_enqueue_media();
	}
	// меняем admin.js на название созданного скрипта
	wp_enqueue_script( 'myuploadscript', get_stylesheet_directory_uri() . '/admin.js', array('jquery'), null, false );
}

add_action( 'admin_enqueue_scripts', 'true_include_myuploadscript' );

/* PHP-функция добавления полей в форму */
function true_image_uploader_field( $name, $value = '', $w = 115, $h = 90) {
	$default = get_stylesheet_directory_uri() . '/img/no-image.png';
	if( $value ) {
		$image_attributes = wp_get_attachment_image_src( $value, array($w, $h) );
		$src = $image_attributes[0];
	} else {
		$src = $default;
	}
	echo '
	<div>
	<img data-src="' . $default . '" src="' . $src . '" width="' . $w . 'px" height="' . $h . 'px" />
	<div>
	<input type="hidden" name="' . $name . '" id="' . $name . '" value="' . $value . '" />
	<button type="submit" class="upload_image_button button">Загрузить</button>
	<button type="submit" class="remove_image_button button">×</button>
	</div>
	</div>
	';
}

// Использование в метабоксах

function true_meta_boxes_u() {
	add_meta_box('truediv', 'Настройки', 'true_print_box_u', 'post', 'normal', 'high');
}
add_action( 'admin_menu', 'true_meta_boxes_u' );

function true_print_box_u($post) {
	if( function_exists( 'true_image_uploader_field' ) ) {
		true_image_uploader_field( 'uploader_custom', get_post_meta($post->ID, 'uploader_custom',true) );
	}
}

function true_save_box_data_u( $post_id ) {
	if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
	return $post_id;
	if (isset($_POST['uploader_custom'])) { update_post_meta( $post_id, 'uploader_custom', $_POST['uploader_custom']); }
	return $post_id;
}

add_action('save_post', 'true_save_box_data_u');
// Использование в настройках темы
function true_add_options_page_u() {
	if ( isset( $_GET['page'] ) == 'uplsettings' ) {
		if ( 'save' == isset( $_REQUEST['action'] ) ) {
			update_option('uploader_custom', $_REQUEST[ 'uploader_custom' ]);
			header("Location: ". site_url() ."/wp-admin/options-general.php?page=uplsettings&saved=true");
			die;
		}
	}
	add_submenu_page('options-general.php','Дополнительные настройки','Настройки','edit_posts', 'uplsettings', 'true_print_options_u');
}

function true_print_options_u() {
	if ( isset( $_REQUEST['saved'] ) ){
		echo '<div class="updated"><p>Сохранено.</p></div>';
	}
	?><div class="wrap">
	<form method="post">
	<?php
	if( function_exists( 'true_image_uploader_field' ) ) {
		true_image_uploader_field('uploader_custom', get_option('uploader_custom'));
	}
	?><p class="submit">
	<input name="save" type="submit" class="button-primary" value="Сохранить изменения" />
	<input type="hidden" name="action" value="save" />
	</p>
	</form>

	</div><?php
}

add_action('admin_menu', 'true_add_options_page_u');

Возникают небольшие косяки при загрузке файлов .pdf или других форматов не имеющих превью. В этом случае (если планируется использовать для поля такие файлы) нужно немного изменять скрипт и функцию вывода поля.

В скрипте подставлять путь до иконки файла:

$(button).parent().prev().attr('src', '/wp-content/themes/meisterwerk-2/images/pdf-2.png');

И в функции прописывать путь до иконки файла:

// Добавление полей в форму
function true_image_uploader_field_passport( $name, $value = '') {
	$default = get_stylesheet_directory_uri() . '/images/download.png';
	if( $value ) { $src = get_stylesheet_directory_uri() . '/images/pdf-2.png'; } 
	else { $src = $default;	}
	echo '
	<div>
	<img data-src="' . $default . '" src="' . $src . '" width="115" />
	<div>
	<input type="hidden" name="' . $name . '" id="' . $name . '" value="' . $value . '" />
	<button type="submit" class="upload_image_button button">Загрузить</button>
	<button type="submit" class="remove_image_button button">×</button>
	</div>
	</div>
	';
}

Несколько полей в одном блоке

Дублируем с уникальными названиями следующие строки

get_post_meta($post->ID, 'passport',true) );
get_post_meta($post->ID, 'certificate',true) );

if (isset($_POST['passport'])) { update_post_meta( $post_id, 'passport', $_POST['passport']); }
if (isset($_POST['certificate'])) { update_post_meta( $post_id, 'certificate', $_POST['certificate']); }

Про создание поля с выбором цвета читайте статью Поле Color Picker

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

  • Похожие записи
  • Комментарии
  • Вложения
Загрузчик изображений для таксономии

Загрузчик изображений для таксономии

Создаем загрузчик изображений для термина таксономии. Данный пост содержит чистый метод создания metabox для термина таксономии. Есть более универсальный метод добавления изображений терминам, но нижеописанный способ может стать дополнительным, когда Читать далее »

/
Metabox woocommerce

Metabox woocommerce

У плагина woocommerce есть набор дополнительных полей при редактировании товара. При необходимости можно в группы полей WC добавить свои произвольные metabox. Должно получится так: Создание и отображение metabox Первый экшн Читать далее »

/
Создание metabox’а

Создание metabox’а

Metabox — это произвольное поле реализованное в виде специальной формы (оболочка для PostMeta). Создание metabox’а самостоятельно — лучшая альтернатива плагину Advanced custom fields, особенно для релизации доп.полей в плагинах. Создание Читать далее »

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

3 комментария

  1. Тимур

     
    Также в данном решении стоит декодер тэгов — htmlspecialchars_decode. При выводе поля он будет выводить тэги в виде текста. По сути он не нужен, т.к. мы используем редактор wysiwyg с целью форматирования. Необходимо убрать в двух местах htmlspecialchars_decode и htmlspecialchars и их круглые скобки (вокруг $content и вокруг $_POST[‘answer‘])
    до задней части тела ниже спины эти «правки». Никакие параграфы редактор не ставит. Первый отлично работает, а вторая бредятина совсем не отлично. Уж простите за грубость, я весь день ищу нужное, но везде только вижу копии статей.
    У тебя единственного эта сноска написана, но и она особо не помогает. Например, если переключить вид редактора в текст, поставить теги, на странице работает формат, стоит переключить (а это однозначно необходимо и не может быть оспорено), как все теги перестраиваются в строчные отступы, но это лишь в редакторе самом видно становится, в странице всё в одну строку и ни одного параграфа нет, вообще.
    Нет, тема моя, поэтому там в принципе не может быть чего-то, что бы отменяло это форматирование. Говорю же, стандартный редактор работает, а добавляемый не хочет.
    Если будет какой-то совет дельный…я уже устал искать.
    Благодарю за возможные ответы….или молчание, тоже ответ.

    1. Alexandr

      По природе своей ленив, каюсь — грешен. Многие решения нахожу в сети, но применяю их лично и проблемные (для себя) моменты описываю здесь. Обязательно обновлю код (в т.ч. на сайте). В ближайшие пару недель буду сильно занят. Но после этого в планах более тщательно разобраться в этой теме. Еще раз спасибо за инфу и коммент!

  2. Тимур

    А вот я нашёл кое-что:
    $settings = array('wpautop'=>0,'textarea_name'=>'MyInputNAME'));
    Оказалось надо было просто действительно «отменить» это нелепое преобразование строчных пробелов и всё заработало ))
    Может кому-то пригодится ))
    Ну всё, теперь я счастлив как слон с шариками =)))) можно идти отдыхать )))

Продвинутые metabox Продвинутые metabox
Особенности excerpt
Рекомендации для васОсобенности excerptOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.