Вопрос или проблема
Я пытаюсь создать портал для клиентов, однако приватная страница не отображается в выпадающем списке родительских страниц (выпадающее меню в правом нижнем углу настроек страницы под атрибутами страницы). И родительская, и дочерняя страницы должны быть приватными, чтобы их могли видеть только авторизованные пользователи.
Я пробовал этот код, но он не сработал для меня.
/**
* Добавление приватных/черновиков/будущих/ожидающих страниц в выпадающий список родительских страниц.
*/
function wps_dropdown_pages_args_add_parents( $dropdown_args, $post = NULL ) {
$dropdown_args['post_status'] = array( 'publish', 'private' );
return $dropdown_args;
}
add_filter( 'page_attributes_dropdown_pages_args', 'wps_dropdown_pages_args_add_parents' );
add_filter( 'quick_edit_dropdown_pages_args', 'wps_dropdown_pages_args_add_parents' );
Предполагается, что следующее условие сделает это работающим
- Используется Классический Редактор, поскольку Gutenberg/Редактор Блоков рендерится с помощью Javascript, требует других решений и пока я не уверен, есть ли опция переопределения.
Для кода, который вы показали, не работает, потому что количество аргументов для add_filter() не указано.
По умолчанию используется только 1 аргумент. Чтобы использовать более 1 аргумента, необходимо указать.
Исправление кода (Код автора для Классического Редактора)
Следующий код протестирован, он работает для любых типов записей, даже для собственных типов записей.
Следующий код доказал свою работоспособность, будучи размещённым в functions.php темы.
/**
* Добавление приватных/черновиков/будущих/ожидающих страниц в выпадающий список родительских страниц.
*/
function wps_dropdown_pages_args_add_parents( $dropdown_args, $post = NULL ) {
$dropdown_args['post_status'] = array( 'publish', 'private' );
return $dropdown_args;
}
add_filter( 'page_attributes_dropdown_pages_args', 'wps_dropdown_pages_args_add_parents', 10, 2 );
add_filter( 'quick_edit_dropdown_pages_args', 'wps_dropdown_pages_args_add_parents' );
Отключение Редактора Блоков (для метода Классического Редактора)
В случае, если кому-либо потребуется отключить редактор Gutenberg для проверки вышеуказанного кода, можно вставить следующий код в functions.php темы:
add_filter( 'use_block_editor_for_post_type', 'sing_use_block_editor_for_post_type', 10, 2 );
function sing_use_block_editor_for_post_type( $can_use, $post_type ) {
switch ( $post_type ) {
case 'custom_post_types':
case 'post':
case 'page':
$can_use = false;
break;
default:
$can_use = true;
break;
}
return $can_use;
}
Метод переопределения для Редактора Блоков/Gutenberg
Пожалуйста, используйте фильтр
rest_{$this->post_type}_query для переопределения запроса
Так как Gutenberg использует Rest API для загрузки данных, список страниц является одним из них.
Следующий код протестирован на тех же тестовых страницах, где и родительская, и дочерняя страницы являются приватными. Следующий код работает, если его поместить в functions.php темы:
add_filter( 'rest_page_query', 'test_rest_page_query', 10, 2);
function test_rest_page_query( $args, $request ) {
// пожалуйста, добавьте свою собственную логику, такую как логика проверки идентификатора экрана
$args['post_status'] = array( 'publish', 'private' );
return $args;
}
Небольшая корректировка безопасности и области действия фрагмента @arushi-rajput:
/**
* Показать всех родителей, независимо от статуса записи. (для Редактора Блоков)
*/
add_filter( 'rest_page_query', 'test_rest_page_query', 10, 2);
function test_rest_page_query( $args, $request ) {
// Проверьте, есть ли у пользователя способность 'edit_pages'
if ( current_user_can( 'edit_pages' ) ) {
$args['post_status'] = array( 'publish', 'private', 'draft', 'pending', 'future' );
} else {
// Для других пользователей показывать только статус 'publish'
$args['post_status'] = array( 'publish' );
}
return $args;
}
Для любого, у кого возникла эта проблема в стандартном интерфейсе wp-admin/edit.php?post_type=page, можно обойти её следующим образом:
- На время изменить родительскую страницу с приватного на публичный статус.
- Установить родительскую страницу для дочерней(их) страницы(страниц) по мере необходимости – поскольку родитель теперь будет виден в выпадающих меню.
- Вернуть родительскую страницу с публичного на приватный статус.
Ответ или решение
Рассмотрим проблему, с которой вы столкнулись при создании портала для клиентов, используя WordPress. В вашем случае, вы хотите установить определенную страницу как родительскую для другой страницы, но обе страницы должны быть приватными и доступны только авторизованным пользователям. Однако, вы заметили, что приватная страница не отображается в выпадающем списке выбора родительской страницы. Давайте детально разберем проблему и способы её решения.
Теория
В WordPress механизм выбора родительских страниц реализован через функцию, которая по умолчанию отображает только опубликованные страницы. Это связано с тем, что в большинстве случаев публичные страницы отображаются пользователям, таким образом, администраторы сайта могут настроить иерархию страниц с использованием опубликованных страниц. Однако, для сайтов с особой организацией контента, например, для порталов, где контент должен быть доступен только определенной группе пользователей, требуется дополнительная настройка.
Пример
В приведенном вами коде используется фильтр page_attributes_dropdown_pages_args
, который позволяет изменить параметры запроса, используемого для генерации списка страниц в админке. Вы пытались добавить страницы со статусом private
в выпадающий список родительских страниц, но не указали количество аргументов, передаваемых в функцию обработки фильтра, что и стало причиной возникновения проблемы.
Пример исправленного кода:
/**
* Добавляет приватные/черновые/будущие/ожидающие публикации страницы в выпадающий список родительских страниц.
*/
function wps_dropdown_pages_args_add_parents( $dropdown_args, $post = NULL ) {
$dropdown_args['post_status'] = array( 'publish', 'private' );
return $dropdown_args;
}
add_filter( 'page_attributes_dropdown_pages_args', 'wps_dropdown_pages_args_add_parents', 10, 2 );
add_filter( 'quick_edit_dropdown_pages_args', 'wps_dropdown_pages_args_add_parents' );
С помощью этих строк кода вы настроите WordPress так, чтобы в классическом редакторе страницы со статусом private
появлялись в выпадающем меню при выборе родительских страниц.
Применение
Для того чтобы изменения работали корректно, убедитесь, что вы отключили редактор блоков (известный как Gutenberg) и используете классический редактор. Код для отключения редактора блоков выглядит следующим образом:
add_filter( 'use_block_editor_for_post_type', 'disable_gutenberg_for_specified_post_types', 10, 2 );
function disable_gutenberg_for_specified_post_types( $can_use, $post_type ) {
$can_use = !in_array( $post_type, ['custom_post_types', 'post', 'page'] );
return $can_use;
}
Если же вы хотите сохранить использование редактора Gutenberg, вам потребуется переключиться на REST API подход для получения списков страниц, что требует использования фильтра rest_page_query
. Код, который позволит учесть это:
add_filter( 'rest_page_query', 'adjust_rest_page_query', 10, 2 );
function adjust_rest_page_query( $args, $request ) {
if ( current_user_can( 'edit_pages' ) ) {
$args['post_status'] = array( 'publish', 'private', 'draft', 'pending', 'future' );
} else {
$args['post_status'] = array( 'publish' );
}
return $args;
}
Этот код обеспечивает, чтобы только пользователи с соответствующими правами (например, те, кто может редактировать страницы) могли видеть все страницы, независимо от их статуса.
Дополнительный совет
В случае, если указанные программные методы кажутся слишком сложными или требуют слишком глубокого знания системы, вы можете временно изменить статус родительской страницы на ‘публичный’, установить страницу в качестве родительской для необходимых страниц, а затем вернуть изначальный статус — ‘приватный’. Это обходной путь, но он требует ручного вмешательства каждый раз при настройке иерархии страниц.
Таким образом, комбинация программных и ручных решений позволит вам эффективно управлять приватными страницами в WordPress, создавая функциональный и защищенный портал для клиентов.