Можно ли использовать динамический идентификатор поста в add_menu_page()?

Вопрос или проблема

Я использую функцию 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(), для получения идентификатора поста по его заголовку. Давайте разберем это подробно.

Шаги для динамического присвоения идентификаторов

  1. Использование функции get_page_by_title():
    Эта функция позволяет получать объект поста на основе его заголовка. Это является основой для решения вашей задачи. Пример использования:

    $home_post = get_page_by_title('Home');
  2. Генерация правильной ссылки для 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").

  3. Кеширование для оптимизации производительности:
    Один из минусов использования get_page_by_title() заключается в том, что эта функция выполняет SQL-запросы при каждом вызове. Для улучшения производительности можно реализовать механизм кеширования:

    • Сохраните результаты в опции WordPress с помощью update_option().
    • Создайте хук на сохранение поста (save_post), чтобы обновлять кеш после изменения или сохранения поста.
  4. Создание страницы настроек (при необходимости):
    Более надежным подходом будет создание страницы настроек, где администратор может вручную назначить идентификаторы постов. Это устранит зависимость от заголовков, которые могут изменяться.

Пример кода на базе всех шагов:

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');

Заключение

Правильная настройка динамических идентификаторов позволит сэкономить время и модернизировать процессы обновления кода при переносе сайта на другой сервер. Не забывайте о важности надежного кеширования для уменьшения нагрузки на сервер. Такой подход будет полезен и стабильен в долгосрочной перспективе.

Оцените материал
Добавить комментарий

Капча загружается...