如何更新插件设置页面上的可选选项

时间:2013-10-18 作者:Eques

我写了一个wordpress插件。我的插件有选项。所有选项都在一个组中,“pluginname settings”。所有选项名称都是统一的,看起来像“pluginname settings[\'option-name\']”。一些代码可以说明我的情况:

register_setting( \'pluginname_options\', \'pluginname-settings\', \'pluginname_validate\' );
add_settings_section( \'section-one\', \'Name of Section One\', \'section_one_callback\', \'pluginname_options-sectionname\' );
add_settings_field( \'optionname\', \'First Option\', \'my_text_input\', \'pluginname_options-sectionname\', \'section-button\', array(
    \'name\' => \'pluginname[optionname]\',
    \'value\' => \'42\')
    )
为了让博客管理员调整它们,我创建了一个设置页面,并将选项分组到选项卡中。每个选项卡显示选项子集(一个部分)和“更新按钮”,如下所示:

echo "<form action=\\"options.php\\" method=\\"POST\\">";
settings_fields( \'pluginname_options\' );
do_settings_sections( \'pluginname_options-sectionname\' ); 
submit_button(\'Update\', \'primary\',  \'submit-form\', false);
echo "</form>";
问题是,当我在一个选项卡上按“更新”时,其他选项卡上的选项会被清除。

据我所知,这是因为所有选项都表示一个设置的数组。

问题:在此设置下,是否可以保存一个节而不清除其他节?在这种情况下,最好的做法是什么?注册单独的设置,使用验证功能填充空格或其他什么?还是只是我做错了?

提前谢谢你。

P、 S:根据评论中的请求,下面是一个最简单的工作示例:

<?php
/*
Plugin Name: Plugin Name
Plugin URI:
Description: Description
Version: 0.0.1
Author: Author Name
Author URI:
License: GPL3+
*/

add_action( \'admin_menu\', \'pluginname_menu\' );

function pluginname_menu()
    {
    add_options_page( \'PluginName Options\', \'pluginname\', \'manage_options\', \'pluginname_options_page\', \'pluginname_options_page\' );
    }

add_action( \'admin_init\', \'pluginname_admin_init\' );

function pluginname_admin_init()
    {
    register_setting( \'pluginname_options\', \'pluginname-settings\' );
    add_settings_section( \'section-one\', \'Section One\', \'pluginname_section_callback\', \'pluginname_options-section-one\' );
    $options_array = get_option(\'pluginname-settings\');
    add_settings_field( \'optionname-one\', \'First Option\', \'pluginname_field_callback\', \'pluginname_options-section-one\', \'section-one\', array(
    \'name\' => \'pluginname-settings[optionname-one]\',
    \'value\' => isset($options_array[\'optionname-one\']) ? $options_array[\'optionname-one\'] : \'42\')
    );
    add_settings_field( \'optionname-two\', \'Second Option\', \'pluginname_field_callback\', \'pluginname_options-section-one\', \'section-one\', array(
    \'name\' => \'pluginname-settings[optionname-two]\',
    \'value\' => isset($options_array[\'optionname-two\']) ? $options_array[\'optionname-two\'] : \'42\')
    );
    add_settings_section( \'section-two\', \'Section Two\', \'pluginname_section_callback\', \'pluginname_options-section-two\' );
    add_settings_field( \'optionname-three\', \'Third Option\', \'pluginname_field_callback\', \'pluginname_options-section-two\', \'section-two\', array(
    \'name\' => \'pluginname-settings[optionname-three]\',
    \'value\' => isset($options_array[\'optionname-three\']) ? $options_array[\'optionname-three\'] : \'42\')
    );
    add_settings_field( \'optionname-four\', \'Fourth Option\', \'pluginname_field_callback\', \'pluginname_options-section-two\', \'section-two\', array(
    \'name\' => \'pluginname-settings[optionname-four]\',
    \'value\' => isset($options_array[\'optionname-four\']) ? $options_array[\'optionname-four\'] : \'42\')
    );
    }

function pluginname_validate($input)
    {
    return $input;
    }

function pluginname_section_callback()
    {
    echo \'Feel free to change parameters below.\';
    }

function pluginname_field_callback( $args )
    {
    $name = esc_attr( $args[\'name\'] );
    $value = esc_attr( $args[\'value\'] );
    echo "<input type=\'text\' name=\'$name\' value=\'$value\' /> ";
    }

function pluginname_tab1()
    {
    echo "<form action=\\"options.php\\" method=\\"POST\\">";
    settings_fields( \'pluginname_options\' );
    do_settings_sections( \'pluginname_options-section-one\' ); 
    submit_button(\'Update\', \'primary\',  \'submit-form\', false);
    echo "</form>";
    }

function pluginname_tab2()
    {
    echo "<form action=\\"options.php\\" method=\\"POST\\">";
    settings_fields( \'pluginname_options\' );
    do_settings_sections( \'pluginname_options-section-two\' ); 
    submit_button(\'Update\', \'primary\',  \'submit-form\', false);
    echo "</form>";
    }

function pluginname_options_page()
    {
    ?>
    <div class="wrap">
        <h2>Options</h2>
        <h2 class="nav-tab-wrapper">
        <a href="?page=pluginname_options_page&tab=1" class="nav-tab <? if ( @( $_GET[\'tab\'] == \'1\' ) || !isset($_GET[\'tab\'])) echo "nav-tab-active"; ?>">Section One Options</a>
        <a href="?page=pluginname_options_page&tab=2" class="nav-tab <? if ( $_GET[\'tab\'] == \'2\' ) echo "nav-tab-active"; ?>">Section Two Options</a>
        </h2>
        <?php $current_tab = $_GET[\'tab\'];
        switch ($current_tab)
            {
            case \'2\' : pluginname_tab2(); break;
            default: pluginname_tab1();
            } ?>
    </div>
    <?php
}
?>
minimal working example.

3 个回复
最合适的回答,由SO网友:helgatheviking 整理而成

通过更改register_setting()

register_setting( \'pluginname_options\', \'pluginname-settings\', \'pluginname_validate\' );
然后更新验证函数以实际执行某些操作。下面它获取选项的当前状态,然后只更新提交的数组片段。当您在选项卡上并单击“更新”时,只会发布选项卡中的信息。因此,数组(如所写)只有2个键,并且会清除其他选项卡中的信息。

function pluginname_validate($input)
    {
    $options_array = get_option(\'pluginname-settings\');

    if( isset( $input[\'optionname-one\'] ) )
         $options_array[\'optionname-one\'] = sanitize_text_field( $input[\'optionname-one\'] );

    if( isset( $input[\'optionname-two\'] ) )
         $options_array[\'optionname-two\'] = sanitize_text_field( $input[\'optionname-two\'] );

    if( isset( $input[\'optionname-three\'] ) )
         $options_array[\'optionname-three\'] = sanitize_text_field( $input[\'optionname-three\'] );

    if( isset( $input[\'optionname-four\'] ) )
         $options_array[\'optionname-four\'] = sanitize_text_field( $input[\'optionname-four\'] );

    return $options_array;
    }
为了好玩,我加入了一些清理,数据清理的类型取决于你的实际选择,但你应该总是做一些清理。

SO网友:fuxia

有两种方法:

将选项卡ID作为隐藏字段与表单一起传递,并仅更新属于该选项卡的字段。

将每个选项卡的字段名分开,并在保存回调中组合它们。

SO网友:Chip Bennett

因此,假设您定义了一个参数,将每个选项添加到自己的选项卡中。我是这样做的,例如:

\'display_social_icons\' => array(
    \'name\' => \'display_social_icons\',
    \'title\' => __( \'Display Social Icons\', \'oenology\' ),
    \'type\' => \'checkbox\',
    \'description\' => __( \'Display social icons in sidebar\', \'oenology\' ),
    \'section\' => \'social\',
    \'tab\' => \'general\',
    \'since\' => \'1.2\',
    \'default\' => true
),
然后,在输出设置页面时,确定当前选项卡:

$currenttab = oenology_get_current_tab();
$settings_section = \'oenology_\' . $currenttab . \'_tab\';
// Defining $currenttab left out for brevity
。。。然后分别输出每个选项卡:

do_settings_sections( $settings_section );
然后,使用特定于选项卡的提交/重置按钮:

<?php submit_button( __( \'Save Settings\', \'oenology\' ), \'primary\', \'theme_oenology_options[submit-\' . $currenttab . \']\', false ); ?>
<?php submit_button( __( \'Reset Defaults\', \'oenology\' ), \'secondary\', \'theme_oenology_options[reset-\' . $currenttab . \']\', false ); ?>
现在,在验证回调中,您可以确定选择了哪个提交/重置选项卡:

    $tabs = oenology_get_settings_page_tabs();

    // Determine what type of submit was input
    $submittype = \'submit\';        
    foreach ( $tabs as $tab ) {
            $resetname = \'reset-\' . $tab[\'name\'];
            if ( ! empty( $input[$resetname] ) ) {
                    $submittype = \'reset\';
            }
    }

    // Determine what tab was input
    $submittab = \'varietals\';        
    foreach ( $tabs as $tab ) {
            $submitname = \'submit-\' . $tab[\'name\'];
            $resetname = \'reset-\' . $tab[\'name\'];
            if ( ! empty( $input[$submitname] ) || ! empty($input[$resetname] ) ) {
                    $submittab = $tab[\'name\'];
            }
    }
。。。然后,在您逐步浏览白名单时,只对选项子集进行操作。

(我在这里留下了很多代码,因为这只是概念证明。如果您想看到一个工作示例,check here.

结束

相关推荐

如何在Contact Form 7-Forms中使用其他快捷码?

我注意到任何不是联系人表单7内置短代码一部分的短代码都不起作用。例如:我试图在contact form 7中的表单元素之间使用手风琴快捷码。但是代码不起作用。如何在不编辑联系人表单7核心文件的情况下解决此问题?