Позвольте мне предисловие к этому, сказав, что я почти никогда не работаю с 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 настроек – это структура .
Это помогает поддерживать сложные настройки:
Как и при любых таких структурных накладных расходах, преимущества более сложных вариантов использования и преимуществ менее простых.
Таким образом, вы можете реализовать все, что использует API настроек, не используя его. Вопрос в том, можете ли вы сделать это как надежный, безопасный и расширяемый способ.
Если вы правильно используете обратные вызовы, вам не нужен весь избыточный код. Вот как я реализую API-интерфейс настроек, который полностью масштабируется .
Преимущества (среди прочего):
Спасибо, что опубликовали это, мне было интересно узнать то же самое. Множество функций.
Чтобы уменьшить их, вы можете хранить свои параметры в виде массивов. WordPress выполняет сериализацию данных для вас. Это сохраняет код (или функции в любом случае), но делает хуже данные. Например, если вы хотите сортировать, редактировать вручную, экспортировать и т. Д., Ваши таблицы, они будут иметь эти сериализованные значения. С другой стороны, ваш плагин добавляет меньше записей в таблицу параметров, и их легче очистить.
Итак, вот ваш код переделан. Несколько примечаний:
<label>
для доступности. Используя add_settings_error (), settings_error (), которые обрабатывают сообщения, а также ошибки. Это часто единственная причина иметь отдельные функции проверки для каждого параметра. Вы можете видеть ниже validate_w (), а validate_h () может быть одной функцией. Я смотрел на попытку абстрагировать обмен сообщениями, но вы не получаете достаточную информацию в обратном вызове проверки, насколько я помню. Как в какой области вы работаете. Код:
<?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; } }