Вопрос или проблема
Я использую функцию add_menu_page в своих пользовательских темах, но когда я экспортирую свою локальную копию сайта и импортирую её на продакшн-сайт, некоторые из номеров id постов меняются, и мне приходится обновлять эту функцию вручную (например, в коде ниже: ?post=8, ?post=8, ?post=10). Есть ли способ сделать эти номера динамическими?
function custom_admin_menu_links() {
$user = wp_get_current_user();
if ( ! $user->has_cap( 'manage_options' ) ) {
add_menu_page( 'Home', 'Home', 'edit_posts', 'post.php?post=6&action=edit', '', 'dashicons-admin-home', 1);
add_menu_page( 'About', 'About', 'edit_posts', 'post.php?post=8&action=edit', '', 'dashicons-id', 2);
add_menu_page( 'Contact', 'Contact', 'edit_posts', 'post.php?post=10&action=edit', '', 'dashicons-phone', 3);
}
}
add_action( 'admin_menu', 'custom_admin_menu_links' );
Существует функция под названием get_page_by_title
, которая принимает название поста и возвращает его ID. Вы можете использовать её вместе с get_edit_post_link
, передавая ID и получая ссылку на редактирование.
Однако, как вы можете быть уверены, что название поста никогда не изменится? Вы можете пойти дальше и добавить страницу настроек, где будете связывать конкретный пост/страницу с сущностью, такой как HOME_ID
, ABOUT_ID
и т. д. Затем, вместо использования get_page_by_title
у вас будет этот массив настроек, и вы сможете создавая использовать вызовы add_menu_page
следующим образом:
if ( ! $user->has_cap( 'manage_options' ) ) {
$options = get_option( 'wt_menu_post_ids', array() );
add_menu_page( 'Home', 'Home', 'edit_posts', get_edit_post_link( $options['HOME_ID'] ), '', 'dashicons-admin-home', 1);
// [...]
}
Быстрое и простое решение может быть таким:
function custom_admin_menu_links() {
$user = wp_get_current_user();
if ( $user->has_cap( 'manage_options' ) ) {
$type="book";
$page = get_page_by_title('home','object',$type);
if (!empty($page)) {
add_menu_page( 'Home', 'Home', 'edit_posts', 'post.php?post=".$page->ID."&action=edit', '', 'dashicons-admin-home', 1);
}
$page = get_page_by_title('About','object',$type);
if (!empty($page)) {
add_menu_page( 'About', 'About', 'edit_posts', 'post.php?post=8&action=edit', '', 'dashicons-id', 2);
}
$page = get_page_by_title('Contact','object',$type);
if (!empty($page)) {
add_menu_page( 'Contact', 'Contact', 'edit_posts', 'post.php?post=10&action=edit', '', 'dashicons-phone', 3);
}
}
}
add_action( 'admin_menu', 'custom_admin_menu_links' );
Но вы выполняете множество запросов при каждой загрузке страницы администратора. Вам действительно стоит найти способ кэшировать результаты. Что-то вроде:
function cache_custom_admin_menu_links($post_ID, $post) {
$links = get_option('my_menu_links');
$keys = array(
'home',
'about',
'contact'
);
if (in_array($post->post_name,$keys)) {
$links[$post->post_name] = $post_ID;
update_option('my_menu_links',$links);
}
}
add_action('save_post','cache_custom_admin_menu_links',10,2);
function custom_admin_menu_links() {
$user = wp_get_current_user();
if ( $user->has_cap( 'manage_options' ) ) {
$type="book";
$links = get_option('my_menu_links');
$i = 1;
foreach ($links as $k=>$v) {
add_menu_page( $k, ucfirst($k), 'edit_posts', 'post.php?post=".$v."&action=edit', '', 'dashicons-phone', $i);
$i++;
}
}
}
add_action( 'admin_menu', 'custom_admin_menu_links' );
Тогда вам просто нужно будет заново сохранить свои посты, а не редактировать код. Я уверен, что даже этот процесс можно автоматизировать, если это необходимо.
да, возможно сделать ID постов динамическими в функции add_menu_page()
. мы можем использовать функцию get_page_by_title()
, чтобы получить ID постов на основе их названий.
function custom_admin_menu_links() {
$user = wp_get_current_user();
if ( ! $user->has_cap( 'manage_options' ) ) {
$home_post = get_page_by_title( 'Home' );
$about_post = get_page_by_title( 'About' );
$contact_post = get_page_by_title( 'Contact' );
if ($home_post) {
add_menu_page( 'Home', 'Home', 'edit_posts', 'post.php?post=" . $home_post->ID . "&action=edit', '', 'dashicons-admin-home', 1);
}
if ($about_post) {
add_menu_page( 'About', 'About', 'edit_posts', 'post.php?post=" . $about_post->ID . "&action=edit', '', 'dashicons-id', 2);
}
if ($contact_post) {
add_menu_page( 'Contact', 'Contact', 'edit_posts', 'post.php?post=" . $contact_post->ID . "&action=edit', '', 'dashicons-phone', 3);
}
}
}
add_action( 'admin_menu', 'custom_admin_menu_links' );
Ответ или решение
Конечно, возможно сделать идентификаторы постов динамическими в функции add_menu_page()
. Ваша задача состоит в том, чтобы каждый раз, когда вы переносите сайт с локального на продуктивный сервер, не приходилось вручную обновлять код. Это достигается использованием функций WordPress, таких как get_page_by_title()
, для получения идентификатора поста по его заголовку. Давайте разберем это подробно.
Шаги для динамического присвоения идентификаторов
-
Использование функции
get_page_by_title()
:
Эта функция позволяет получать объект поста на основе его заголовка. Это является основой для решения вашей задачи. Пример использования:$home_post = get_page_by_title('Home');
-
Генерация правильной ссылки для
add_menu_page()
:
После получения объекта поста, используйте егоID
для создания ссылки вadd_menu_page()
:if ($home_post) { add_menu_page('Home', 'Home', 'edit_posts', 'post.php?post=' . $home_post->ID . '&action=edit', '', 'dashicons-admin-home', 1); }
Это же самое можно сделать и для других страниц ("About", "Contact").
-
Кеширование для оптимизации производительности:
Один из минусов использованияget_page_by_title()
заключается в том, что эта функция выполняет SQL-запросы при каждом вызове. Для улучшения производительности можно реализовать механизм кеширования:- Сохраните результаты в опции WordPress с помощью
update_option()
. - Создайте хук на сохранение поста (
save_post
), чтобы обновлять кеш после изменения или сохранения поста.
- Сохраните результаты в опции WordPress с помощью
-
Создание страницы настроек (при необходимости):
Более надежным подходом будет создание страницы настроек, где администратор может вручную назначить идентификаторы постов. Это устранит зависимость от заголовков, которые могут изменяться.
Пример кода на базе всех шагов:
function cache_custom_admin_menu_links($post_ID, $post) {
$links = get_option('my_menu_links', array());
$keys = array('home', 'about', 'contact');
if (in_array($post->post_name, $keys)) {
$links[$post->post_name] = $post_ID;
update_option('my_menu_links', $links);
}
}
add_action('save_post', 'cache_custom_admin_menu_links', 10, 2);
function custom_admin_menu_links() {
$user = wp_get_current_user();
if (!$user->has_cap('manage_options')) {
$links = get_option('my_menu_links');
$i = 1;
foreach ($links as $k => $v) {
add_menu_page(ucfirst($k), ucfirst($k), 'edit_posts', 'post.php?post=' . $v . '&action=edit', '', 'dashicons-' . $k, $i);
$i++;
}
}
}
add_action('admin_menu', 'custom_admin_menu_links');
Заключение
Правильная настройка динамических идентификаторов позволит сэкономить время и модернизировать процессы обновления кода при переносе сайта на другой сервер. Не забывайте о важности надежного кеширования для уменьшения нагрузки на сервер. Такой подход будет полезен и стабильен в долгосрочной перспективе.