WordPress как на ладони
Наставник Трепачёв Д.П., phphtml.net wordpress jino

add_meta_box() WP 2.5.0

Добавляет дополнительные блоки (meta box) на страницы редактирования/создания постов, постоянных страниц или произвольных типов записей в админ-панели.

Вызывается во время события (хука) add_meta_boxes. Для версий ниже 3.0 на хук admin_init.

Используется в: wp_add_dashboard_widget().

Хуков нет.

Возвращает

Ничего не возвращает.

Использование

add_meta_box( $id, $title, $callback, $screen, $context, $priority, $callback_args );
$id(строка) (обязательный)
id атрибут HTML тега, контейнера блока.
По умолчанию: нет
$title(строка) (обязательный)
Заголовок/название блока. Виден пользователям.
По умолчанию: нет
$callback(строка) (обязательный)
Функция, которая выводит на экран HTML содержание блока. Должна выводить результат на экран.
По умолчанию: нет
$screen(строка/массив/WP_Screen)

Название экрана для которого добавляется блок. Смотрите get_current_screen(). Например может быть:

  • Для типов записей: post, page, link, attachment или custom_post_type
  • Или для других страниц админки: link, comment.
  • Можно указать несколько типов в массиве: array('post', 'page'). C версии 4.4.

По умолчанию: null (текущий экран)

$context(строка)
Место где должен показываться блок: normal, advanced или side.
По умолчанию: 'advanced'
$priority(строка)
Приоритет блока для показа выше или ниже остальных блоков: high или low.
По умолчанию: 'default'
$callback_args(массив)
Аргументы, которые нужно передать в callback функцию указанную в параметре $callback. callback функция получит данные поста (объект $post) и аргументы переданные в этом параметре.
По умолчанию: null

Примеры

#1 Метабокс для постов и страниц

Пример добавления произвольного блока на страницы редактирования/создания постов и постоянных страниц:

/* Добавляем блоки в основную колонку на страницах постов и пост. страниц */
function myplugin_add_custom_box() {
	$screens = array( 'post', 'page' );
	foreach ( $screens as $screen )
		add_meta_box( 'myplugin_sectionid', 'Название мета блока', 'myplugin_meta_box_callback', $screen );
}
add_action('add_meta_boxes', 'myplugin_add_custom_box');

/* HTML код блока */
function myplugin_meta_box_callback() {
	// Используем nonce для верификации
	wp_nonce_field( plugin_basename(__FILE__), 'myplugin_noncename' );

	// Поля формы для введения данных
	echo '<label for="myplugin_new_field">' . __("Description for this field", 'myplugin_textdomain' ) . '</label> ';
	echo '<input type="text" id= "myplugin_new_field" name="myplugin_new_field" value="whatever" size="25" />';
}

/* Сохраняем данные, когда пост сохраняется */
function myplugin_save_postdata( $post_id ) {
	// проверяем nonce нашей страницы, потому что save_post может быть вызван с другого места.
	if ( ! wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename(__FILE__) ) )
		return $post_id;

	// проверяем, если это автосохранение ничего не делаем с данными нашей формы.
	if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
		return $post_id;

	// проверяем разрешено ли пользователю указывать эти данные
	if ( 'page' == $_POST['post_type'] && ! current_user_can( 'edit_page', $post_id ) ) {
		  return $post_id;
	} elseif( ! current_user_can( 'edit_post', $post_id ) ) {
		return $post_id;
	}

	// Убедимся что поле установлено.
	if ( ! isset( $_POST['myplugin_new_field'] ) )
		return;

	// Все ОК. Теперь, нужно найти и сохранить данные
	// Очищаем значение поля input.
	$my_data = sanitize_text_field( $_POST['myplugin_new_field'] );

	// Обновляем данные в базе данных.
	update_post_meta( $post_id, '_my_meta_value_key', $my_data );
}
add_action( 'save_post', 'myplugin_save_postdata' );

#2 Новая вкладка аккордеона (метабокс в меню аккордеона)

Этот пример показывает, как добавить дополнительный элемент аккордеона на странице настроек меню WordPress.

<?php
add_action( 'admin_head-nav-menus.php', 'register_my_meta_box_accordion_nav_menus' );
function register_my_meta_box_accordion_nav_menus() {
	add_meta_box( 'my-custom-meta-box', 'Мой метабокс', 'render_my_meta_box_accordion_nav_menus', 'nav-menus', 'side' );
}

function render_my_meta_box_accordion_nav_menus() {
	?>
	<div class="my-custom-meta-box" id="my-custom-meta-box">
		Контент метабокса
	</div>
	<?php
}

Получим:

#2.1 Вкладка аккордеона с контентом (рабочий код)

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

<?php
/**
 * Регистрация и добавление вкладки в аккардионе для созданию меню
 *
 * @link https://gist.github.com/nikolov-tmw/8698598
 */
add_action( 'admin_head-nav-menus.php', 'register_menu_files_metabox' );
function register_menu_files_metabox() {
	add_meta_box( 'menu-media-files-metabox', 'Файлы', 'render_menu_files_metabox', 'nav-menus', 'side', 'default' );
}

/**
 * Вывод на экран метабокса "Файлы"
 *
 * @param string $object Не используется.
 * @param array  $args   Параметры и аргументы.
 */
function render_menu_files_metabox( $object, $args ) {
	global $nav_menu_selected_id;
	$files_ext = [ 'xlsx', 'pdf', 'zip' ];

	$my_items = get_posts( [
		'numberposts'    => - 1,
		'post_type'      => 'attachment',
		'post_mime_type' => get_mime_files_extension( $files_ext ),
	] );

	$walker       = new Walker_Nav_Menu_Checklist();
	$removed_args = [
		'action',
		'customlink-tab',
		'edit-menu-item',
		'menu-item',
		'page-tab',
		'_wpnonce',
	]; ?>
	<div id="tab-files-div">
	<div id="tabs-panel-list-files" class="tabs-panel tabs-panel-active">
		<p>Отображаются только файлы с расширением <b><?php echo implode( ', ', $files_ext ); ?></b>.</p>

		<ul id="tab-files-checklist-pop" class="categorychecklist form-no-clear">
			<?php echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $my_items ), 0, (object) [ 'walker' => $walker ] ); ?>
		</ul>

		<p class="button-controls">
			<span class="list-controls">
				<a href="<?php
				echo esc_url( add_query_arg(
					[
						'list-files' => 'all',
						'selectall'  => 1,
					],
					remove_query_arg( $removed_args )
				) );
				?>#menu-media-files-metabox" class="select-all"><?php _e( 'Select All' ); ?></a>
			</span>

			<span class="add-to-menu">
				<input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?>
					   class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to Menu' ); ?>"
					   name="add-tab-files-menu-item" id="submit-tab-files-div"/>
				<span class="spinner"></span>
			</span>
		</p>
	</div>
	<?php
}

/**
 * Возвращает mime типы расширений файлов
 *
 * @param array $files_ext расширения файлов
 *
 * @return array
 */
function get_mime_files_extension( $files_ext ) {

	// Получает список разрешенных mime типов.
	$mimes = get_allowed_mime_types();

	// Поиск mime типа в массиве расширений.
	$need_mimes = [];
	foreach ( $files_ext as $file_ext ) {
		foreach ( $mimes as $type => $mime ) {
			if ( false !== strpos( $type, $file_ext ) ) {
				$need_mimes[] = $mime;
			}
		}
	}

	return $need_mimes;
}

/**
 * Заменяет ссылку на страницу медиафайла ссылкой на сам медиафайл
 *
 * @param string $link    ссылка на страницу медиафайла
 * @param string $post_id ID медиафайла
 *
 * @return string
 */
add_filter( 'attachment_link', 'change_attachment_link', 1000, 2 );
function change_attachment_link( $link, $post_id ) {
	return wp_get_attachment_url( $post_id );
}

Получим:

Новая вкладка аккордеона с добавление медиафайла

Основа взята из файла custom-menu-panel.php, найденного на просторах github и реализующий добавления кастомных объектов для списка.

Класс PHP

Этот пример показывает как добавить дополнительный блок в контексте PHP класса:

/**
 * Вызываем класс на странице редактирования поста.
 */
function call_someClass() {
	new someClass();
}

if ( is_admin() ) {
	add_action( 'load-post.php', 'call_someClass' );
	add_action( 'load-post-new.php', 'call_someClass' );
}

/** 
 * Код класса.
 */
class someClass {

	/**
	 * Устанавливаем хуки в момент инициализации класса.
	 */
	public function __construct() {
		add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
		add_action( 'save_post', array( $this, 'save' ) );
	}

	/**
	 * Добавляем дополнительный блок.
	 */
	public function add_meta_box( $post_type ) {
			// Устанавливаем типы постов к которым будет добавлен блок
			$post_types = array('post', 'page');
			if ( in_array( $post_type, $post_types )) {
		add_meta_box(
			'some_meta_box_name'
			,__( 'Some Meta Box Headline', 'myplugin_textdomain' )
			,array( $this, 'render_meta_box_content' )
			,$post_type
			,'advanced'
			,'high'
		);
			}
	}

	/**
	 * Сохраняем данные при сохранении поста.
	 *
	 * @param int $post_id ID поста, который сохраняется.
	 */
	public function save( $post_id ) {

		/*
		 * Нам нужно сделать проверку, чтобы убедится что запрос пришел с нашей страницы, 
				 * потому что save_post может быть вызван еще где угодно.
		 */

		// Проверяем установлен ли nonce.
		if ( ! isset( $_POST['myplugin_inner_custom_box_nonce'] ) )
			return $post_id;

		$nonce = $_POST['myplugin_inner_custom_box_nonce'];

		// Проверяем корректен ли nonce.
		if ( ! wp_verify_nonce( $nonce, 'myplugin_inner_custom_box' ) )
			return $post_id;

		// Если это автосохранение ничего не делаем.
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
			return $post_id;

		// Проверяем права пользователя.
		if ( 'page' == $_POST['post_type'] ) {

			if ( ! current_user_can( 'edit_page', $post_id ) )
				return $post_id;

		} else {

			if ( ! current_user_can( 'edit_post', $post_id ) )
				return $post_id;
		}

		/* OK, все чисто, можно сохранять данные. */

		// Очищаем поле input.
		$mydata = sanitize_text_field( $_POST['myplugin_new_field'] );

		// Обновляем данные.
		update_post_meta( $post_id, '_my_meta_value_key', $mydata );
	}

	/**
	 * Код дополнительного блока.
	 *
	 * @param WP_Post $post Объект поста.
	 */
	public function render_meta_box_content( $post ) {

		// Добавляем nonce поле, которое будем проверять при сохранении.
		wp_nonce_field( 'myplugin_inner_custom_box', 'myplugin_inner_custom_box_nonce' );

		// Получаем существующие данные из базы данных.
		$value = get_post_meta( $post->ID, '_my_meta_value_key', true );

		// Выводим поля формы, используя полученные данные.
		echo '<label for="myplugin_new_field">';
		_e( 'Description for this field', 'myplugin_textdomain' );
		echo '</label> ';
		echo '<input type="text" id="myplugin_new_field" name="myplugin_new_field"';
				echo ' value="' . esc_attr( $value ) . '" size="25" />';
	}
}
Использование параметра $callback_args

массив аргументов $callback_args будет передан callback функции вторым параметров. В первом параметре передаются другие данные записи (массив $_POST).

// Эта функция добавляет Блок который передает доп. параметры callback функции my_metabox_callback()
function add_my_meta_box() {
	 $var1 = "this";
	 $var2 = "that";
	 add_meta_box('metabox_id', 'Metabox Title', 'my_metabox_callback', 
		 'page', 'normal', 'low', array('foo'=>$var1,'bar'=>$var2));
}

// $post - это объект содержащий данные глобального массива $_POST
// $metabox - это массив с агрументами: metabox_id, title, callback 
// и новыми переданными аргументами в параметре $callback_args 
function my_metabox_callback ($post, $metabox) {
	 echo 'Last Modified: ' . $post->post_modified;        // время последнего изменения поста
	 echo $metabox['args']['foo'];                         // раз
	 echo $metabox['args']['bar'];                         // два
	 echo get_post_meta($post->ID,'my_custom_field',true); // значение произвольно поля
}

Код add meta box: wp-admin/includes/template.php WP 4.8.1

<?php
function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) {
	global $wp_meta_boxes;

	if ( empty( $screen ) ) {
		$screen = get_current_screen();
	} elseif ( is_string( $screen ) ) {
		$screen = convert_to_screen( $screen );
	} elseif ( is_array( $screen ) ) {
		foreach ( $screen as $single_screen ) {
			add_meta_box( $id, $title, $callback, $single_screen, $context, $priority, $callback_args );
		}
	}

	if ( ! isset( $screen->id ) ) {
		return;
	}

	$page = $screen->id;

	if ( !isset($wp_meta_boxes) )
		$wp_meta_boxes = array();
	if ( !isset($wp_meta_boxes[$page]) )
		$wp_meta_boxes[$page] = array();
	if ( !isset($wp_meta_boxes[$page][$context]) )
		$wp_meta_boxes[$page][$context] = array();

	foreach ( array_keys($wp_meta_boxes[$page]) as $a_context ) {
		foreach ( array('high', 'core', 'default', 'low') as $a_priority ) {
			if ( !isset($wp_meta_boxes[$page][$a_context][$a_priority][$id]) )
				continue;

			// If a core box was previously added or removed by a plugin, don't add.
			if ( 'core' == $priority ) {
				// If core box previously deleted, don't add
				if ( false === $wp_meta_boxes[$page][$a_context][$a_priority][$id] )
					return;

				/*
				 * If box was added with default priority, give it core priority to
				 * maintain sort order.
				 */
				if ( 'default' == $a_priority ) {
					$wp_meta_boxes[$page][$a_context]['core'][$id] = $wp_meta_boxes[$page][$a_context]['default'][$id];
					unset($wp_meta_boxes[$page][$a_context]['default'][$id]);
				}
				return;
			}
			// If no priority given and id already present, use existing priority.
			if ( empty($priority) ) {
				$priority = $a_priority;
			/*
			 * Else, if we're adding to the sorted priority, we don't know the title
			 * or callback. Grab them from the previously added context/priority.
			 */
			} elseif ( 'sorted' == $priority ) {
				$title = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['title'];
				$callback = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['callback'];
				$callback_args = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['args'];
			}
			// An id can be in only one priority and one context.
			if ( $priority != $a_priority || $context != $a_context )
				unset($wp_meta_boxes[$page][$a_context][$a_priority][$id]);
		}
	}

	if ( empty($priority) )
		$priority = 'low';

	if ( !isset($wp_meta_boxes[$page][$context][$priority]) )
		$wp_meta_boxes[$page][$context][$priority] = array();

	$wp_meta_boxes[$page][$context][$priority][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $callback_args);
}

Cвязанные функции

Из метки: metabox (метабоксы)

Еще из раздела: Админ-панель

add_meta_box 39 комментариев
Полезные 2 Вопросы 1 Все
  • Виктор
    @

    Такой вот код:

    function my_template_box() {
    	add_meta_box( 'my_box_id', 'Заголовок', 'my_template_box_callback', 'page', 'side', 'high' );
    }
    add_action('add_meta_boxes', 'my_template_box_callback');

    По началу было все отлично, метабокс выводился вверху справа в сайдбаре, но после он стал выводится внизу под контентом редактора, не смотря на то что прописан параметр 'side', в чём может быть причина данного явления?

    • Kama4477

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

      1
  • campusboy1749 cайт: wp-plus.ru

    А можно пример, как добавлять боксы для рубрик или тегов? Сейчас я использую хуки category_add_form_fields и category_edit_form_fields, чтобы туда свои поля добавить, но может это не по фен-шую.

    • Kama4477

      Нету там боксов... Так и делается через эти хуки, насколько я знаю. unknw

  • Елена
    @

    Как пофиксить, чтобы значение этого поля "myplugin_new_field" сохранялось?

  • Мне нужен дополнительный виджет в консоли типа "Заметки". Создать сам виджет, разместить в нём textarea и кнопку "Сохранить" - это не проблема. А как, собственно, сохранить сам написанный в поле текст? Например так, как он сохраняется в произвольных полях у постов (записей).

    Ответитьмесяц назад #
    • campusboy1749 cайт: wp-plus.ru

      Есть специальная функция wp_add_dashboard_widget, там есть пример виджета с настройками, может он пригодится.

      Ответитьмесяц назад #
      • Там специальная страница настроек виджета. А мне нужно просто сохранить текст, введённый в поле textarea. Прямо тут, на месте. Например, написал себе на память что нужно сделать, исправить и т.д., нажал кнопку сохранить, и оно висит себе. Сделал, стёр, написал другое, сохранил - висит другое.

        Ответитьмесяц назад #
        • campusboy1749 cайт: wp-plus.ru

          Попробуйте в репозитории поискать плагин по слову note и поглядеть, как у них это реализовано. К примеру, wp-dashboard-notes

          2
          Ответитьмесяц назад #
          • Спасибочки, попробую.

            Ответитьмесяц назад #
          • Нашла плагин, который делает именно то, что мне нужно - AdminPad. Он крошечный, простой, и код у него короткий:

            // register adminpad widget
            add_action('wp_dashboard_setup','adminpad_dashboard_widget');
            function adminpad_dashboard_widget() {
            	// only for site admins
            	if (current_user_can('activate_plugins')) {
            		wp_add_dashboard_widget('adminpad','AdminPad','adminpad_user_form');
            	} else {
            		return;
            	}
            }
            // display form and save data
            function adminpad_user_form() {
               $data = stripslashes(trim(get_option('adminpad_content')));
               if (isset($_POST['adminpad_save'])) {
            	  $note = trim($_POST['adminpad_content']);
            	  if (get_option('adminpad_content') !== false) {
            		 update_option('adminpad_content', $note);
            	  } else { add_option ('adminpad_content', $note); }
            	  echo '<meta http-equiv="refresh" content="0">';
               } else {
            	  $apform = '<form method="post" action="'.admin_url('index.php').'">';
            	  $apform .= '<div class="textarea-wrap" id="adminpad">';
            	  $apform .= '<textarea id="adminpad_content" name="adminpad_content" rows="5" cols="15" placeholder="Start writing...">'.$data.'</textarea></div>';
            	  $apform .= '<p style="margin-bottom:0;"><input type="submit" id="save" value="Save Note" class="button-primary"></p>';
            	  $apform .= '<input type="hidden" name="adminpad_save" id="adminpad_save" value="true"></form>';
               echo $apform;
               }    
            }

            Но вся эта конструкция почему-то очень долго грузится при нажатии на кнопку "сохранить". При этом содержимое виджета "схлопывается". Можно даже успеть сделать скриншот:

            Не подскажете что с этим делать?

            Ответитьмесяц назад #
            • Kama4477

              Картинка коду не соотвествует... Код не должен тормозить, но в нем есть дырки и вообще он какой-то не профессиональный... Но вроде должен работать.

              1
              Ответитьмесяц назад #
              • Вас смущает заголовок и расположение? В этом "несоответствие"? Это да, заголовок AdminPad я поменяла на "Заметки", а функцию wp_add_dashbord_widget на add_meta_box, под которой мы и беседуем. Соответственно, указала там параметры side и high. Но, в принципе, можно было этого не делать, весь блок перетаскивается на нужное место визуально и остаётся там после обновления страницы. А в целом замена заголовка и смена положения никак на проблему не влияют. Всё равно общая картина остаётся такой, как я её описала. Код работает, но при сохранении загружается очень медленно. Картинка была призвана проиллюстрировать именно это, что даже скриншот можно успеть сделать. Потом "схлопнутый" блок раскрывается.

                А что за дырки и что вообще с этим делать? Как мне решить проблему, если не этим плагином? Простая вроде задача-то ...

                Ответитьмесяц назад #
              • Присмотрелась повнимательнее - он не тормозит в прямом смысле слова, он дважды обновляет страницу. Если закомментировать строчку:

                echo '<meta http-equiv="refresh" content="0">';

                то страница перезагрузится с пустым виджетом, как на скриншоте. Если после этого обновить страницу ещё раз, вручную, то появится содержимое. Идиотизм какой-то ... Наверняка же можно сделать это за один раз.

                Ответитьмесяц назад #
                • campusboy1749 cайт: wp-plus.ru

                  Не могу уже смотреть на твои страдания smile вот, лови

                  <?php
                  
                  // Регистрация виджета "Мои заметки"
                  add_action( 'wp_dashboard_setup', 'my_notes_dashboard_widget' );
                  function my_notes_dashboard_widget() {
                  	// Регистрируем виджет только для администраторов сайта
                  	if ( ! current_user_can( 'activate_plugins' ) ) {
                  		return;
                  	}
                  
                  	wp_add_dashboard_widget( 'my_notes', 'Мои заметки', 'my_notes_form' );
                  }
                  
                  // Отображение виджета "Мои заметки"
                  function my_notes_form() {
                  	$notes_content = esc_textarea( get_option( 'my_notes_content' ) );
                  	printf( '<textarea>%s</textarea>', $notes_content );
                  	submit_button();
                  }
                  
                  // Сохранение текста заметки по Ajax
                  add_action( 'wp_ajax_my_notes', 'my_notes_ajax_save' );
                  function my_notes_ajax_save() {
                  	check_ajax_referer( 'my_notes_nonce', 'security' );
                  
                  	if ( ! isset( $_POST['my_notes_content'] ) || ! current_user_can( 'activate_plugins' ) ) {
                  		return;
                  	}
                  
                  	$notes_content = sanitize_textarea_field( wp_unslash( $_POST['my_notes_content'] ) );
                  
                  	// Обновляем данные
                  	$status = update_option( 'my_notes_content', $notes_content );
                  
                  	if ( $status ) {
                  		wp_send_json_success( array(
                  			'message' => 'Заметка сохранена'
                  		) );
                  	} else {
                  		wp_send_json_error( array(
                  			'message' => 'Заметка не изменилась'
                  		) );
                  	}
                  
                  }
                  
                  // Индивидуальные стили для виджета "Мои заметки"
                  add_action( 'admin_print_styles', 'my_notes_styles' );
                  function my_notes_styles() {
                  	?>
                  	<style>
                  		#my_notes textarea {
                  			width: 100%;
                  			min-height: 100px;
                  		}
                  
                  		#my_notes p {
                  			float: none !important;
                  			padding: 5px 0 0 !important;
                  		}
                  	</style>
                  	<?php
                  }
                  
                  // JS скрипт для ajax сохранения из виджета "Мои заметки"
                  add_action( 'admin_print_scripts', 'my_notes_scripts', 999 );
                  function my_notes_scripts() {
                  	$ajax_nonce = wp_create_nonce( "my_notes_nonce" );
                  	?>
                  	<script>
                  		jQuery(document).ready(function ($) {
                  			var $boxNotes = $('#my_notes');
                  
                  			$('#submit', $boxNotes).click(function () {
                  				$boxNotes.animate({opacity: 0.5}, 300);
                  
                  				$.post(
                  					ajaxurl,
                  					{
                  						action: 'my_notes',
                  						my_notes_content: $('textarea', $boxNotes).val(),
                  						security: '<?php echo $ajax_nonce; ?>'
                  					},
                  					function (response) {
                  						$boxNotes.animate({opacity: 1}, 300);
                  						$('h2 span', $boxNotes).text(response.data.message);
                  					}
                  				);
                  			});
                  		});
                  	</script>
                  	<?php
                  }
                  2
                  Ответитьмесяц назад #
                  • Ооо! "Каким теплом душа моя согрета! Свершилось всё, о чём я так мечтал!" (с) )))
                    Спасибище огромное. Пошла пробовать. )

                    1
                    Ответитьмесяц назад #
  • campusboy1749 cайт: wp-plus.ru

    Вот так можно добавить вкладку в аккардион меню:

    <?php
    add_action( 'admin_head-nav-menus.php', 'register_my_meta_box_accordion_nav_menus' );
    function register_my_meta_box_accordion_nav_menus() {
    	add_meta_box( 'my-custom-meta-box', 'Мой метабокс', 'render_my_meta_box_accordion_nav_menus', 'nav-menus', 'side' );
    }
    
    function render_my_meta_box_accordion_nav_menus() {
    	?>
    	<div class="my-custom-meta-box" id="my-custom-meta-box">
    		Контент метабокса
    	</div>
    	<?php
    }

    1
    Ответитьвчера #
    • campusboy1749 cайт: wp-plus.ru

      Пример, как не просто добавить вкладку в меню, но и реализовать выбор того или иного объекта. На примере выбора файлов из медиабиблиотеки:

      <?php
      /**
       * Регистрация и добавление вкладки в аккардионе для созданию меню
       *
       * @link https://gist.github.com/nikolov-tmw/8698598
       */
      add_action( 'admin_head-nav-menus.php', 'register_menu_files_metabox' );
      function register_menu_files_metabox() {
      	add_meta_box( 'menu-media-files-metabox', 'Файлы', 'render_menu_files_metabox', 'nav-menus', 'side', 'default' );
      }
      
      /**
       * Вывод на экран метабокса "Файлы"
       *
       * @param string $object Не используется.
       * @param array  $args   Параметры и аргументы.
       */
      function render_menu_files_metabox( $object, $args ) {
      	global $nav_menu_selected_id;
      	$files_ext = [ 'xlsx', 'pdf', 'zip' ];
      
      	$my_items = get_posts( [
      		'numberposts'    => - 1,
      		'post_type'      => 'attachment',
      		'post_mime_type' => get_mime_files_extension( $files_ext ),
      	] );
      
      	$walker       = new Walker_Nav_Menu_Checklist();
      	$removed_args = [
      		'action',
      		'customlink-tab',
      		'edit-menu-item',
      		'menu-item',
      		'page-tab',
      		'_wpnonce',
      	]; ?>
      	<div id="tab-files-div">
      	<div id="tabs-panel-list-files" class="tabs-panel tabs-panel-active">
      		<p>Отображаются только файлы с расширением <b><?php echo implode( ', ', $files_ext ); ?></b>.</p>
      
      		<ul id="tab-files-checklist-pop" class="categorychecklist form-no-clear">
      			<?php echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $my_items ), 0, (object) [ 'walker' => $walker ] ); ?>
      		</ul>
      
      		<p class="button-controls">
      			<span class="list-controls">
      				<a href="<?php
      				echo esc_url( add_query_arg(
      					[
      						'list-files' => 'all',
      						'selectall'  => 1,
      					],
      					remove_query_arg( $removed_args )
      				) );
      				?>#menu-media-files-metabox" class="select-all"><?php _e( 'Select All' ); ?></a>
      			</span>
      
      			<span class="add-to-menu">
      				<input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?>
      					   class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to Menu' ); ?>"
      					   name="add-tab-files-menu-item" id="submit-tab-files-div"/>
      				<span class="spinner"></span>
      			</span>
      		</p>
      	</div>
      	<?php
      }
      
      /**
       * Возвращает mime типы расширений файлов
       *
       * @param array $files_ext расширения файлов
       *
       * @return array
       */
      function get_mime_files_extension( $files_ext ) {
      
      	// Получает список разрешенных mime типов.
      	$mimes = get_allowed_mime_types();
      
      	// Поиск mime типа в массиве расширений.
      	$need_mimes = [];
      	foreach ( $files_ext as $file_ext ) {
      		foreach ( $mimes as $type => $mime ) {
      			if ( false !== strpos( $type, $file_ext ) ) {
      				$need_mimes[] = $mime;
      			}
      		}
      	}
      
      	return $need_mimes;
      }
      
      /**
       * Заменяет ссылку на страницу медиафайла ссылкой на сам медиафайл
       *
       * @param string $link    ссылка на страницу медиафайла
       * @param string $post_id ID медиафайла
       *
       * @return string
       */
      add_filter( 'attachment_link', 'change_attachment_link', 1000, 2 );
      function change_attachment_link( $link, $post_id ) {
      	return wp_get_attachment_url( $post_id );
      }

      Основа взята из файла custom-menu-panel.php, найденного на просторах github и реализующий добавления кастомных объектов для списка.

      1
      Ответитьвчера #

Здравствуйте, !

Ваш комментарий