Intereting Posts
удаление программ программным путем Проверьте, есть ли в текущей категории дети Вызов ссылки следующей категории на странице архива – WordPress front-page.php не является листингом в Static Front Page List Как я могу вставлять плагин комментариев на свой собственный сайт? плагин не подключается к моему пользовательскому подключению Скрытые некоторые настройки в сообщении или странице Программа Tv с CPT и настраиваемым полем Buddypress – Пользовательское имя для зарегистрированных пользователей Сообщения в сообщении Как получить таксономические условия по ID в определенном порядке Общая пользовательская таксономия между двумя настраиваемыми типами сообщений сортировать результаты поиска по пользовательским полям, используя раскрывающийся список Вы можете проверить, есть ли в поле Post WYSIWYG изображение? Thumbnail With Next / Prev Links Не показывая следующую запись? Форма контакта WordPress 7 Проверка размера изображения

В чем преимущества API настроек?

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

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

Если я не ошибаюсь, из того, что я понимаю, для использования API настроек требуется создание новой функции PER SETTING. Это означает 3-5 функций для среднего плагина и до сотен для более продвинутых плагинов. Кажется нелепо писать эти многие функции (и разрабатывать систему именования, чтобы не путать их), когда вы могли бы просто импортировать все применимые переменные $_POST в массив и отказаться от всего беспорядка.

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

  function __construct() { /* constructor stuff */ $this->options = $this->db_options = get_option( 'de-menu-options' ); if( $this->options === false ){ $this->options = $this->defaults; } if (is_admin()) { add_action('admin_menu', array(&$this, 'admin_menu')); } /* more stuff */ // When WordPress shuts down we store changes to options add_action('shutdown', array(&$this, 'update')); } public function admin_menu() { add_options_page('DE Menu Options', 'DE Menu', 'manage_options', 'de-menu-options', array(&$this, 'options')); add_option('de-menu-options', $this->options); } public function options() { if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.') ); } if ( !empty($_POST) && check_admin_referer('de-menu-options') ) { // These options are saved to the database at shutdown $this->options = array( "columns" => $_POST["de-menu-columns"], "maintenance" => $_POST["de-menu-maintenance"] ); echo 'DE Menu options saved'; } ?> <div class="wrap"> <h2>DE Menu Plugin</h2> <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>"> <?php settings_fields('de-menu-options'); ?> <input type="checkbox" name="de-menu-maintenance" /> <label for="de-menu-columns">Columns:</label> <input type="text" name="de-menu-columns" value="<?php echo $this->options['columns']; ?>" /> <p class="submit"> <input type="submit" name="de-menu-submit" value="Update Options »" /> </p> </form> </div> <?php } function update() { // By storing all changes at the end we avoid multiple database calls $diff = array_diff( $this->options, $this->db_options ); if( !empty( $diff ) ){ update_option('de-menu-options', $this->options); } } 

Теперь с настройками API у меня есть что-то более похожее на следующее:

  function __construct() { /* constructor stuff */ // Do I load options? Will they be loaded for me? Who knows? if (is_admin()) { add_action('admin_menu', array(&$this, 'admin_menu')); add_action('admin_init', array(&$this, 'admin_init')); } /* more stuff */ // Settings API should update options for me... I think } public function admin_menu() { add_options_page('DE Menu Options', 'DE Menu', 'manage_options', 'de-menu-options', array(&$this, 'options')); add_option('de-menu-options', $this->options); } public function admin_init() { register_setting('de-menu-options','de-menu-options',array(&$this,'validate')); add_settings_section('de-menu-main-options', 'Main Settings', 'options_section', 'de-menu-options'); add_settings_field('de-menu-maintenance', 'Maintenance Mode', array(&$this,'options_maintenance'), 'de-menu-options', 'de-menu-main-options'); add_settings_field('de-menu-columns', 'Columns', array(&$this,'options_columns'), 'de-menu-options', 'de-menu-main-options'); } public function options() { if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.') ); } if ( !empty($_POST) && check_admin_referer('de-menu-options') ) { // These options are saved to the database at shutdown $this->options = array( "columns" => $_POST["de-menu-columns"], "maintenance" => $_POST["de-menu-maintenance"] ); echo 'DE Menu options saved'; } ?> <div class="wrap"> <h2>DE Menu Plugin</h2> <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>"> <?php settings_fields('de-menu-options'); ?> <?php do_settings_sections('de-menu-options'); ?> <p class="submit"> <input type="submit" name="de-menu-submit" value="Update Options »" /> </p> </form> </div> <?php } public function options_section() { echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>'; } public function options_maintenance() { echo "<input id='de-menu-maintenance' name='options[maintenance]' type='checkbox' />"; } public function options_columns() { echo "<input id='de-menu-columns' name='options[columns]' type='checkbox' value=".$this->options['columns']."/>"; } function validate($options) { return $options; // I guess? } 

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

Так что же я получаю от этой дополнительной работы?

Моя точка зрения заключается в том, что основная цель и преимущество API настроек – это структура .

Это помогает поддерживать сложные настройки:

  • упорядоченный (логика регистрации и разделы);
  • защищенные (nonces, обратные вызовы проверки);
  • расширяемый (подключение к другой странице или возможность подключения).

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

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

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

Преимущества (среди прочего):

  • API настроек принудительно дезактивирует ненадежные пользовательские данные.
  • API настроек заставляет параметры регистрироваться как массив параметров, в результате чего создается отдельная запись DB wp_options, а не отдельные записи БД для каждой опции
  • API настроек упрощает форматирование настроек
  • API настроек упрощает интерфейс администратора, совместимый с основным пользовательским интерфейсом администратора, что приводит к улучшению UX

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

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

Итак, вот ваш код переделан. Несколько примечаний:

  • В моем примере показаны как простые параметры (de_w, de_h), так и параметр массива (de_width_height).
  • Всегда санируйте вход пользователя. Я использовал целые числа в примере, потому что их легко дезинфицировать.
  • При использовании API настроек вам не нужны $ _POST, nonces, check_admin_referer (), update_option () и т. Д.
  • Сохранение происходит при загрузке следующей страницы, а не при выключении. Затем WP выполняет перенаправление на вашу страницу. Поэтому для отладки напечатайте некоторый вывод и вызовите wp_die () в одной из функций проверки.
  • Действие формы всегда «options.php». Так работает API настроек. Не используйте ничего. Ну, вы можете использовать admin_url ('options.php'), если хотите.
  • WP напечатает сообщение сохранения для вас.
  • Расширения, не включенные здесь: использование <label> для доступности. Используя add_settings_error (), settings_error (), которые обрабатывают сообщения, а также ошибки. Это часто единственная причина иметь отдельные функции проверки для каждого параметра. Вы можете видеть ниже validate_w (), а validate_h () может быть одной функцией. Я смотрел на попытку абстрагировать обмен сообщениями, но вы не получаете достаточную информацию в обратном вызове проверки, насколько я помню. Как в какой области вы работаете.
  • Функции обратного вызова валидации получают исходное значение $ _POST из API настроек. Мне нравится указывать параметр как таковой, $ raw. Для параметра массива вы получаете массив, такой как магия.
  • Изменить: $ это лучше, чем & $ this.

Код:

 <?php $foo= new de_Foo(); class de_Foo { function __construct() { if (is_admin()) { add_action('admin_menu', array($this, 'admin_menu')); add_action('admin_init', array($this, 'admin_init')); } } public function admin_menu() { add_options_page( 'DE Menu Options', 'DE Menu', 'manage_options', 'de-menu-options', array($this,'xoxptions') ); // add_option('de-menu-options', $this->options); } public function admin_init() { register_setting( 'de-menu-settings-group', 'de_w', array($this, 'validate_w') ); register_setting( 'de-menu-settings-group', 'de_h', array($this, 'validate_h') ); register_setting( 'de-menu-settings-group', 'de_width_height', array($this, 'validate_width_height') ); add_settings_section( 'de-menu-settings-section-size', 'Size', array($this, 'settings_section_size_render'), 'de-menu-options' ); add_settings_field( 'de_w', 'W', array($this, 'w_render'), 'de-menu-options', 'de-menu-settings-section-size' ); add_settings_field( 'de_h', 'H', array($this, 'h_render'), 'de-menu-options', 'de-menu-settings-section-size' ); add_settings_field( 'de_width_height', 'Width / Height', array($this, 'width_height_render'), 'de-menu-options', 'de-menu-settings-section-size' ); } public function options() { if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.') ); } //////////////////////////// // no no no //////////////////////////// // if ( !empty($_POST) && check_admin_referer('de-menu-options') ) { // // These options are saved to the database at shutdown // $this->options = array( // "columns" => $_POST["de-menu-columns"], // "maintenance" => $_POST["de-menu-maintenance"] // ); // echo 'DE Menu options saved'; // } //////////////////////////// ?> <div class="wrap"> <h2>DE Menu Plugin</h2> <form method="post" action="<?php echo admin_url('options.php'); ?>"> <?php settings_fields('de-menu-settings-group'); ?> <?php do_settings_sections('de-menu-options'); ?> <p class="submit"> <input type="submit" name="de-menu-submit" value="Update Options" /> </p> </form> </div> <?php } public function settings_section_size_render() { echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>'; } public function w_render() { $w= esc_attr( get_option('de_w') ); echo "<p><input name='de_w' value='$w'></p>\n"; } public function h_render() { $h= esc_attr( get_option('de_h') ); echo "<p><input name='de_h' value='$h'></p>\n"; } public function width_height_render() { $width_height= get_option('de_width_height', array()); $width= esc_attr( @$width_height['width'] ); $height= esc_attr( @$width_height['height'] ); echo "<p>Width: <input name='de_width_height[width]' value='$width'></p>\n"; echo "<p>Height: <input name='de_width_height[height]' value='$height'></p>\n"; } function validate_w($raw) { return (int)$raw; } function validate_h($raw) { return (int)$raw; } function validate_width_height($raw) { is_array($raw) or $raw= array(); $result= array(); $result['width']= (int)@$raw['width']; $result['height']= (int)@$raw['height']; return $result; } }