问题描述
让我先说说我几乎没有使用 WordPress – 事实上,我在 WordPress 的最后一次网站是在 2.2 之前回来的。昨天我做了一切的一切,问了几个问题,试图让一个基本的菜单插件工作。
我现在有插件完全正常运行,所以我决定在这里做一些小的修改,增加功能和兼容性,包括使用 Settings API 。然而,在阅读这个 API 的教程的一段很短的时间里,我变得很困惑,那么这个混乱只会在我阅读时加深,并试图实现这些例子 – 这种情况使我的插件被实现为一个类。
除非我做错了,从我所理解的使用设置 API 需要创建一个新的功能 PER SETTING 。这意味着平均插件的 3-5 个功能,更高级的插件最多可达数百个。当您可以轻松地将所有适用的 $_POST
变量导入数组并放弃整个混乱时,写出这么多函数 (并开发命名系统以避免混淆) 似乎是荒唐的。
也许我是 old-fashioned,但是除非有什么可以从中获益,否则我看不出有什么原因使我写的代码数量翻了三倍或四倍。尝试添加设置 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?
}
从滚动条中可能很显而易见的是,只需两个选项,代码已经更长了。这是 like-wise 从评论中显而易见的,我不完全明白我在做什么。那么就有 5 个新功能 (仅删除 1 个) 才能完成所有这些功能。
那么我从这些额外的工作中获得什么优势呢?
最佳解决方案
我的观点是,设置 API 的主要目的和好处是结构。
它有助于保持复杂的设置设置:
-
有序 (注册和部分的逻辑);
-
安全 (nonces,验证回调);
-
可扩展 (钩入另一页或允许挂钩) 。
与任何这样的结构性开销一样,它会使更复杂的用例受益,而且不太简单。
所以你可以实现任何设置 API,而不使用它。问题是如果你能以可靠,安全和可扩展的方式来实现这一点。
次佳解决方案
如果您正确使用回调,则不需要所有冗余代码。 Here’s how I implement the Settings API, in a way that is completely scalable 。
优点 (除其他外):
-
「设置」API 强制对不受信任的用户数据进行清理。
-
「设置」API 强制将注册为选项数组的选项导致单个 wp_options 数据库条目,而不是每个选项的离散数据库条目
-
「设置」API 可帮助设置表单的安全加固
-
「设置」API 可帮助管理界面与核心管理界面一致,从而实现更好的用户体验
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。