WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

Блок произвольных полей в админке WordPress своими руками

wordpress против

Чтобы не создавать произвольные поля полностью в ручную, используйте мой PHP класс для удобно создания метаполей записи.

Чтобы вывести подобный блок для элементов таксономий, смотрите описание события: (taxonomy)_edit_form_fields. Также смотрите ответ на вопрос: Метаполя для рубрик (таксономий) в WordPress

Вводная часть

Прежде чем начать рассказывать о том как создать произвольный блок данных в админ-панели на странице редактирования постов, который будет управлять указанными произвольными полями, следует отметить, что WordPress — платформа которая, пожалуй, как никакая другая поддается расширению с наименьшими усилиями. В частности, именно поэтому под WordPress написано так много плагинов — все очень просто, нужно лишь знать азы PHP и понимать принцип работы системы.

Каждый, кто достаточно близко знаком с WordPress неоднократно встречался с понятием «произвольные поля» и с их помощью решал некоторые нетривиальные задачи.

Произвольные поля в WordPress — очень удобный инструмент, когда нужно «прикрепить» к конкретному посту какие-либо дополнительные данные. Такими данными может быть что угодно, начиная от логических true/false (1/0), заканчивая объемными текстами, массивами и прочим. К примеру, мы можем создать новое произвольное поле Title и в его значение написать текст (альтернативный заголовок поста), затем в коде шаблона использовать следующий код, чтобы вывести этот текст:

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

Следует отметить, что функцию get_post_meta() можно использовать за пределами Цикла WordPress, т.е. где угодно в шаблоне. В данном примере мы используем её в <head> части документа, чтобы дать html странице заголовок отличный от заголовка самой статьи (иногда полезно для SEO).

Блок произвольных полей в WordPress

Другой пример: используя произвольные поля мы можем выполнять или не выполнять действия, в зависимости от того, какие данные у нас находится в значении произвольного поля. Например, размещая в произвольное поле логические цифры 1 или 0 мы можем выводить или не выводить какую-либо информацию для текущего поста.

Произвольные поля используются в WordPress сплошь и рядом, различными плагинами оценки постов (WP-PostRatings), SEO плагинами (Platinum SEO Pack), позволяющими указать Title, Description, Keywords поста, моим плагином для создания миниатюр (Kama Thumbnail) и многими другими плагинами. Образно говоря, каждая четвертая нестандартная задача решается посредством произвольных полей, поэтому если вы еще не знаете как их использовать, то ознакомьтесь с этим мануалом. А ниже мы поговорим о том, как создать отдельный блок с нужными нам произвольными полями и как сделать это без плагинов.

Мало кто знает, что если создать произвольное поле ключ которого (название) начинается на _ (нижнее подчеркивание), например _my_special_key, то такое поле не будет выводиться в выпадающем списке произвольных полей при редактировании постов и будет считаться "внутренним" произвольным полем, которое используется системой. Создать такое поле можно только запросом к БД, например, используя функции add_post_meta() или update_post_meta().

меню

Прежде чем начать создание

Забегая вперед, скажу что нижеследующие описание будет полезно, только тем кто хоть немного разбирается в HTML, т.е. если вы совсем не в зуб ногой в HTML и PHP, то читать все что ниже — пустая трата времени.

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

Кастомный блок произвольных полей

А данные такого блока в самих произвольных полях, после сохранения поста, будут записаны так:

Произвольные поля в WordPress

Что мы видим? — Ненужные для посторонних глаз ключи произвольных полей (о них я говорил выше), которые к тому же нужно еще и выбирать из выпадающего списка (а их там может быть совсем не 4, а куда больше...): description, robotmeta, select и title. Разумеется, создать мета блок произвольных полей — отличная идея.

меню

Создаем мета блок произвольных полей

Для создания метаблока нам понадобятся всего 2 хука: add_meta_boxes и save_post, функция add_meta_box() и некоторые знания html и php. Добавляем следующий код в файл темы functions.php:

#1. Создадим новый мета блок для постов

Назовем его "Дополнительные поля":

// подключаем функцию активации мета блока (my_extra_fields)
add_action('add_meta_boxes', 'my_extra_fields', 1);

function my_extra_fields() {
	add_meta_box( 'extra_fields', 'Дополнительные поля', 'extra_fields_box_func', 'post', 'normal', 'high'  );
}

#2. Заполним этот блок полями html формы

Делается это через, указанную в add_meta_box() функцию extra_fields_box_func(). Именно она отвечает за содержание мета блока:

<?php
// код блока
function extra_fields_box_func( $post ){
	?>
	<p><label><input type="text" name="extra[title]" value="<?php echo get_post_meta($post->ID, 'title', 1); ?>" style="width:50%" /> ? заголовок страницы (title)</label></p>

	<p>Описание статьи (description):
		<textarea type="text" name="extra[description]" style="width:100%;height:50px;"><?php echo get_post_meta($post->ID, 'description', 1); ?></textarea>
	</p>

	<p>Видимость поста: <?php $mark_v = get_post_meta($post->ID, 'robotmeta', 1); ?>
		 <label><input type="radio" name="extra[robotmeta]" value="" <?php checked( $mark_v, '' ); ?> /> index,follow</label>
		 <label><input type="radio" name="extra[robotmeta]" value="nofollow" <?php checked( $mark_v, 'nofollow' ); ?> /> nofollow</label>
		 <label><input type="radio" name="extra[robotmeta]" value="noindex" <?php checked( $mark_v, 'noindex' ); ?> /> noindex</label>
		 <label><input type="radio" name="extra[robotmeta]" value="noindex,nofollow" <?php checked( $mark_v, 'noindex,nofollow' ); ?> /> noindex,nofollow</label>
	</p>

	<p><select name="extra[select]">
			<?php $sel_v = get_post_meta($post->ID, 'select', 1); ?>
			<option value="0">----</option>
			<option value="1" <?php selected( $sel_v, '1' )?> >Выбери меня</option>
			<option value="2" <?php selected( $sel_v, '2' )?> >Нет, меня</option>
			<option value="3" <?php selected( $sel_v, '3' )?> >Лучше меня</option>
		</select> ? выбор за вами</p>

	<input type="hidden" name="extra_fields_nonce" value="<?php echo wp_create_nonce(__FILE__); ?>" />
	<?php
}

Все названия полей я оформил в массив extra[], чтобы потом проще было обработать эти данные.

Спрятанное поле name="extra_fields_nonce", нужно для проверки при сохранении данных.

меню

#3. Сохраняем данные

На этом этапе, мы уже создали блок произвольных полей, теперь нужно обработать данные полей при сохранении поста. Обработать, значит записать их в в базу данных или удалить от туда. Для этого используем хук save_post, который срабатывает в момент сохранения поста. В этот момент мы получим данные из массива extra[] и обработаем них:

// включаем обновление полей при сохранении
add_action( 'save_post', 'my_extra_fields_update', 0 );

## Сохраняем данные, при сохранении поста
function my_extra_fields_update( $post_id ){
	// базовая проверка
	if (
		   empty( $_POST['extra'] )
		|| ! wp_verify_nonce( $_POST['extra_fields_nonce'], __FILE__ )
		|| wp_is_post_autosave( $post_id )
		|| wp_is_post_revision( $post_id )
	)
		return false;

	// Все ОК! Теперь, нужно сохранить/удалить данные
	$_POST['extra'] = array_map( 'sanitize_text_field', $_POST['extra'] ); // чистим все данные от пробелов по краям
	foreach( $_POST['extra'] as $key => $value ){
		if( empty($value) ){
			delete_post_meta( $post_id, $key ); // удаляем поле если значение пустое
			continue;
		}

		update_post_meta( $post_id, $key, $value ); // add_post_meta() работает автоматически
	}

	return $post_id;
}

Вот и все, блок произвольных полей готов!

Теперь, изменяя html код, мы можем редактировать содержимое мета блока. Но не забываем, что названия полей имеют вид массива со значением ключа произвольно поля: name="extra[meta_key]".

меню

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

Если нужно создать блок для другого типа записей, допустим page (для страниц), то регистрируем еще один мета блок и описываем его html код в новой функции, которую так же нужно указать при регистрации блока (extra_fields_box_page_func). Функцию обработки полей при сохранении поста создавать уже не надо, главное указать названия полей в виде массивов extra[]:

function my_extra_fields() {
	add_meta_box( 'extra_fields', 'Дополнительные поля', 'extra_fields_box_func', 'post', 'normal', 'high'  );
	add_meta_box( 'extra_fields', 'Дополнительные поля', 'extra_fields_box_page_func', 'page', 'normal', 'high'  );
}

## html код блока для типа записей page
function extra_fields_box_page_func(){
   ?>
   <!-- Здесь поля html формы -->
   <?php
}
меню

Сложности с типом checkbox

Недостатком такого метода является то, что массив extra[], обязательно должен быть определен, пусть даже он передает пустое значение иначе поле не будет обработано при сохранении данных. В связи с этим, возникает проблема при использовании типа checkbox: <input type="checkbox", потому что checkbox передает данные только, если галочка выставлена и вообще ничего не передает, если галки нет. А нам нужно чтобы он передавал пустое значение, чтобы код удалял значение, если оно было сохранено до этого.

Чтобы обойти этот "недуг" я сделал так: перед полем чекбокса создаем hidden поле с name как у чекбокса и пустым значением. И получается, если галочка стоит, то значение hidden поля перебивается, если галки нет, то берется пустое значение hidden поля.

Т.е. checkbox нужно вызывать так:

<input type="hidden" name="extra[my_checkbox]" value="" />
<input type="checkbox" name="extra[my_checkbox]" value="1" />

Такой же трюк иногда может пригодится и для поля с типом radio.

Пример реального кода с типами checkbox:

<?php 
// подключаем функцию активации мета блока (my_extra_fields)
add_action('admin_init', 'my_extra_fields', 1);

function my_extra_fields() {
	add_meta_box( 'extra_fields', 'Дополнительные поля', 'extra_fields_box_func', 'post', 'normal', 'high'  );
}

// код блока
function extra_fields_box_func( $post ){
?>
	<p><label><input type="text" name="extra[title]" value="<?php echo get_post_meta($post->ID, 'title', 1); ?>" style="width:50%" /> ? заголовок страницы (title)</label></p>

	<p>Описание статьи (description):
		<textarea type="text" name="extra[description]" style="width:100%;height:50px;"><?php echo get_post_meta($post->ID, 'description', 1); ?></textarea>
	</p>

	<p>Видимость поста: <?php $mark_v = get_post_meta($post->ID, 'robotmeta', 1); ?>
		<label><input type="radio" name="extra[robotmeta]" value="" <?php checked( $mark_v, '' ); ?> /> index,follow</label>
		<label><input type="radio" name="extra[robotmeta]" value="nofollow" <?php checked( $mark_v, 'nofollow' ); ?> /> nofollow</label>
		<label><input type="radio" name="extra[robotmeta]" value="noindex" <?php checked( $mark_v, 'noindex' ); ?> /> noindex</label>
		<label><input type="radio" name="extra[robotmeta]" value="noindex,nofollow" <?php checked( $mark_v, 'noindex,nofollow' ); ?> /> noindex,nofollow</label>
	</p>

	<p><select name="extra[select]" />
			<?php $sel_v = get_post_meta($post->ID, 'select', 1); ?>
			<option value="0">----</option>
			<option value="1" <?php selected( $sel_v, '1' )?> >Выбери меня</option>
			<option value="2" <?php selected( $sel_v, '2' )?> >Нет, меня</option>
			<option value="3" <?php selected( $sel_v, '3' )?> >Лучше меня</option>
		</select> ? выбор за вами</p>

	<p>
		<input type="hidden" name="extra[white]" value="">
		<label><input type="checkbox" name="extra[white]" value="1" <?php checked( get_post_meta($post->ID, 'white', 1), 1 )?> /> белый</label>
		<input type="hidden" name="extra[red]" value="">
		<label><input type="checkbox" name="extra[red]" value="1"   <?php checked( get_post_meta($post->ID, 'red',   1), 1 )?> /> красный</label>
		<input type="hidden" name="extra[black]" value="">
		<label><input type="checkbox" name="extra[black]" value="1" <?php checked( get_post_meta($post->ID, 'black', 1), 1 )?> /> черный</label>
	</p>

	<input type="hidden" name="extra_fields_nonce" value="<?php echo wp_create_nonce(__FILE__); ?>" />
<?php
}

// включаем обновление полей при сохранении
add_action('save_post', 'my_extra_fields_update', 0);

/* Сохраняем данные, при сохранении поста */
function my_extra_fields_update( $post_id ){
	// базовая проверка
	if (
		   empty( $_POST['extra'] )
		|| ! wp_verify_nonce( $_POST['extra_fields_nonce'], __FILE__ )
		|| wp_is_post_autosave( $post_id )
		|| wp_is_post_revision( $post_id )
	)
		return false;

	// Все ОК! Теперь, нужно сохранить/удалить данные
	$_POST['extra'] = array_map( 'sanitize_text_field', $_POST['extra'] );
	foreach( $_POST['extra'] as $key => $value ){
		if( empty($value) ){
			delete_post_meta( $post_id, $key ); // удаляем поле если значение пустое
			continue;
		}

		update_post_meta( $post_id, $key, $value ); // add_post_meta() работает автоматически
	}

	return $post_id;
}
меню

Еще один пример создания метабокса (ООП)

Этот пример показывает как создать одно поле, в котором будет храниться массив данных. Массив можно расширять или уменьшать через нажатие на + или удалить (работает на скрипте).

Это пример создание поля "повторитель", как у плагина ACF (поле repeater в платной версии).

В результате получим такой метабокс:

<?php

new My_Best_Metaboxes;

class My_Best_Metaboxes {

	public $post_type = 'post';

	static $meta_key = 'company_address';

	public function __construct() {
		add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
		add_action( 'save_post_' . $this->post_type, array( $this, 'save_metabox' ) );
		add_action( 'admin_print_footer_scripts', array( $this, 'show_assets' ), 10, 999 );
	}

	## Добавляет матабоксы
	public function add_metabox() {
		add_meta_box( 'box_info_company', 'Информация о компании', array( $this, 'render_metabox' ), $this->post_type, 'advanced', 'high' );
	}

	## Отображает метабокс на странице редактирования поста
	public function render_metabox( $post ) {

		?>
		<table class="form-table company-info">

			<tr>
				<th>
					Адреса компании <span class="dashicons dashicons-plus-alt add-company-address"></span>
				</th>
				<td class="company-address-list">
					<?php
					$input = '
					<span class="item-address">
						<input type="text" name="'. self::$meta_key .'[]" value="%s">
						<span class="dashicons dashicons-trash remove-company-address"></span>
					</span>
					';

					$addresses = get_post_meta( $post->ID, self::$meta_key, true );

					if ( is_array( $addresses ) ) {
						foreach ( $addresses as $addr ) {
							printf( $input, esc_attr( $addr ) );
						}
					} else {
						printf( $input, '' );
					}
					?>
				</td>
			</tr>

		</table>

		<?php
	}

	## Очищает и сохраняет значения полей
	public function save_metabox( $post_id ) {

		// Check if it's not an autosave.
		if ( wp_is_post_autosave( $post_id ) )
			return;

		if ( isset( $_POST[self::$meta_key] ) && is_array( $_POST[self::$meta_key] ) ) {
			$addresses = $_POST[self::$meta_key];

			$addresses = array_map( 'sanitize_text_field', $addresses ); // очистка

			$addresses = array_filter( $addresses ); // уберем пустые адреса

			if ( $addresses ) 
				update_post_meta( $post_id, self::$meta_key, $addresses );
			else 
				delete_post_meta( $post_id, self::$meta_key );

		}
	}

	## Подключает скрипты и стили
	public function show_assets() {
		if ( is_admin() && get_current_screen()->id == $this->post_type ) {
			$this->show_styles();
			$this->show_scripts();
		}
	}

	## Выводит на экран стили
	public function show_styles() {
		?>
		<style>
			.add-company-address {
				color: #00a0d2;
				cursor: pointer;
			}
			.company-address-list .item-address {
				display: flex;
				align-items: center;
			}
			.company-address-list .item-address input {
				width: 100%;
				max-width: 400px;
			}
			.remove-company-address {
				color: brown;
				cursor: pointer;
			}
		</style>
		<?php
	}

	## Выводит на экран JS
	public function show_scripts() {
		?>
		<script>
			jQuery(document).ready(function ($) {

				var $companyInfo = $('.company-info');

				// Добавляет бокс с вводом адреса фирмы
				$('.add-company-address', $companyInfo).click(function () {
					var $list = $('.company-address-list');
						$item = $list.find('.item-address').first().clone();

					$item.find('input').val(''); // чистим знанчение

					$list.append( $item );
				});

				// Удаляет бокс с вводом адреса фирмы
				$companyInfo.on('click', '.remove-company-address', function () {
					if ($('.item-address').length > 1) {
						$(this).closest('.item-address').remove();
					}
					else {
						$(this).closest('.item-address').find('input').val('');
					}
				});

			});
		</script>
		<?php
	}

}
меню

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

В статье я говорил о плагинах, которые создают мета блоки заменяющие произвольные поля, но ни разу не упомянул ни один. Исправляюсь:

  • Advanced Custom Fields (ACF) — пожалуй, самый популярный и гибкий плагин для создания произвольных полей. С хорошей документацией.

  • Custom Field Suite — похож на ACF, только менее навороченный.

  • Carbon Fields — похож на ACF только без визуальной настройки, все делается в коде. Хорошо подойдет для разработчиков. Бесплатный.

  • CMB2 — CMB2 инструмент для разработчиков для создания: метабоксов, метаполей. Позволяет легко управлять записями, элементами таксономий, пользователями, комментариями или создавать произвольные страницы настроек.

  • Custom Field Template — настоящий комбайн. С ним можно создать любую форму, для любых типов постов, указать формы для отдельных постов и рубрик. Думаю в большинстве случаев,  можно обойтись без такого комбайна.

  • kc-settings - ураган а не плагин, хоть и не сторонник плагинов, но рекомендую.
меню

Заключение

Простота в настройке блока произвольных полей при создании его таким способом теряется! Я ни в коем случае не хочу сказать, что создавать блоки таким способом лучше чем использовать плагины. Однако, такой подход более гибок, потому что мы можем создать абсолютно любые поля и расположить/стилизовать их как нам вздумается.

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

Это скорее обучающая статья и для многих плагины реализующие эту задачу будут лучшим решением.

213 комментов
Полезные 22 Вопросы 2 Все
  • Александр-HIMиk cайт: www.alexzdesign.ru

    Что касается произвольных полей, то меня устраивает плагин Magic-fields. На базе него спокойно создаются каталоги товаров smile

    Ответить8 лет назад #
  • Игорь cайт: top-fotograf.ru

    Пару месяцев назад искал подобное решение, но в рунете не нашел. Зато у буржуев было то что я искал. Но там используется несколько другой метод чем у вас - поля задаются через массив:

    <?php 
    
    //-------------------------------------BETTER--META--BOX-------------------------//
    
    $prefix = '1_';
    
    $meta_box = array(
    	'id' => 'my-meta-box',
    	'title' => 'Информация об организации',
    	'page' => 'post',
    	'context' => 'normal',
    	'priority' => 'high',
    	'fields' => array(
    		array(
    			'name' => 'Адрес:',
    			'id' => $prefix . 'adr',
    			'type' => 'text'
    		),
    		array(
    			'name' => 'Телефон:',
    			'id' => $prefix . 'tel',
    			'type' => 'text'
    		),
    		array(
    			'name' => 'E-mail:',
    			'id' => $prefix . 'mail',
    			'type' => 'text'
    		),
    		array(
    			'name' => 'Сайт:',
    			'desc' => 'С http://',
    			'id' => $prefix . 'url',
    			'type' => 'text'
    		)
    
    	)
    );
    
    add_action('admin_menu', 'mytheme_add_box');
    
    // Add meta box
    function mytheme_add_box() {
    	global $meta_box;
    
    	add_meta_box($meta_box['id'], $meta_box['title'], 'mytheme_show_box', $meta_box['page'], $meta_box['context'], $meta_box['priority']);
    }
    
    // Callback function to show fields in meta box
    function mytheme_show_box() {
    	global $meta_box, $post;
    
    	// Use nonce for verification
    	echo '<input type="hidden" name="mytheme_meta_box_nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';
    
    	echo '<table class="form-table">';
    
    	foreach ($meta_box['fields'] as $field) {
    		// get current post meta data
    		$meta = get_post_meta($post->ID, $field['id'], true);
    
    		echo '<tr>',
    				'<th style="width:20%"><label for="', $field['id'], '">', $field['name'], '</label></th>',
    				'<td>';
    		switch ($field['type']) {
    			case 'text':
    				echo '<input type="text" name="', $field['id'], '" id="', $field['id'], '" value="', $meta ? $meta : $field['std'], '" size="30" style="width:97%" />',
    					'<br />', $field['desc'];
    				break;
    			case 'textarea':
    				echo '<textarea name="', $field['id'], '" id="', $field['id'], '" cols="60" rows="4" style="width:97%">', $meta ? $meta : $field['std'], '</textarea>',
    					'<br />', $field['desc'];
    				break;
    			case 'select':
    				echo '<select name="', $field['id'], '" id="', $field['id'], '">';
    				foreach ($field['options'] as $option) {
    					echo '<option', $meta == $option ? ' selected="selected"' : '', '>', $option, '</option>';
    				}
    				echo '</select>';
    				break;
    			case 'radio':
    				foreach ($field['options'] as $option) {
    					echo '<input type="radio" name="', $field['id'], '" value="', $option['value'], '"', $meta == $option['value'] ? ' checked="checked"' : '', ' />', $option['name'];
    				}
    				break;
    			case 'checkbox':
    				echo '<input type="checkbox" name="', $field['id'], '" id="', $field['id'], '"', $meta ? ' checked="checked"' : '', ' />';
    				break;
    		}
    		echo    '<td>',
    			'</tr>';
    	}
    
    	echo '</table>';
    }
    
    add_action('save_post', 'mytheme_save_data');
    
    // Save data from meta box
    function mytheme_save_data($post_id) {
    	global $meta_box;
    
    	// verify nonce
    	if (!wp_verify_nonce($_POST['mytheme_meta_box_nonce'], basename(__FILE__))) {
    		return $post_id;
    	}
    
    	// check autosave
    	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
    		return $post_id;
    	}
    
    	// check permissions
    	if ('page' == $_POST['post_type']) {
    		if (!current_user_can('edit_page', $post_id)) {
    			return $post_id;
    		}
    	} elseif (!current_user_can('edit_post', $post_id)) {
    		return $post_id;
    	}
    
    	foreach ($meta_box['fields'] as $field) {
    		$old = get_post_meta($post_id, $field['id'], true);
    		$new = $_POST[$field['id']];
    
    		if ($new && $new != $old) {
    			update_post_meta($post_id, $field['id'], $new);
    		} elseif ('' == $new && $old) {
    			delete_post_meta($post_id, $field['id'], $old);
    		}
    	}
    }
    
    ?>
    Ответить8 лет назад #
    • Kama7534

      Я встречал подобное на англ. Интересное решение, хорошая альтернатива, потому что в чем-то более универсальное, чем пример из этой статьи.

      Из отличий вижу:

      1. в моем примере блок создается полностью вручную и поэтому его можно по-разному стилизовать. Если надо использовать javascript обработку и т.п. Полный кастом иногда удобнее.

      2. в моем примере как-то удобнее создавать несколько блоков для разных типов записей. В этом примере для этого придется дублировать весь код для каждого блока и переписывать переменную $meta_box.

      П.С. спасибо за хороший пример!

      Ответить8 лет назад #
  • БГ cайт: dedavova.ru

    Спасибо за статью, на вашем сайте всегда можно найти оригинальные, нужные и понятные решения.

    А можно ли добавить блок произвольных полей к записям только определенной рубрики?

    Ответить7.10 лет назад #
    • Kama7534

      Пожалуйста!

      Так сделать можно, но разумеется не для новой статьи, потому что у новой статьи еще нет рубрики... Вы учли этот момент? Раз для новой такое не делается, то если логика вообще такое делать?

      Если все-таки нужно, то покопайте в сторону проверки переменной $post на странице редактирования. Через нее можно будет получить категорию записи и соответственно условием потом проверить: если категория "наша", то выводим блок (активируем фильтр).

      Ответить7.10 лет назад #
  • БГ cайт: dedavova.ru

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

    Ответить7.9 лет назад #
  • wlad2 cайт: wlad2.ru

    как ты обворачиваешь <var>$post</var>

    Ответить7.9 лет назад #
  • Константин cайт: konsta1.bget.ru

    Подскажите, как в блоке произвольных полей создать еще одно - кнопка загрузки изображений

    Ответить7.9 лет назад #
    • Kama7534

      К сожалению я не знаю ответ на этот вопрос.

      Ответить7.9 лет назад #
    • Александр cайт: milordk.ru

      либо плагины, либо пишите код (jquery в помощь)

      Ответить7.8 лет назад #
    • kalbac cайт: leomaks.ru

      Кама, я надеюсь ты не против что я у тебя в комментариях по умничаюmosking
      Константин, я тут поковырялся и нашел решение по вашему вопросу. Ниже представлен немного модифицированный код господина Камы

      // подключаем функцию активации мета блока (my_extra_fields)
      add_action('admin_init', 'my_extra_fields', 1);
      
      function my_extra_fields() {
      	add_meta_box( 'extra_fields', 'Дополнительные поля', 'extra_fields_box_func', 'post', 'normal', 'high'  );
      }
      
      // код блока
      function extra_fields_box_func( $post ){
      ?>
      	<p><label><input type="text" name="extra[title]" value="<?php echo get_post_meta($post->ID, 'title', 1); ?>" style="width:50%" /> < заголовок страницы (title)</label></p>
      
      	<p>Описание статьи (description):
      		<textarea type="text" name="extra[description]" style="width:100%;height:50px;"><?php echo get_post_meta($post->ID, 'description', 1); ?></textarea>
      	</p>
      
      	<p>Видимость поста: <?php $mark_v = get_post_meta($post->ID, 'robotmeta', 1); ?>
      		 <label><input type="radio" name="extra[robotmeta]" value="" <?php checked( $mark_v, '' ); ?> /> index,follow</label>
      		 <label><input type="radio" name="extra[robotmeta]" value="nofollow" <?php checked( $mark_v, 'nofollow' ); ?> /> nofollow</label>
      		 <label><input type="radio" name="extra[robotmeta]" value="noindex" <?php checked( $mark_v, 'noindex' ); ?> /> noindex</label>
      		 <label><input type="radio" name="extra[robotmeta]" value="noindex,nofollow" <?php checked( $mark_v, 'noindex,nofollow' ); ?> /> noindex,nofollow</label>
      	</p>
      
      	<p><select name="extra[select]" />
      			<?php $sel_v = get_post_meta($post->ID, 'select', 1); ?>
      			<option value="0">----</option>
      			<option value="1" <?php selected( $sel_v, '1' )?> >Выбери меня</option>
      			<option value="2" <?php selected( $sel_v, '2' )?> >Нет, меня</option>
      			<option value="3" <?php selected( $sel_v, '3' )?> >Лучше меня</option>
      		</select> < выбор за вами</p>
      
      // Загрузка изображения для поста
      	<p>
      		<label for="upload_image">URL картинки: </label><br/>
      		<input id="upload_image" type="text" size="90" name="extra[image]" value="<?php get_post_meta($post->ID, 'image', true); ?>" />
      		<input class="upload_image_button" type="button" value="Загрузить" /><br/>
      
      	</p>  
      
      	<input type="hidden" name="extra_fields_nonce" value="<?php echo wp_create_nonce(__FILE__); ?>" />
      <?php
      }
      
      // включаем обновление полей при сохранении
      add_action('save_post', 'my_extra_fields_update', 0);
      
      /* Сохраняем данные, при сохранении поста */
      function my_extra_fields_update( $post_id ){
      	if ( !wp_verify_nonce($_POST['extra_fields_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; 
      
      	// Все ОК! Теперь, нужно сохранить/удалить данные
      	$_POST['extra'] = array_map('trim', $_POST['extra']);
      	foreach( $_POST['extra'] as $key=>$value ){
      		if( empty($value) )
      			continue delete_post_meta($post_id, $key); // удаляем поле если значение пустое
      
      		update_post_meta($post_id, $key, $value); // add_post_meta() работает автоматически
      	}
      	return $post_id;
      }
      
      //Создаём функйию подключения ява скриптов к админке
      
      function upload_scripts() {
      	wp_enqueue_script('media-upload');
      	wp_enqueue_script('thickbox');
      	wp_register_script('my-upload', get_bloginfo('template_directory').'/js/custom_uploader.js', array('jquery','media-upload','thickbox'));
      	wp_enqueue_script('my-upload');
      }
      
      //Создаём функйию подключения стилей thickbox
      
      function upload_styles() {
      	wp_enqueue_style('thickbox');
      }
      add_action('admin_print_scripts', 'upload_scripts'); //Регистрируем скрипты в админке
      add_action('admin_print_styles', 'upload_styles'); //Регестрируем стили в админке

      И собственно сам java скрипт который нужно пометить в папку вашей темы с названием js (если такой папки нету создайте её).
      P.S. файл с java скриптом в нашем случае необходимо назвать custom_uploader.js
      Вот код:

      jQuery(document).ready(function() {
      	var fileInput = '';
      
      	jQuery('.upload_image_button').click(function() {
      		fileInput = jQuery(this).prev('input');
      		formfield = jQuery('#upload_image').attr('name');
      		post_id = jQuery('#post_ID').val();
      		tb_show('', 'media-upload.php?post_id='+post_id+'&type=image&TB_iframe=true');
      		return false;
      	});
      
      	window.original_send_to_editor = window.send_to_editor;
      	window.send_to_editor = function(html){
      
      		if (fileInput) {
      			fileurl = jQuery('img',html).attr('src');
      
      			fileInput.val(fileurl);
      
      			tb_remove();
      
      		} else {
      			window.original_send_to_editor(html);
      		}
      	};
      
      });
      1
      Ответить7.8 лет назад #
  • Александр cайт: milordk.ru

    А зачем использовать плагины?... каждый плагин - это море запросов в БД.. лучше приведенные функции вставлять сразу в тему)

    Ответить7.8 лет назад #
  • Егор

    Очень нужна ваша помощь.
    Пользуюсь плагином WP-PostRatings, нужно чтобы популярные посты выводились с произвольными полями. Возможно реализовать как-то ?

    Ответить7.8 лет назад #
  • Дима

    Метаблок - это хорошо ok, но желателен пример который позволяет дополнять таблицы wp_posts. Можешь показать такой пример?

    Ответить7.8 лет назад #
    • Kama7534

      В смысле добавлять колонки в таблицу с выводом постов в админке? Я как нужно понял?

      Ответить7.8 лет назад #
Здравствуйте, !     Войти . Зарегистрироваться