Добавить пользовательский пункт меню администратора для страниц, использующих определенный шаблон
Я хочу добавить новый пользовательский пункт меню на боковую панель администратора WordPress, который отображает страницы, использующие определенный шаблон. Например: группа страниц использует шаблон под названием "Рассылка розничной торговли" (page-retailer-sendout.php ) будет отображаться под пунктом меню верхнего уровня "Страницы" по умолчанию.
Я пробовал следующие комбинации URL-адресов, но ни одна из них не сработала так далеко.
- http://domain.test/wp-admin/edit.php?post_type=page&page_template=page-retailer-sendout
- http://domain.test/wp-admin/edit.php?post_type=pagetemplate=page-retailer-sendout
- http://domain.test/wp-admin/edit.php?post_type=page&page_template=retailer_sendout
Я также протестировал некоторые плагины настройки меню администратора, но они не дают возможности ссылаться на страницы с определенным именем шаблона.
Я мне удобно добавлять пользовательскую функцию в тему functions.php файл, но я не знаю, с чего начать.
Мы будем очень признательны за любую помощь.
1 answers
Если это то, что вы хотите:
... вы можете сделать это так:
Шаг №1: Добавьте пользовательский пункт меню (Retailer Sendout
).
function add_retailer_sendout_admin_menu() {
$slug = 'edit.php?post_type=page&template=page-retailer-sendout.php';
add_menu_page( 'Retailer Sendout', 'Retailer Sendout', 'edit_pages', $slug,
'', 'dashicons-admin-page', 19 );
}
add_action( 'admin_menu', 'add_retailer_sendout_admin_menu' );
Примечания:
Я использую
add_menu_page()
чтобы добавить меню (которое является меню верхнего уровня) с разрешениемedit_pages
и значкомdashicons-admin-page
- просто проверьте ссылку для получения более подробной информации о синтаксисе и параметрах, но позиция (7-й параметр) установлена на19
, которая поместил бы меню надPages
меню.Если вы измените имя строки запроса
template
, вам также необходимо изменить его в на обоих шагах #2 и #3 ниже. Но если вы измените только значение , вам нужно будет также изменить его на шаге №2 ниже.
Шаг №2: Выделите пункт меню (это добавит current
к пункту/li
class
) после того, как вы нажали на ссылку.
Потому что "Страницы" и "Страницы" Меню всех страниц slug edit.php?post_type=page
, мы должны убедиться, что WordPress не переопределяет $parent_file
(т.Е. Указанное выше значение $slug
), как указано в highlight_retailer_sendout_admin_menu()
ниже, поэтому fix_admin_parent_file_override()
, хотя это хак/трюк, необходим - вы могли бы просто добавить класс CSS current
в меню Retailer Sendout
, но в итоге у вас будет два/три выделенных меню..
И хотя я не изменяю CSS class
, вы можете использовать эту функцию для добавления своих пользовательских классов и/или удаления/редактирования существующих. Кроме того, просто так вы знаете, что $menu
представляет собой массив меню верхнего уровня только , поэтому я использую $submenu
для доступа к подменю. Я также использую $pagenow
, потому что на данный момент текущий экран (см. get_current_screen()
) еще не был настроен.
function fix_admin_parent_file_override( $menu ) {
global $pagenow, $submenu;
// If we're NOT on the edit.php page, do nothing.
if ( ! is_admin() || 'edit.php' !== $pagenow ) {
return $menu;
}
// Same as in the above add_retailer_sendout_admin_menu().
$slug = 'edit.php?post_type=page&template=page-retailer-sendout.php';
// We have to make sure the $parent_file is not overriden (by WordPress) to
// the 'Pages' menu.
if ( ! empty( $_GET['template'] ) &&
'page-retailer-sendout.php' === $_GET['template'] ) {
// Change the 'Pages' URL.
$menu[20][2] .= '&template=';
$submenu[ $menu[20][2] ] = $submenu['edit.php?post_type=page'];
// Change the 'All Pages' URL.
$submenu[ $menu[20][2] ][5][2] = $menu[20][2];
unset( $submenu['edit.php?post_type=page'] );
}
return $menu;
}
add_filter( 'add_menu_classes', 'fix_admin_parent_file_override' );
И далее мы устанавливаем $parent_file
- обратите внимание, что в приведенном выше примере мы не устанавливаем $parent_file
, мы только следим за тем, чтобы WordPress впоследствии не переопределял значение. Поэтому для этой части мы должны использовать parent_file
крюк:
function highlight_retailer_sendout_admin_menu( $parent_file ) {
// Make sure the PARENT slug is the one for the 'Pages' / 'All Pages' menu.
if ( 'edit.php?post_type=page' === $parent_file &&
( ! empty( $_GET['template'] ) ) &&
// ..and make sure the template being queried is page-retailer-sendout.php.
'page-retailer-sendout.php' === $_GET['template'] )
{
// Return the $slug value as in the above add_retailer_sendout_admin_menu()
return 'edit.php?post_type=page&template=page-retailer-sendout.php';
}
return $parent_file;
}
add_filter( 'parent_file', 'highlight_retailer_sendout_admin_menu' );
Шаг № 3: Отфильтруйте страницы по шаблону.
Имя шаблона хранится в частных метаданных с именем _wp_page_template
, поэтому мы фильтруем запрос сообщений/страниц, добавляя мета-запрос для этих метаданных.
И мы используем pre_get_posts
крюк, который также работает на общедоступной стороне сайта, поэтому мы выполняем проверки, такие как is_admin()
и is_main_query()
чтобы предотвратить вмешательство в другие WP_Query
вызовы (или сообщения запросы).
function filter_admin_pages_by_template( $query ) {
// Make sure we run the filter only on the admin side of the site (wp-admin)
// and that the query is the main query.
if ( is_admin() && $query->is_main_query() &&
( ! empty( $_GET['template'] ) ) &&
// ..and also, check if we're on the edit.php?post_type=page screen.
'edit-page' === get_current_screen()->id )
{
$meta_query = (array) $query->get( 'meta_query' );
$meta_query[] = array(
'key' => '_wp_page_template',
'value' => $_GET['template'],
);
$query->set( 'meta_query', $meta_query );
}
}
add_action( 'pre_get_posts', 'filter_admin_pages_by_template' );
И на самом деле, вы можете использовать код для фильтрации любых шаблонов.. не только page-retailer-sendout.php
, как в вопросе. :)