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

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

HIT

21.08.2016

2493

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 woocommerce

Metabox woocommerce

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

/
Metabox для таксономии

Metabox для таксономии

Учимся создавать метаполя для терминов таксономии, оформлять их в виде metabox’а, а также выводить их во frontend. Визуальный редактор для описания терминов Превратить текстовое поле в стандартный визуальный редактор WP Читать далее »

Создание 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
Галерея изображений товара в категории
Рекомендации для васГалерея изображений товара в категорииOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.