Intereting Posts
Пользовательские канонические URL-адреса Использование Subversion для развертывания WordPress Поиск и фильтр-плагин – Как отключить перенаправление Как прокомментировать тему WordPress? Локально? Через FTP? Выбор новой и редактируемой страницы для пользовательских типов сообщений Страница с сообщениями из категории не работает Изменить пользовательский подменю Как отображать только сообщения верхнего уровня в цикле через WP_Query? Данные тестовой единицы темы. Иностранные шрифты зашли на мою машину pingback возвращает faultCode 0, нет сообщения Самые комментируемые последние 24 часа, неделя, месяц, год и все время – posts_where Обновление с помощью $ qpdb-> query () всегда возвращает 0 строк Помогите изменить текст для нового уведомления веб-сайта (wpmu_welcome_notification) Как принудительно обновлять содержимое страницы, загруженной ранее пользователем? Могу ли я использовать тот же textdomain в двух отдельных плагинах?

API настроек с примером массивов

Я использую книгу разработки плагинов Wrox WordPress в качестве основной ссылки для начала работы с новым плагином, и я понимаю, что все настройки можно сохранить как 1 массив, но книга не дает примера этого и всего, что я делаю поиск в Интернете кажется настолько отличным от одного примера к другому. Вторая половина поста Константина меня закрыла, но мне бы хотелось увидеть более полный пример с несколькими полями.

Solutions Collecting From Web of "API настроек с примером массивов"

Короткий ответ: ваши значения атрибутов name должны использовать схему option_name[array_key] . Итак, когда вы используете …

 <input name="option_name[key1]"> <input name="option_name[key2]"> 

… вы получаете массив как значение параметра в своей функции проверки:

 array ( 'key1' => 'some value', 'key2' => 'some other value' ) 

PHP делает это для вас, это не функция WordPress. 🙂

Как сделать эту работу с API настроек?

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

введите описание изображения здесь

Страница параметров

Нам нужен крючок admin_menu и две функции: одна для регистрации страницы, одна для рендеринга вывода.

 add_action( 'admin_menu', 't5_sae_add_options_page' ); function t5_sae_add_options_page() { add_options_page( 'T5 Settings API Example', // $page_title, 'T5 SAE', // $menu_title, 'manage_options', // $capability, 't5_sae_slug', // $menu_slug 't5_sae_render_page' // Callback ); } function t5_sae_render_page() { ?> <div class="wrap"> <h2><?php print $GLOBALS['title']; ?></h2> <form action="options.php" method="POST"> <?php settings_fields( 'plugin:t5_sae_option_group' ); do_settings_sections( 't5_sae_slug' ); submit_button(); ?> </form> </div> <?php } 

Действие формы должно быть options.php , или валидация не будет вызываться. Посмотрите на источник PHP wp-admin/options-permalink.php – есть скрытая ловушка do_settings_sections('permalink'); – но он не может работать, потому что action формы неверно.

Теперь вернемся к нашей странице. Мы делаем это лучше, чем WordPress.

Настройки, разделы и поля регистрации

Мы подключаемся к admin_init когда нам это нужно, и вызываем функцию регистрации.

 if ( ! empty ( $GLOBALS['pagenow'] ) and ( 'options-general.php' === $GLOBALS['pagenow'] or 'options.php' === $GLOBALS['pagenow'] ) ) { add_action( 'admin_init', 't5_sae_register_settings' ); } 

Важная часть здесь: $GLOBALS['pagenow'] должен быть либо options-general.php (для вывода), либо options.php (для проверки). Не вызывайте весь следующий код для каждого запроса. Большинство учебников и почти всех плагинов ошибаются.

Хорошо, давайте регистрироваться как сумасшедшие:

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

  2. Мы регистрируем группу настроек с именем plugin:t5_sae_option_group . Мне нравятся префиксные имена, их легче сортировать и понимать таким образом.

  3. Затем мы регистрируем два раздела: 1 и 2.

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

 function t5_sae_register_settings() { $option_name = 'plugin:t5_sae_option_name'; // Fetch existing options. $option_values = get_option( $option_name ); $default_values = array ( 'number' => 500, 'color' => 'blue', 'long' => '' ); // Parse option values into predefined keys, throw the rest away. $data = shortcode_atts( $default_values, $option_values ); register_setting( 'plugin:t5_sae_option_group', // group, used for settings_fields() $option_name, // option name, used as key in database 't5_sae_validate_option' // validation callback ); /* No argument has any relation to the prvious register_setting(). */ add_settings_section( 'section_1', // ID 'Some text fields', // Title 't5_sae_render_section_1', // print output 't5_sae_slug' // menu slug, see t5_sae_add_options_page() ); add_settings_field( 'section_1_field_1', 'A Number', 't5_sae_render_section_1_field_1', 't5_sae_slug', // menu slug, see t5_sae_add_options_page() 'section_1', array ( 'label_for' => 'label1', // makes the field name clickable, 'name' => 'number', // value for 'name' attribute 'value' => esc_attr( $data['number'] ), 'option_name' => $option_name ) ); add_settings_field( 'section_1_field_2', 'Select', 't5_sae_render_section_1_field_2', 't5_sae_slug', // menu slug, see t5_sae_add_options_page() 'section_1', array ( 'label_for' => 'label2', // makes the field name clickable, 'name' => 'color', // value for 'name' attribute 'value' => esc_attr( $data['color'] ), 'options' => array ( 'blue' => 'Blue', 'red' => 'Red', 'black' => 'Black' ), 'option_name' => $option_name ) ); add_settings_section( 'section_2', // ID 'Textarea', // Title 't5_sae_render_section_2', // print output 't5_sae_slug' // menu slug, see t5_sae_add_options_page() ); add_settings_field( 'section_2_field_1', 'Notes', 't5_sae_render_section_2_field_1', 't5_sae_slug', // menu slug, see t5_sae_add_options_page() 'section_2', array ( 'label_for' => 'label3', // makes the field name clickable, 'name' => 'long', // value for 'name' attribute 'value' => esc_textarea( $data['long'] ), 'option_name' => $option_name ) ); } 

Все эти обработчики обратного вызова для разделов и полей будут вызываться автоматически, когда мы вызываем do_settings_sections( 't5_sae_slug' ); на нашей странице. Мы сделали это уже, поэтому нам нужно просто …

Печать полей

Обратите внимание, как создаются атрибуты name : переданное option_name – это первая часть, ключ массива следует в квадратных скобках [] .

 function t5_sae_render_section_1() { print '<p>Pick a number between 1 and 1000, and choose a color.</p>'; } function t5_sae_render_section_1_field_1( $args ) { /* Creates this markup: /* <input name="plugin:t5_sae_option_name[number]" */ printf( '<input name="%1$s[%2$s]" id="%3$s" value="%4$s" class="regular-text">', $args['option_name'], $args['name'], $args['label_for'], $args['value'] ); // t5_sae_debug_var( func_get_args(), __FUNCTION__ ); } function t5_sae_render_section_1_field_2( $args ) { printf( '<select name="%1$s[%2$s]" id="%3$s">', $args['option_name'], $args['name'], $args['label_for'] ); foreach ( $args['options'] as $val => $title ) printf( '<option value="%1$s" %2$s>%3$s</option>', $val, selected( $val, $args['value'], FALSE ), $title ); print '</select>'; // t5_sae_debug_var( func_get_args(), __FUNCTION__ ); } function t5_sae_render_section_2() { print '<p>Makes some notes.</p>'; } function t5_sae_render_section_2_field_1( $args ) { printf( '<textarea name="%1$s[%2$s]" id="%3$s" rows="10" cols="30" class="code">%4$s</textarea>', $args['option_name'], $args['name'], $args['label_for'], $args['value'] ); } 

О, я ввел функцию t5_sae_debug_var() . Вот:

 function t5_sae_debug_var( $var, $before = '' ) { $export = esc_html( var_export( $var, TRUE ) ); print "<pre>$before = $export</pre>"; } 

Полезно узнать, получили ли мы то, что ожидали.

Теперь это работает очень хорошо, нам нужно только одно:

Проверка массива параметров

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

 function t5_sae_validate_option( $values ) { $default_values = array ( 'number' => 500, 'color' => 'blue', 'long' => '' ); if ( ! is_array( $values ) ) // some bogus data return $default_values; $out = array (); foreach ( $default_values as $key => $value ) { if ( empty ( $values[ $key ] ) ) { $out[ $key ] = $value; } else { if ( 'number' === $key ) { if ( 0 > $values[ $key ] ) add_settings_error( 'plugin:t5_sae_option_group', 'number-too-low', 'Number must be between 1 and 1000.' ); elseif ( 1000 < $values[ $key ] ) add_settings_error( 'plugin:t5_sae_option_group', 'number-too-high', 'Number must be between 1 and 1000.' ); else $out[ $key ] = $values[ $key ]; } elseif ( 'long' === $key ) { $out[ $key ] = trim( $values[ $key ] ); } else { $out[ $key ] = $values[ $key ]; } } } return $out; } 

Это довольно уродливо; Я бы не использовал такой код в производстве. Но он делает то, что должен: он возвращает проверенный массив значений. WordPress будет сериализовать массив, сохранить его под нашим именем параметра в базе данных и вернуть его неэтериализованным, когда мы вызываем get_option() .


Все это работает, но это излишне сложно, мы получаем разметку с 1998 года ( <tr valign="top"> ) и много избыточности.

Используйте API настроек, когда это необходимо. Как альтернативное использование admin_url( 'admin-post.php' ) качестве действия формы (посмотрите на его источник) и создайте полную страницу настроек со своим, вероятно, более элегантным кодом.

Фактически, вы должны это делать, когда пишете сетевой плагин, потому что API настроек там не работает.

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