如何将变量传递给add_settings_section()回调?


16

我正在尝试尽可能自动地执行插件中每个设置的Settings API函数调用。循环遍历options数组,然后输出add_settings_section()add_settings_field()很简单:

add_settings_section()

$oenology_hooks_tabs = oenology_hooks_get_settings_page_tabs();
foreach ( $oenology_hooks_tabs as $tab ) {
    $tabname = $tab['name'];
    $tabtitle = $tab['title'];
    $tabsections = $tab['sections'];
    foreach ( $tabsections as $section ) {
        $sectionname = $section['name'];
        $sectiontitle = $section['title'];
        $sectiondescription = $section['description'];
        // Add settings section
        add_settings_section(
            'oenology_hooks_' . $sectionname . '_section',
            $sectiontitle,
            'oenology_hooks_' . $sectionname . '_text',
            'oenology_hooks_' . $tabname . '_tab'
        );
    }
}

和`add_settings_field():

global $oenology_hooks;
$oenology_hooks = oenology_hooks_get_hooks();

foreach ( $oenology_hooks as $hook ) {
    $hookname = $hook['name'];
    $hooktitle = $hook['title'];
    $hooktab = $hook['tab'];
    $hooksection = $hook['section'];
    add_settings_field(
        'oenology_hooks_' . $hookname,
        $hooktitle,
        'oenology_hooks_setting_callback',
        'oenology_hooks_' . $hooktab . '_tab',
        'oenology_hooks_' . $hooksection . '_section',
        $hook
    );
}

使用add_settings_field(),我可以轻松地通过将$hook变量传递给回调作为函数调用中的第五个参数来编写通用回调:

function oenology_hooks_setting_callback( $hook ) {
    $oenology_hooks_options = get_option( 'plugin_oenology_hooks_settings' ); 
    $hookname = $hook['name'];
    $hooktitle = $hook['title'];
    $hookdescription = $hook['description'];
    $hooktype = $hook['type'];
    $hooktab = $hook['tab'];
    $hooksection = $hook['section'];
    $inputvalue = $hookname . '_hide';
    $inputname = 'plugin_oenology_hooks_settings[' . $inputvalue . ']';
    $textareaname = 'plugin_oenology_hooks_settings[' . $hookname . ']';
    $textareavalue = $oenology_hooks_options[$hookname];
    if ( 'Filter' == $hooktype ) {
        ?>
        <input type="checkbox" name="<?php echo $inputname; ?>" value="<?php echo $inputvalue;?>" <?php checked( true == $oenology_hooks_options[$inputvalue]  ); ?> />
        <span>Hide <?php echo $hooktitle; ?> content?</span><br />
        <?php
    }
    ?>
    <span class="description"><?php echo $hooktype; ?> Hook: <?php echo $hookdescription; ?></span><br />
    <textarea name="<?php echo $textareaname; ?>" cols="80" rows="3" ><?php 
        echo esc_textarea( $textareavalue ); 
    ?></textarea>
    <?php 
}

但是,似乎add_settings_section()没有类似的$args参数。因此,我不能使用相同的方法将$section变量传递给回调。

因此,我的问题是:有什么方法可以将变量传递给add_settings_section()回调,或者有其他方法可以创建类似于我正在做的回调的回调add_settings_field()

编辑:

@Bainternet钉了它!这是我的工作代码:

/**
 * Callback for add_settings_section()
 * 
 * Generic callback to output the section text
 * for each Plugin settings section. 
 * 
 * @param   array   $section_passed Array passed from add_settings_section()
 */
function oenology_hooks_sections_callback( $section_passed ) {
    global $oenology_hooks_tabs;
    $oenology_hooks_tabs = oenology_hooks_get_settings_page_tabs();
    foreach ( $oenology_hooks_tabs as $tab ) {
        $tabname = $tab['name'];
        $tabsections = $tab['sections'];
        foreach ( $tabsections as $section ) {
            $sectionname = $section['name'];
            $sectiondescription = $section['description'];
            $section_callback_id = 'oenology_hooks_' . $sectionname . '_section';
            if ( $section_callback_id == $section_passed['id'] ) {
                ?>
                <p><?php echo $sectiondescription; ?></p>
                <?php
            }
        }
    }
}

1
只是一个旁注:为什么不extract( $args, EXTR_SKIP );以开头oenology_hooks_setting_callback(),所以您不必将数组的每个部分保存到一个新的数组中$var?然后$'name_inside_the_array,这些将可用于,例如。“$标题, $ tab`等
凯泽

...因为我实际上对PHP并不那么聪明?:)我会尝试的;谢谢!
Chip Bennett

也许您想看一下Gist,它显示了一些“也许是最佳实践”示例,说明如何添加过滤器和挂钩,解析参数以及处理查询字符串输入。它有点旧,我有时间的时候可能会对其进行修改,但是imo值得一看。:)
kaiser

这实际上只是一个插件,它为我添加到Oenology的挂钩添加了UI。我对将钩子实际添加到主题的方式非常满意。现在,我只是想提供一种方便的方法来将它们展示给最终用户。
Chip Bennett

我没有误会你。我只是想向您展示,以防万一。我将此代码视为具有讽刺意味的东西-看看以wordpress方式为每个人获取所有东西要付出多大的努力...
kaiser

Answers:


18

如果您查看do_settings_sections函数,更具体地说是正在执行回调函数的1164行:

call_user_func($section['callback'], $section);

您会看到$ section数组正在传递给回调函数,因此您可以通过 $section['id']

希望此后。

更新资料

这是一个示例,如果您为所有部分指定了add_settings_section回调,oenology_hooks_section_callback则可以像这样标识它:

function oenology_hooks_section_callback($section_passed){
    if ($section_passed['id'] == 'whatever_section_id'){
        //do stuff
    }
    if ($section_passed['id'] == 'whatever_section_id_number2'){
        //do other stuff
    }
 }

做事情,我的意思是做与该部分回调有关的任何事情。


嗯...看起来很有希望。我该如何确定$section['id']
Chip Bennett

@Chip Bennett id将是您传递给的第一个论点add_settings_section()
Rarst 2011年

@Chip Bennett我添加了一个示例来尝试更好地解释。
Bainternet 2011年

@Bainternet:太棒了!我有一个选项脚本,并且遇到了与Chip Bennett相同的问题。现在,它就像一种魅力。谢谢。
Anh Tran

好吧,所以终于在周末点击了;让我尝试一下我想到的代码,然后我将进行报告。
Chip Bennett

4

我知道这是一个老问题,但是我会投入两美分,以防万一有人来了。一个更简单的方法是编写您自己的add_settings_section()函数修改,仅在函数末尾添加一个回调args参数。

看起来像这样(或类似的东西)

function my_add_settings_section($id, $title, $callback, $page, $callbackargs) {

global $wp_settings_sections;

if ( !isset($wp_settings_sections) ) 
{
    $wp_settings_sections = array();
}

if ( !isset($wp_settings_sections[$page]) )
{
    $wp_settings_sections[$page] = array();
}

if ( !isset($wp_settings_sections[$page][$id]) )
{
    $wp_settings_sections[$page][$id] = array();
}

$wp_settings_sections[$page][$id] = array( 'id' => $id, 'title' => $title, 'callback' => $callback, 'callbackargs' => $callbackargs, 'page' => 'page' );
}

现在,您将简单地使用此函数而不是本机的wordpress函数,并'callbackargs'以通常的方式通过array键访问回调args ,如下所示

function oenology_hooks_sections_callback( $section_passed ) {
   // Our callback arguments  
   $section_passed['callbackargs']
}

我们可以用来传递给其他函数:

 function oenology_hooks_sections_callback( $section_passed ) {
   // Our callback arguments  
   $args = $section_passed['callbackargs'];
   some_other_function( $args );
}

或者,回调args本身可以是我们使用的数组:

function oenology_hooks_sections_callback( $section_passed ) {
   // Our callback arguments  
   if ( $section_passed['callbackargs']['stuff'] !== 'things' ) 
   {
       echo 'stuff is not things!";
   }
}

这都是可能的,因为所有add_settings_section()操作都是在$wp_settings_sections全局变量中添加一个新的数组成员,该新的数组成员可以是一个数组本身,其中包含任意数量的具有不同名称的键,任何知道它们的函数都可以使用该键。当do_settings_sections调用call_user_func_array它传递一个$sectionsparamater作为Bainternet指出,这意味着,我们加入到整个阵列$wp_settings_sectionsmy_add_settings_section()被传递到我们的回调,这意味着我们有机会获得我们添加到它的每一个新的数组成员,如callbackargs使我们的功能有一个完整的落后的回调。

即使我不确定这可能很明显,我还是想解释一下,以防万一有人感到困惑。


1

您也可以始终使用更通用的方法,而不是寻找特定的函数实现(意味着,无需检查add_settings_section是否隐式传递了任何内容)。这种通用方法使用PHP闭包。

使用方法:在每个地方都传递一个函数名,而不是传递一个在其中使用的匿名函数。

例:

代替

foreach ( $ar as $name => value ) {
    add_settings_section(
        $section,
        'something',
        'something-else',
        'callback_name'
    );
}

function callback_name() {
    do_something();
}

您可以使用:

foreach ( $ar as $name => value ) {
    add_settings_section(
        $section,
        'something',
        'something-else',
        function () use ( $name, $value ) {
            callback_name( $name, $value )
        }
    );
}

function callback_name( $name, $value ) {
    do_something( $name, $value );
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.