Полное руководство по настройке WordPress API, часть 6: страницы меню

Содержание цикла статей «Полное руководство по настройке WordPress API»:

  1. Полное руководство по настройке WordPress API, часть 1: введение
  2. Полное руководство по настройке WordPress API, часть 2: секции, поля и настройки
  3. Полное руководство по настройке WordPress API, часть 3: все о создании меню
  4. Полное руководство по настройке WordPress API, часть 4: опции темы
  5. Полное руководство по настройке WordPress API, часть 5: закладочная навигация
  6. Полное руководство по настройке WordPress API, часть 6: страницы меню
  7. Полное руководство по настройке WordPress API, часть 7: валидация, очистка и элементы ввода
  8. Полное руководство по настройке WordPress API, часть 8: валидация, очистка и элементы ввода

В третьей части данной серии статей, мы познакомились с различными функциями для создания меню, которые предоставляет WordPress API. Если вы читали все статьи и выполняли все примеры, то знаете, что мы уже создали страницу настроек для нашей темы с помощью функции add_theme_page.

Хотя создание меню и подменю не относится к Settings API, оно играет важную роль в построении функциональности плагинов и/или тем.

В этой статье, мы создадим новое меню в панели управления WordPress, которое сделает опции нашей темы доступными везде, а не только из меню опций «Внешний вид» (Appearance).

Примечание: статья предполагает, что вы уже знакомы с Settings API и опциями темы. Если вы начинающий разработчик, то рекомендуется сначала ознакомиться с предыдущими статьями цикла.

Взгляд на API

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

До того, как рассмотреть примеры, давайте определимся с тем, что мы собираемся делать дальше:

  • Создание меню верхнего уровня для опций нашей темы;
  • Добавление подменю для закладки «Опции отображения»;
  • Добавление подменю для закладки «Опции социальных сетей».

Для реализации данного плана нам понадобится две функции:

  • add_menu_page для создания меню верхнего уровня;
  • add_submenu_page для создания подменю.

Мы узнаем о параметрах, принимаемых каждой функцией и о назначении их использования в нашей теме.

Работа в данной статье основана на этой версии шаблона Sandbox. Проверьте, что ваша версия совпадает с ней.

Меню верхнего уровня

Первым делом, мы хотим создать меню верхнего уровня. Этот пункт меню будет показан сразу после пункта «Настройки» (Settings) в административной панели WordPress и будет выполнять несколько задач:

  1. Показывать доступные опции темы;
  2. Отображать раздел настроек, заданный по умолчанию.

Функция принимает семь аргументов — первые пять обязательные, а остальные два — нет:

  • Page_title – текст, отображаемый в заголовке окна браузера;
  • Menu_title – текст, отображаемый в названии пункта меню;
  • Capability – группа пользователей, имеющих доступ к данному меню;
  • Menu_slug – уникальное значение, идентифицирующее это меню. Необходимо для регистрации подменю;
  • Function_name – имя функции, вызываемой при клике по пункту меню;
  • Icon_url – путь к иконке, которая будет отображаться рядом с названием меню;
  • Position – расположение создаваемого пункта меню по отношению к уже имеющимся.

В нашей дальнейшей работе мы сфокусируемся только на первых пяти параметрах. Позиционирование меню будет рассмотрено в конце статьи.

Сначала, создадим вызов функции add_menu_page. Согласно WordPress Codex, пункт меню в административную панель может быть добавлен с помощью хука admin_menu.

Ранее, мы уже писали функцию, которая добавляет пункт меню нашей темы в меню «Внешний вид» (Appearance). Если быть точным, то функция sandbox_example_theme_menu выглядела так:

function sandbox_example_theme_menu() {  
  
    add_theme_page(  
        'Тема Sandbox',             // Текст в заголовке браузера  
        'Тема Sandbox',             // Текст самого пункта меню в боковом меню WordPress  
        'administrator',            // Группы пользователей, имеющих доступ к данному меню  
        'sandbox_theme_options',    // Уникальный ID - псевдоним – для данного пункта меню  
        'sandbox_theme_display'     // Имя функции, используемой для вывода страницы пункта меню на экран   
    );  
  
}  // Конец функции sandbox_example_theme_menu

add_action('admin_menu', 'sandbox_example_theme_menu');

В этом коде функция регистрировалась с помощью хука admin_menu. Всегда очень важно сохранять логику в последовательности написания функций.

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

Добавьте вызов функции add_menu_page прямо под вызовом выше:

add_menu_page(  
        'Тема Sandbox',             // Текст, выводимый в заголовке браузера  
        'Тема Sandbox',             // Текст, выводимый в названии пункта меню  
        'administrator',            // Группа пользователей, имеющих доступ к данному пункту меню  
        'sandbox_theme_menu',       // Идентификатор, используемый для создания подменю   
        'sandbox_theme_display'     // Callback-функция, используемая для вывода страницы данного меню  
    );

Как видите, мы зарегистрировали меню, которое будет отображать текст «Тема Sandbox» в заголовке браузера и названии пункта меню. Мы дали доступ к этому меню только администраторам и присвоили ему уникальный ID — sandbox_theme_parent_menu. Далее мы будем использовать это значение.

Важно прояснить одну вещь: мы определили sandbox_theme_display как функцию, вызываемую при нажатии на пункт меню. В третьей части мы использовали эту функцию (и модифицировали её в пятой части). Она ответственна за вывод нашей страницы опций с закладками.

Передавая её имя функции add_menu_page, мы выводим для пункта меню страницу опций по умолчанию.

Теперь мы готовы начать создание подменю, но сначала давайте убедимся, что ваши функции выглядят вот так:

function sandbox_example_theme_menu() {  
  
    add_theme_page(  
        'Тема Sandbox',             // Текст в заголовке браузера  
        'Тема Sandbox',             // Текст самого пункта меню в боковом меню WordPress  
        'administrator',            // Группы пользователей, имеющих доступ к данному меню  
        'sandbox_theme_options',    // Уникальный ID - псевдоним – для данного пункта меню  
        'sandbox_theme_display'     // Имя функции, используемой для вывода страницы пункта меню на экран   
    );

    add_menu_page(  
        'Тема Sandbox',             // Текст, выводимый в заголовке браузера  
        'Тема Sandbox',             // Текст, выводимый в названии пункта меню  
        'administrator',            // Группа пользователей, имеющих доступ к данному пункту меню  
        'sandbox_theme_menu',       // Идентификатор, используемый для создания подменю   
        'sandbox_theme_display'     // Callback-функция, используемая для вывода страницы данного меню  
    );
  
}  // Конец функции sandbox_example_theme_menu

Добавление подменю

Процесс добавления подменю очень похож на использующийся для меню, за исключением того, что подменю принадлежит уже созданному пункту меню. Функции API для регистрации подменю также аналогичны меню.

Функция принимает шесть аргументов, обязательными из которых являются первые пять, а оставшийся — опциональный:

  • Parent_slug – уникальный идентификатор родительского пункта меню; в нашем случае, sandbox_theme_menu;
  • Page_title – текст, отображаемый в заголовке окна браузера, при активации данного подпункта меню;
  • Menu_title – название подпункта меню в административной панели;
  • Capability – группа пользователей, имеющих доступ к данному пункту меню;
  • Menu_slug – уникальный ID для данного подпункта;
  • Function_name – функция, вызываемая при активации данного подпункта.

Функция довольно проста в работе. Нам необходимо создать два подпункта меню – один для «Опций отображения» и один для «Опций социальных сетей».

Опции отображения

Сначала, давайте создадим подменю для опций отображения. Добавьте следующий блок кода прямо под вызовом функции add_menu_page, который был определен выше:

add_submenu_page(  
        'sandbox_theme_menu',               // Уникальный ID пункта меню верхнего уровня, которому принадлежит данный подпункт  
        'Опции отображения',                // Текст, выводимый в заголовке браузера  
        'Опции отображения',                // Текст, выводимый в названии пункта меню
        'administrator',                    // Группа пользователей, имеющих доступ к данному пункту меню 
        'sandbox_theme_display_options',    // Идентификатор, используемый для создания данного пункта внутри меню 
        'sandbox_theme_display'             // Callback-функция, используемая для вывода страницы данного меню 
    );

Все параметры, передаваемые этой функции должны быть четко определены, за исключением function_name, передаваемого последним. Заметьте, что это значение совпадает со значением, указанным в вызове add_menu_page. Но разница есть, как вы считаете?

Группа настроек «Опции отображения» является стандартной при входе в меню опций, поэтому она должна отобразиться при активации меню верхнего уровня настроек нашей темы, а также вкладки «Опции отображения».

Важная особенность WordPress: после того, как вы добавили первый подпункт меню, WordPress будет отображать ДВА подпункта в меню верхнего уровня, один из которых дублирует функции пункта меню верхнего уровня, а другой относится к созданному подпункту.

Я обратил на это внимание, потому что видел разработчиков, которых вводила в ступор эта особенность. Но это именно особенность WordPress, а не ошибка в вашем коде.

Опции социальных сетей

Добавление пункта меню для опций социальных сетей, практически полностью аналогично шагам для добавления пункта опций отображения. Мы просто изменим значения для заголовка, названия пункта меню и страницы, вызываемой при выборе пункта.

Сначала, осуществим вызов функции add_submenu_page. Это будет выглядеть так:

add_submenu_page(  
    'sandbox_theme_menu',
    'Опции социальных сетей',
    'Опции социальных сетей',
    'administrator',
    'sandbox_theme_social_options',
    'sandbox_theme_display'
);

Сохраните изменения, обновите окно административной панели и увидите подпункт «Опции социальных сетей» доступный в меню «Тема Sandbox». Однако при клике на этом пункте показываются «Опции отображения».

Мы столкнулись с небольшим испытанием: нам нужно выбрать закладку «Опции социальных сетей» при клике на соответствующем подпункте.

Переработка функционала закладок

У нас несколько вариантов как привязать наш пункт подменю к закладке:

  • Можно объявить новую функцию, которая бы выводила опции социальных сетей. Это требует проделывания некоторой дополнительной работы по созданию новой функции, настройке закладок таким образом, чтобы не нарушить удобство интерфейса, а также не допустить увеличения объёма кода;
  • Мы можем переопределить существующую функцию sandbox_theme_display для приема опциональных параметров и затем использовать анонимную функцию, вызвав add_submenu_page и передав в неё параметры через данную анонимную функцию.

Оба этих варианта нам подходят. Однако, лично я лучше переделаю функцию, чем буду увеличивать объём кода, поэтому далее будет рассмотрен именно этот способ.

Переопределим функцию sandbox_theme_display. Передадим ей опциональный аргумент, который будет использоваться для указания закладки, которую мы хотим выделить. Найдите следующий кусок кода в файле functions.php:

function sandbox_theme_display() {  
    /* Пример создан специально для данной статьи. */  
} // Конец функции sandbox_theme_display

Обновите заголовок таким образом, чтобы функция принимала один аргумент и возвращала значение null, если этот аргумент не определен:

function sandbox_theme_display( $active_tab = null ) {  
    /* Пример создан специально для данной статьи. */  
} // Конец функции sandbox_theme_display

Если вы новичок в PHP, то можете прочитать об аргументах по умолчанию здесь.

Из предыдущей статьи вы помните, что наша функция отображения считывает установленное значение строки запроса. Мы хотим оставить этот механизм рабочим, но нужно учитывать, что параметр может быть передан также и в функцию.

Чтобы выполнить такую модификацию, найдите следующий блок кода в функции sandbox_theme_display:

$active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'display_options';

Данный код занимается только обработкой параметров в строке запроса. Чтобы учесть новые опциональные параметры, нам нужен алгоритм, который сначала проверяет, задан ли параметр строки запроса; если нет, то проверяет, задан ли аргумент функции для отображения опций социальных сетей; если нет, то по умолчанию оно покажет закладку «Опции отображения».

Измените код выше, добавив в него следующую условную конструкцию:

if( isset( $_GET[ 'tab' ] ) ) {  
    $active_tab = $_GET[ 'tab' ];  
} else if( $active_tab == 'social_options' ) {  
    $active_tab = 'social_options';  
} else {  
    $active_tab = 'display_options';  
} // Конец конструкции if/else

Конечная версия кода выглядит следующим образом:

function sandbox_theme_display( $active_tab = null ) {  
?>  
    <!-- Создаем заголовок в стандартном контейнере «wrap» -->  
    <div class="wrap">  
  
        <!-- Добавляем иконку к странице -->  
        <div id="icon-themes" class="icon32"></div>  
        <h2>Опции темы Sandbox</h2>  
  
        <!-- Делаем вызов функции WordPress для вывода ошибок, возникающих при сохранении настроек. -->  
        <?php settings_errors(); ?> 

        <?php  
        if( isset( $_GET[ 'tab' ] ) ) {  
            $active_tab = $_GET[ 'tab' ];  
        } else if( $active_tab == 'social_options' ) {  
            $active_tab = 'social_options';  
        } else {  
            $active_tab = 'display_options';  
        } // Конец конструкции if/else
        ?>

        <h2 class="nav-tab-wrapper">  
            <a href="?page=sandbox_theme_options&tab=display_options" class="nav-tab">Опции отображения</a>
            <a href="?page=sandbox_theme_options&tab=social_options" class="nav-tab">Опции социальных сетей</a>
        </h2>
  
        <!-- Создаем форму, которая будет использоваться для вывода наших опций -->  
        <form method="post" action="options.php">  
            <?php  
                  
                if( $active_tab == 'display_options' ) {  
                    settings_fields( 'sandbox_theme_display_options' );  
                    do_settings_sections( 'sandbox_theme_display_options' );  
                } else {  
                    settings_fields( 'sandbox_theme_social_options' );  
                    do_settings_sections( 'sandbox_theme_social_options' );  
                } // Конец конструкции if/else  
                  
                submit_button();  
                  
            ?>  
        </form>
  
    </div> <!-- Конец контейнера «wrap» -->  
<?php  
} // Конец функции sandbox_theme_display

Но это еще не все. Хотя мы настроили вывод опций социальных сетей, но не вызвали функцию с использованием аргументов. Для этого нужно переопределить функцию add_submenu_page. На данный момент функция выглядит так:

add_submenu_page(  
        'sandbox_theme_menu',  
        'Опции социальных сетей',  
        'Опции социальных сетей',  
        'administrator',  
        'sandbox_theme_social_options',  
        'sandbox_theme_display'
    );

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

add_submenu_page(  
    'sandbox_theme_menu',  
    'Social Options',  
    'Social Options',  
    'administrator',  
    'sandbox_theme_social_options',  
    create_function( null, 'sandbox_theme_display( "social_options" );' )  
);

Если вы новичок в PHP, то прочитайте о функции create_function, а также об анонимных функциях. Это очень мощные инструменты, хотя их рассмотрение и выходит за рамки данной статьи.

Итоговый вид функции sandbox_example_theme_menu выглядит так:

function sandbox_example_theme_menu() {  
  
    add_theme_page(  
        'Тема Sandbox',             // Текст в заголовке браузера  
        'Тема Sandbox',             // Текст самого пункта меню в боковом меню WordPress  
        'administrator',            // Группы пользователей, имеющих доступ к данному меню  
        'sandbox_theme_options',    // Уникальный ID - псевдоним – для данного пункта меню  
        'sandbox_theme_display'     // Имя функции, используемой для вывода страницы пункта меню на экран   
    );

    add_menu_page(  
        'Тема Sandbox',             // Текст, выводимый в заголовке браузера  
        'Тема Sandbox',             // Текст, выводимый в названии пункта меню  
        'administrator',            // Группа пользователей, имеющих доступ к данному пункту меню  
        'sandbox_theme_menu',       // Идентификатор, используемый для создания подменю   
        'sandbox_theme_display'     // Callback-функция, используемая для вывода страницы данного меню  
    );

    add_submenu_page(  
        'sandbox_theme_menu',               // Уникальный ID пункта меню верхнего уровня, которому принадлежит данный подпункт  
        'Опции отображения',                // Текст, выводимый в заголовке браузера  
        'Опции отображения',                // Текст, выводимый в названии пункта меню
        'administrator',                    // Группа пользователей, имеющих доступ к данному пункту меню 
        'sandbox_theme_display_options',    // Идентификатор, используемый для создания данного пункта внутри меню 
        'sandbox_theme_display'             // Callback-функция, используемая для вывода страницы данного меню 
    );
  
    add_submenu_page(  
        'sandbox_theme_menu',  
        'Опции социальных сетей',  
        'Опции социальных сетей',  
        'administrator',  
        'sandbox_theme_social_options',  
        create_function( null, 'sandbox_theme_display( "social_options" );' )
    );

}  // Конец функции sandbox_example_theme_menu

add_action('admin_menu', 'sandbox_example_theme_menu');

Заключение

На данный момент, в нашей теме имеются подпункты для каждой закладки, доступные из меню верхнего уровня. Важно заметить, что имеется множество мнений о том, как создавать меню в административной панели WordPress.

Хорошо спроектированная система меню может улучшить ваш продукт, но при неправильном подходе она также может запутать пользователя, смешавшись со стандартными пунктами меню, либо позиция ваших пунктов может быть замещена сторонними дополнениями.

Нет абсолютно правильного или абсолютно неправильного способа создания меню, просто нужно быть внимательным и осторожным в размещении ваших пунктов. Если одно из имеющихся в WordPress меню подходит по смыслу, то помещайте подменю туда.

В следующей статье, мы поговорим о различных элементах ввода, с помощью которых могут быть представлены опции в теме WordPress, а также как производить валидацию и очистку данных до их сериализации (помещения в базу данных).

Перевод статьи «The Complete Guide To The WordPress Settings API, Part 6: Menu Pages» был подготовлен дружной командой проекта Сайтостроение от А до Я.