Статьи

API настроек WordPress, часть 4: параметры темы

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

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

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

Примечание автора: эта статья проведет вас через процесс введения нового раздела настроек для параметров темы, но статья не завершает процесс — пожалуйста, прочитайте больше в этой ветке комментариев . Знайте, что я знаю об этом, я прошу прощения за то, что не разъяснил это в статье, и у меня будет полная рабочая версия в следующей статье позже в этом месяце!


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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function sandbox_example_plugin_menu() {
 
    add_plugins_page(
        ‘Sandbox Plugin’, // The title to be displayed in the browser window for this page.
        ‘Sandbox Plugin’, // The text to be displayed for this menu item
        ‘administrator’, // Which type of users can see this menu item
        ‘sandbox_plugin_options’, // The unique ID — that is, the slug — for this menu item
        ‘sandbox_plugin_display’ // The name of the function to call when rendering this menu’s page
    );
 
} // end sandbox_example_theme_menu
add_action(‘admin_menu’, ‘sandbox_example_plugin_menu’);
 
function sandbox_plugin_display() {
 
    // Create a header in the default WordPress ‘wrap’ container
    $html = ‘<div class=»wrap»>’;
        $html .= ‘<h2>Sandbox Plugin Options</h2>’;
        $html .= ‘<p class=»description»>There are currently no options.
    $html .= ‘</div>’;
     
    // Send the markup to the browser
    echo $html;
     
} // end sandbox_plugin_display

Удалите его из functions.php .

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function sandbox_create_menu_page() {
 
    add_menu_page(
        ‘Sandbox Options’, // The title to be displayed on this menu’s corresponding page
        ‘Sandbox’, // The text to be displayed for this actual menu item
        ‘administrator’, // Which type of users can see this menu
        ‘sandbox’, // The unique ID — that is, the slug — for this menu item
        ‘sandbox_menu_page_display’,// The name of the function to call when rendering this menu’s page
        »
    );
     
    add_submenu_page(
        ‘sandbox’, // Register this submenu with the menu defined above
        ‘Sandbox Options’, // The text to the display in the browser when this menu item is active
        ‘Options’, // The text for this menu item
        ‘administrator’, // Which type of users can see this menu
        ‘sandbox_options’, // The unique ID — the slug — for this menu item
        ‘sandbox_options_display’ // The function used to render this menu’s page to the screen
    );
 
} // end sandbox_create_menu_page
add_action(‘admin_menu’, ‘sandbox_create_menu_page’);
 
function sandbox_menu_page_display() {
     
    // Create a header in the default WordPress ‘wrap’ container
    $html = ‘<div class=»wrap»>’;
        $html .= ‘<h2>Sandbox</h2>’;
    $html .= ‘</div>’;
     
    // Send the markup to the browser
    echo $html;
     
} // end sandbox_menu_page_display
 
function sandbox_options_display() {
 
    // Create a header in the default WordPress ‘wrap’ container
    $html = ‘<div class=»wrap»>’;
        $html .= ‘<h2>Sandbox Options</h2>’;
    $html .= ‘</div>’;
     
    // Send the markup to the browser
    echo $html;
     
} // end sandbox_options_display

На этом этапе у вас должны остаться две особые функции в области администрирования WordPress, которые мы создали:

  • Элемент меню «Тема песочницы» в меню « Внешний вид» .
  • Набор из трех опций в разделе «Общие» в меню « Настройки» .

Если вы видите эти два варианта, вам пора; в противном случае убедитесь, что ваш functions.php выглядит следующим образом:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
function sandbox_example_theme_menu() {
 
    add_theme_page(
        ‘Sandbox Theme’, // The title to be displayed in the browser window for this page.
        ‘Sandbox Theme’, // The text to be displayed for this menu item
        ‘administrator’, // Which type of users can see this menu item
        ‘sandbox_theme_options’, // The unique ID — that is, the slug — for this menu item
        ‘sandbox_theme_display’ // The name of the function to call when rendering this menu’s page
    );
 
} // end sandbox_example_theme_menu
add_action(‘admin_menu’, ‘sandbox_example_theme_menu’);
 
function sandbox_theme_display() {
 
    // Create a header in the default WordPress ‘wrap’ container
    $html = ‘<div class=»wrap»>’;
        $html .= ‘<h2>Sandbox Theme Options</h2>’;
        $html .= ‘<p class=»description»>There are currently no options.
    $html .= ‘</div>’;
     
    // Send the markup to the browser
    echo $html;
     
} // end sandbox_theme_display
 
/* ———————————————————————— *
 * Setting Registration
 * ———————————————————————— */
  
function sandbox_initialize_theme_options() {
 
    // First, we register a section.
    add_settings_section(
        ‘general_settings_section’, // ID used to identify this section and with which to register options
        ‘Sandbox Options’, // Title to be displayed on the administration page
        ‘sandbox_general_options_callback’, // Callback used to render the description of the section
        ‘general’ // Page on which to add this section of options
    );
     
    // Next, we’ll introduce the fields for toggling the visibility of content elements.
    add_settings_field(
        ‘show_header’, // ID used to identify the field throughout the theme
        ‘Header’, // The label to the left of the option interface element
        ‘sandbox_toggle_header_callback’, // The name of the function responsible for rendering the option interface
        ‘general’, // The page on which this option will be displayed
        ‘general_settings_section’, // The name of the section to which this field belongs
        array( // The array of arguments to pass to the callback. In this case, just a description.
            ‘Activate this setting to display the header.’
        )
    );
     
    add_settings_field(
        ‘show_content’,
        ‘Content’,
        ‘sandbox_toggle_content_callback’,
        ‘general’,
        ‘general_settings_section’,
        array(
            ‘Activate this setting to display the content.’
        )
    );
     
    add_settings_field(
        ‘show_footer’,
        ‘Footer’,
        ‘sandbox_toggle_footer_callback’,
        ‘general’,
        ‘general_settings_section’,
        array(
            ‘Activate this setting to display the footer.’
        )
    );
     
    // Finally, we register the fields with WordPress
     
    register_setting(
        ‘general’,
        ‘show_header’
    );
     
    register_setting(
        ‘general’,
        ‘show_content’
    );
     
    register_setting(
        ‘general’,
        ‘show_footer’
    );
     
} // end sandbox_initialize_theme_options
add_action(‘admin_init’, ‘sandbox_initialize_theme_options’);
 
/* ———————————————————————— *
 * Section Callbacks
 * ———————————————————————— */
 
function sandbox_general_options_callback() {
    echo ‘<p>Select which areas of content you wish to display.</p>’;
} // end sandbox_general_options_callback
 
/* ———————————————————————— *
 * Field Callbacks
 * ———————————————————————— */
 
function sandbox_toggle_header_callback($args) {
     
    // Note the ID and the name attribute of the element match that of the ID in the call to add_settings_field
    $html = ‘<input type=»checkbox» id=»show_header» name=»show_header» value=»1″ ‘ .
     
    // Here, we’ll take the first argument of the array and add it to a label next to the checkbox
    $html .= ‘<label for=»show_header»> ‘ .
     
    echo $html;
     
} // end sandbox_toggle_header_callback
 
function sandbox_toggle_content_callback($args) {
 
    $html = ‘<input type=»checkbox» id=»show_content» name=»show_content» value=»1″ ‘ .
    $html .= ‘<label for=»show_content»> ‘ .
     
    echo $html;
     
} // end sandbox_toggle_content_callback
 
function sandbox_toggle_footer_callback($args) {
     
    $html = ‘<input type=»checkbox» id=»show_footer» name=»show_footer» value=»1″ ‘ .
    $html .= ‘<label for=»show_footer»> ‘ .
     
    echo $html;
     
} // end sandbox_toggle_footer_callback

На данный момент, мы готовы начать.


Прежде чем писать какой-либо код, важно спланировать, что мы будем делать. К этому моменту мы написали несколько полезных функций — мы даем пользователям возможность переключать видимость областей верхнего и нижнего колонтитула. Дело в том, что параметры в данный момент находятся на странице «Общие» меню « Настройки» . Поскольку мы работаем над темой, мы должны включить ее на страницу настроек нашей темы.

Кроме того, этих трех вариантов недостаточно для полезной темы. Пользователи часто размещают свои социальные сети в своем блоге, поэтому давайте планируем дать пользователям возможность добавлять ссылки на свои учетные записи в Twitter, Facebook и Google+.

Имея это в виду, мы можем планировать следующие два раздела:

  • Показать варианты
    • заголовок
    • содержание
    • нижний колонтитул
  • Социальные параметры
    • щебет
    • facebook
    • Google+

Чтобы сделать еще один шаг вперед, мы добавим эти параметры на страницу параметров темы песочницы, доступ к которой можно получить из меню « Внешний вид» . Кроме того, каждый раздел будет доступен через собственную вкладку в навигации по странице.


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

01
02
03
04
05
06
07
08
09
10
11
12
function sandbox_theme_display() {
 
    // Create a header in the default WordPress ‘wrap’ container
    $html = ‘<div class=»wrap»>’;
        $html .= ‘<h2>Sandbox Theme Options</h2>’;
        $html .= ‘<p class=»description»>There are currently no options.
    $html .= ‘</div>’;
 
    // Send the markup to the browser
    echo $html;
 
} // end sandbox_theme_display

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

  • Присвойте странице параметров значок, чтобы внешний вид более соответствовал внешнему виду WordPress.
  • Удалить описание страницы
  • Измените PHP-строку HTML в HTML-блок, чтобы облегчить поддержание сверхурочной работы.
  • Ввести функцию отображения ошибок настроек
  • Создайте форму, которая будет использоваться для размещения наших вариантов

Это относительно прямо вперед. В этом случае код гораздо лучше объясняет, что мы делаем, пытаясь разбить его на строки. Просмотрите приведенный ниже код, обращая пристальное внимание на комментарии, а затем убедитесь, что ваш обратный вызов выглядит так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
function sandbox_theme_display() {
?>
    <!— Create a header in the default WordPress ‘wrap’ container —>
    <div class=»wrap»>
 
        <!— Add the icon to the page —>
        <div id=»icon-themes» class=»icon32″></div>
        <h2>Sandbox Theme Options</h2>
 
        <!— Make a call to the WordPress function for rendering errors when settings are saved.
        <?php settings_errors();
 
        <!— Create the form that will be used to render our options —>
        <form method=»post» action=»options.php»>
            <?php settings_fields( ‘general’ );
            <?php do_settings_sections( ‘general’ );
            <?php submit_button();
        </form>
 
    </div><!— /.wrap —>
<?php
} // end sandbox_theme_display

Разрешение всего вашего кода корректно, ваша страница настроек должна выглядеть так:

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

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

Для этого добавьте следующий блок кода в качестве первой строки в функцию sandbox_initialize_theme_options :

1
2
3
if( false == get_option( ‘sandbox_theme_display_options’ ) ) {
    add_option( ‘sandbox_theme_display_options’ );
} // end if

Найдите вызов add_settings_section и запомните аргумент title. Прямо сейчас это должно выглядеть так:

1
2
3
4
5
6
add_settings_section(
    ‘general_settings_section’, // ID used to identify this section and with which to register options
    ‘Sandbox Options’, // Title to be displayed on the administration page
    ‘sandbox_general_options_callback’, // Callback used to render the description of the section
    ‘general’ // Page on which to add this section of options
);

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

1
2
3
4
5
6
add_settings_section(
    ‘general_settings_section’, // ID used to identify this section and with which to register options
    ‘Display Options’, // Title to be displayed on the administration page
    ‘sandbox_general_options_callback’, // Callback used to render the description of the section
    ‘sandbox_theme_display_options’ // Page on which to add this section of options
);

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

1
2
3
4
5
6
add_settings_section(
    ‘general_settings_section’, // ID used to identify this section and with which to register options
    ‘Display Options’, // Title to be displayed on the administration page
    ‘sandbox_general_options_callback’, // Callback used to render the description of the section
    ‘sandbox_theme_display_options’ // Page on which to add this section of options
);

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

01
02
03
04
05
06
07
08
09
10
add_settings_field(
    ‘show_header’, // ID used to identify the field throughout the theme
    ‘Header’, // The label to the left of the option interface element
    ‘sandbox_toggle_header_callback’, // The name of the function responsible for rendering the option interface
    ‘general’, // The page on which this option will be displayed
    ‘general_settings_section’, // The name of the section to which this field belongs
    array( // The array of arguments to pass to the callback. In this case, just a description.
        ‘Activate this setting to display the header.’
    )
);

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
add_settings_field(
    ‘show_header’, // ID used to identify the field throughout the theme
    ‘Header’, // The label to the left of the option interface element
    ‘sandbox_toggle_header_callback’, // The name of the function responsible for rendering the option interface
    ‘sandbox_theme_display_options’, // The page on which this option will be displayed
    ‘general_settings_section’, // The name of the section to which this field belongs
    array( // The array of arguments to pass to the callback. In this case, just a description.
        ‘Activate this setting to display the header.’
    )
);
 
add_settings_field(
    ‘show_content’,
    ‘Content’,
    ‘sandbox_toggle_content_callback’,
    ‘sandbox_theme_display_options’,
    ‘general_settings_section’,
    array(
        ‘Activate this setting to display the content.’
    )
);
 
add_settings_field(
    ‘show_footer’,
    ‘Footer’,
    ‘sandbox_toggle_footer_callback’,
    ‘sandbox_theme_display_options’,
    ‘general_settings_section’,
    array(
        ‘Activate this setting to display the footer.’
    )
);

До этого момента мы регистрировали каждую опцию индивидуально с настройками на общей странице:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
register_setting(
    ‘general’,
    ‘show_header’
);
 
register_setting(
    ‘general’,
    ‘show_content’
);
 
register_setting(
    ‘general’,
    ‘show_footer’
);

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

1
2
3
4
register_setting(
    ‘sandbox_theme_display_options’,
    ‘sandbox_theme_display_options’
);

Это, пожалуй, самая сложная идея для понимания. Вспомните из второй статьи серии, что настройки представляют собой комбинацию полей и разделов, к которым они принадлежат. Поскольку все наши поля принадлежат одному и тому же разделу — опциям отображения — мы регистрируем этот раздел в WordPress.

Не пропустите это: до этого момента наши параметры сохранялись как отдельные настройки в базе данных. Это означает, что мы можем просто искать их по их идентификатору (например, get_option('show_header'); , но, поскольку мы добавили их в пользовательский раздел, они являются частью набора параметров. Это означает, что прочитав наши параметры, мы должны сначала получить доступ к коллекции параметров, а затем запросить отдельный параметр для коллекции.

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

1
2
3
4
5
6
7
8
function sandbox_toggle_header_callback($args) {
     
    $html = ‘<input type=»checkbox» id=»show_header» name=»show_header» value=»1″ ‘ .
    $html .= ‘<label for=»show_header»> ‘ .
     
    echo $html;
     
} // end sandbox_toggle_header_callback

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

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
function sandbox_toggle_header_callback($args) {
     
    // First, we read the options collection
    $options = get_option(‘sandbox_theme_display_options’);
     
    // Next, we update the name attribute to access this element’s ID in the context of the display options array
    // We also access the show_header element of the options collection in the call to the checked() helper function
    $html = ‘<input type=»checkbox» id=»show_header» name=»sandbox_theme_display_options[show_header]» value=»1″ ‘ .
     
    // Here, we’ll take the first argument of the array and add it to a label next to the checkbox
    $html .= ‘<label for=»show_header»> ‘ .
     
    echo $html;
     
} // end sandbox_toggle_header_callback

Достаточно просто, правда? Поскольку у нас есть три элемента, нам нужно внести соответствующие изменения в каждый из элементов. Каждая функция будет выглядеть почти одинаково, за исключением имени опции. Вместо show_header он будет читать show_content или show_footer .

После этого окончательная версия трех элементов формы должна выглядеть следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function sandbox_toggle_header_callback($args) {
 
    $options = get_option(‘sandbox_theme_display_options’);
 
    $html = ‘<input type=»checkbox» id=»show_header» name=»sandbox_theme_display_options[show_header]» value=»1″ ‘ .
    $html .= ‘<label for=»show_header»> ‘ .
 
    echo $html;
 
} // end sandbox_toggle_header_callback
 
function sandbox_toggle_content_callback($args) {
 
    $options = get_option(‘sandbox_theme_display_options’);
 
    $html = ‘<input type=»checkbox» id=»show_content» name=»sandbox_theme_display_options[show_content]» value=»1″ ‘ .
    $html .= ‘<label for=»show_content»> ‘ .
 
    echo $html;
 
} // end sandbox_toggle_content_callback
 
function sandbox_toggle_footer_callback($args) {
 
    $options = get_option(‘sandbox_theme_display_options’);
 
    $html = ‘<input type=»checkbox» id=»show_footer» name=»sandbox_theme_display_options[show_footer]» value=»1″ ‘ .
    $html .= ‘<label for=»show_footer»> ‘ .
 
    echo $html;
 
} // end sandbox_toggle_footer_callback

Наконец, мы готовы отобразить параметры на нашей странице параметров новой темы. Это простой вопрос вызова двух функций в API настроек:

  1. settings_fields заботится о предоставлении нескольких мер безопасности для формы параметров.
  2. do_settings_sections фактически отображает параметры на странице.

Каждая функция берет идентификатор страницы, которую мы будем отображать. В нашем случае это sandbox_theme_display_options . Чтобы отобразить наши параметры, мы обновляем form так:

1
2
3
4
5
<form method=»post» action=»options.php»>
       <?php settings_fields( ‘sandbox_theme_display_options’ );
       <?php do_settings_sections( ‘sandbox_theme_display_options’ );
       <?php submit_button();
   </form>

На этом этапе вы сможете обновить страницу параметров темы песочницы и увидеть наши три варианта, представленные следующим образом:

Параметры отображения темы песочницы

Окончательная версия вашего functions.php должна выглядеть следующим образом:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
 
function sandbox_example_theme_menu() {
 
    add_theme_page(
        ‘Sandbox Theme’, // The title to be displayed in the browser window for this page.
        ‘Sandbox Theme’, // The text to be displayed for this menu item
        ‘administrator’, // Which type of users can see this menu item
        ‘sandbox_theme_options’, // The unique ID — that is, the slug — for this menu item
        ‘sandbox_theme_display’ // The name of the function to call when rendering this menu’s page
    );
 
} // end sandbox_example_theme_menu
add_action( ‘admin_menu’, ‘sandbox_example_theme_menu’ );
 
/**
 * Renders a simple page to display for the theme menu defined above.
 */
function sandbox_theme_display() {
?>
    <!— Create a header in the default WordPress ‘wrap’ container —>
    <div class=»wrap»>
     
        <div id=»icon-themes» class=»icon32″></div>
        <h2>Sandbox Theme Options</h2>
        <?php settings_errors();
         
        <form method=»post» action=»options.php»>
            <?php settings_fields( ‘sandbox_theme_display_options’ );
            <?php do_settings_sections( ‘sandbox_theme_display_options’ );
            <?php submit_button();
        </form>
         
    </div><!— /.wrap —>
<?php
} // end sandbox_theme_display
 
function sandbox_initialize_theme_options() {
 
    // If the theme options don’t exist, create them.
    if( false == get_option( ‘sandbox_theme_display_options’ ) ) {
        add_option( ‘sandbox_theme_display_options’ );
    } // end if
 
    // First, we register a section.
    add_settings_section(
        ‘general_settings_section’, // ID used to identify this section and with which to register options
        ‘Display Options’, // Title to be displayed on the administration page
        ‘sandbox_general_options_callback’, // Callback used to render the description of the section
        ‘sandbox_theme_display_options’ // Page on which to add this section of options
    );
     
    // Next, we’ll introduce the fields for toggling the visibility of content elements.
    add_settings_field(
        ‘show_header’, // ID used to identify the field throughout the theme
        ‘Header’, // The label to the left of the option interface element
        ‘sandbox_toggle_header_callback’, // The name of the function responsible for rendering the option interface
        ‘sandbox_theme_display_options’, // The page on which this option will be displayed
        ‘general_settings_section’, // The name of the section to which this field belongs
        array( // The array of arguments to pass to the callback. In this case, just a description.
            ‘Activate this setting to display the header.’
        )
    );
     
    add_settings_field(
        ‘show_content’,
        ‘Content’,
        ‘sandbox_toggle_content_callback’,
        ‘sandbox_theme_display_options’,
        ‘general_settings_section’,
        array(
            ‘Activate this setting to display the content.’
        )
    );
     
    add_settings_field(
        ‘show_footer’,
        ‘Footer’,
        ‘sandbox_toggle_footer_callback’,
        ‘sandbox_theme_display_options’,
        ‘general_settings_section’,
        array(
            ‘Activate this setting to display the footer.’
        )
    );
     
    // Finally, we register the fields with WordPress
    register_setting(
        ‘sandbox_theme_display_options’,
        ‘sandbox_theme_display_options’
    );
     
} // end sandbox_initialize_theme_options
add_action(‘admin_init’, ‘sandbox_initialize_theme_options’);
 
function sandbox_general_options_callback() {
    echo ‘<p>Select which areas of content you wish to display.</p>’;
} // end sandbox_general_options_callback
 
function sandbox_toggle_header_callback($args) {
     
    // First, we read the options collection
    $options = get_option(‘sandbox_theme_display_options’);
     
    // Next, we update the name attribute to access this element’s ID in the context of the display options array
    // We also access the show_header element of the options collection in the call to the checked() helper function
    $html = ‘<input type=»checkbox» id=»show_header» name=»sandbox_theme_display_options[show_header]» value=»1″ ‘ .
     
    // Here, we’ll take the first argument of the array and add it to a label next to the checkbox
    $html .= ‘<label for=»show_header»> ‘ .
     
    echo $html;
     
} // end sandbox_toggle_header_callback
 
function sandbox_toggle_content_callback($args) {
 
    $options = get_option(‘sandbox_theme_display_options’);
     
    $html = ‘<input type=»checkbox» id=»show_content» name=»sandbox_theme_display_options[show_content]» value=»1″ ‘ .
    $html .= ‘<label for=»show_content»> ‘ .
     
    echo $html;
     
} // end sandbox_toggle_content_callback
 
function sandbox_toggle_footer_callback($args) {
     
    $options = get_option(‘sandbox_theme_display_options’);
     
    $html = ‘<input type=»checkbox» id=»show_footer» name=»sandbox_theme_display_options[show_footer]» value=»1″ ‘ .
    $html .= ‘<label for=»show_footer»> ‘ .
     
    echo $html;
     
} // end sandbox_toggle_footer_callback
?>

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

В соответствии с нашим обычным процессом, давайте точно спланируем, что будем делать:

  • Нам нужно создать новый раздел полей
  • Будут добавлены три поля: одно для Facebook, одно для Twitter и одно для Google+
  • Нам нужно обновить страницу параметров, чтобы отобразить эти новые параметры.

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

Вот начальная функция. Обратите внимание на комментарии, а также!

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
/**
 * Initializes the theme’s social options by registering the Sections,
 * Fields, and Settings.
 *
 * This function is registered with the ‘admin_init’ hook.
 */
function sandbox_theme_intialize_social_options() {
 
    // If the social options don’t exist, create them.
    if( false == get_option( ‘sandbox_theme_social_options’ ) ) {
        add_option( ‘sandbox_theme_social_options’ );
    } // end if
 
} // end sandbox_theme_intialize_social_options
add_action( ‘admin_init’, ‘sandbox_theme_intialize_social_options’ );

Далее нам нужно добавить новый раздел для настроек. Это делается сразу после кода выше:

1
2
3
4
5
6
add_settings_section(
    ‘social_settings_section’, // ID used to identify this section and with which to register options
    ‘Social Options’, // Title to be displayed on the administration page
    ‘sandbox_social_options_callback’, // Callback used to render the description of the section
    ‘sandbox_theme_social_options’ // Page on which to add this section of options
);

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

1
2
3
function sandbox_social_options_callback() {
    echo ‘<p>Provide the URL to the social networks you\’d like to display.</p>’;
} // end sandbox_general_options_callback

На этом этапе мы можем проверить работоспособность, чтобы убедиться, что раздел был правильно зарегистрирован в API настроек. Вернитесь в функцию sandbox_theme_display и добавьте следующие две строки в элемент формы. Они могут идти прямо под своим аналогом sandbox_theme_display_options :

1
2
<?php settings_fields( ‘sandbox_theme_social_options’ );
<?php do_settings_sections( ‘sandbox_theme_social_options’ );

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

Социальные параметры

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

1
2
3
4
5
6
7
add_settings_field(
    ‘twitter’,
    ‘Twitter’,
    ‘sandbox_twitter_callback’,
    ‘sandbox_theme_social_options’,
    ‘social_settings_section’
);

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
function sandbox_twitter_callback() {
     
    // First, we read the social options collection
    $options = get_option( ‘sandbox_theme_social_options’ );
     
    // Next, we need to make sure the element is defined in the options.
    $url = »;
    if( isset( $options[‘twitter’] ) ) {
        $url = $options[‘twitter’];
    } // end if
     
    // Render the output
    echo ‘<input type=»text» id=»twitter» name=»sandbox_theme_social_options[twitter]» value=»‘ . $options[‘twitter’] . ‘» />’;
     
} // end sandbox_twitter_callback

Наконец, мы возвращаемся в функцию sandbox_theme_intialize_social_options и регистрируем новый параметр в WordPress:

1
2
3
4
5
6
     
register_setting(
    ‘sandbox_theme_social_options’,
    ‘sandbox_theme_social_options’,
    ‘sandbox_theme_sanitize_social_options’
);

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

Итак, давайте продолжим и заглушим функцию:

1
2
function sandbox_theme_sanitize_social_options( $input ) {
} // end sandbox_theme_sanitize_social_options

Обратите внимание, что обратный вызов принимает один аргумент, который мы назвали $ input. Этот аргумент представляет собой набор опций, которые существуют для разделов социальных опций. Поскольку мы разрешаем пользователям вводить необработанный текст в поле ввода, мы должны предотвратить сохранение любого вредоносного кода (такого как JavaScript или SQL).

Для этого нам нужно сделать следующее:

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

Давайте продолжим и напишем код для этого. Обновите функцию, чтобы она выглядела так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
function sandbox_theme_sanitize_social_options( $input ) {
     
    // Define the array for the updated options
    $output = array();
 
    // Loop through each of the options sanitizing the data
    foreach( $input as $key => $val ) {
     
        if( isset ( $input[$key] ) ) {
            $output[$key] = esc_url_raw( strip_tags( stripslashes( $input[$key] ) ) );
        } // end if
     
    } // end foreach
     
    // Return the new collection
    return apply_filters( ‘sandbox_theme_sanitize_social_options’, $output, $input );
 
} // end sandbox_theme_sanitize_social_options

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

  • stripslashes — это встроенная функция PHP, которая будет «заключать в кавычки» строку
  • strip_tags — это еще одна встроенная функция PHP, которая удаляет теги HTML и PHP из строки
  • esc_url_raw — это функция WordPress, которая будет обеспечивать чистый URL

Вышеописанный процесс агрессивен, конечно, но если вы хотите убедиться, что вы разрешаете сохранение только URL-адресов в базе данных, это эффективно.

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

На этом этапе сохраните свою работу и обновите браузер. Ваша страница параметров теперь должна отображать не только параметры отображения, но и первую социальную функцию. Более того, вы сможете указать URL-адрес своего профиля в Twitter и сохранить его в базе данных.

Социальная сеть Twitter

Знакомство с Facebook и Google+ будет происходить точно так же, как и для добавления поддержки Twitter. В основном:

  • Определите поле настроек
  • Настройте обратный звонок

Достаточно просто, правда? Все остальное уже решено благодаря API настроек. Конечно, мы должны быть полными — вот как включить поддержку следующих сетей.

Сначала мы определим два поля настроек:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
add_settings_field(
    ‘facebook’,
    ‘Facebook’,
    ‘sandbox_facebook_callback’,
    ‘sandbox_theme_social_options’,
    ‘social_settings_section’
);
 
add_settings_field(
    ‘googleplus’,
    ‘Google+’,
    ‘sandbox_googleplus_callback’,
    ‘sandbox_theme_social_options’,
    ‘social_settings_section’
);

Далее мы определим их два обратных вызова:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function sandbox_facebook_callback() {
     
    $options = get_option( ‘sandbox_theme_social_options’ );
     
    $url = »;
    if( isset( $options[‘facebook’] ) ) {
        $url = $options[‘facebook’];
    } // end if
     
    // Render the output
    echo ‘<input type=»text» id=»facebook» name=»sandbox_theme_social_options[facebook]» value=»‘ . $options[‘facebook’] . ‘» />’;
     
} // end sandbox_facebook_callback
 
function sandbox_googleplus_callback() {
     
    $options = get_option( ‘sandbox_theme_social_options’ );
     
    $url = »;
    if( isset( $options[‘googleplus’] ) ) {
        $url = $options[‘googleplus’];
    } // end if
     
    // Render the output
    echo ‘<input type=»text» id=»googleplus» name=»sandbox_theme_social_options[googleplus]» value=»‘ . $options[‘googleplus’] . ‘» />’;
     
} // end sandbox_googleplus_callback

Сохраните свою работу и еще раз обновите страницу настроек. Теперь должно быть два дополнительных поля — одно для Facebook и одно для Google+. Не стесняйтесь и их опробовать.

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


Что хорошего в вариантах, если мы не обращаемся к ним на реальном сайте? Прежде чем закончить эту статью, давайте сделаем небольшое обновление шаблона index нашей темы. А именно, нам нужно убедиться, что мы ссылаемся на наши новые опции и представить возможность отображения в социальных сетях:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE html>
<html>
    <head>
        <title>The Complete Guide To The Settings API |
    </head>
    <body>
     
        <?php $display_options = get_option( ‘sandbox_theme_display_options’ );
        <?php $social_options = get_option ( ‘sandbox_theme_social_options’ );
     
        <?php if( $display_options[ ‘show_header’ ] ) { ?>
            <div id=»header»>
                <h1>Sandbox Header</h1>
            </div><!— /#header —>
        <?php } // end if ?>
         
        <?php if( $display_options[ ‘show_content’ ] ) { ?>
            <div id=»content»>
                <?php echo $social_options[‘twitter’] ?
                <?php echo $social_options[‘facebook’] ?
                <?php echo $social_options[‘googleplus’] ?
            </div><!— /#content —>
        <?php } // end if ?>
         
        <?php if( $display_options[ ‘show_footer’ ] ) { ?>
            <div id=»footer»>
                <p>© <?php echo date(‘Y’);
            </div><!— /#footer —>
        <?php } // end if ?>
     
    </body>
</html>

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

А пока что экспериментируйте с тем, что мы уже рассмотрели!

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

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

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