問題描述

我試圖儘可能地自動化外掛中每個設定的 Settings API 函式呼叫。迴圈選擇陣列,並輸出 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
            }
        }
    }
}

最佳解決方案

如果您仔細檢視 do_settings_sections 函式更具體地執行回撥函式的行 1164:

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

您可以看到 $ section 陣列被傳遞給回撥函式,因此您可以透過 $section['id']來識別回撥

希望這樣做。

Update

這裡是一個例子,如果你所有部分的 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
    }
 }

並且做的東西我的意思是做任何你想做的那個部分回撥。

次佳解決方案

我知道這是一個古老的問題,但我會把我的兩分錢,以防萬一有人來; 這樣做的一個更簡單的方法是寫你自己修改的 add_settings_section()函式,這隻會在它的末尾新增一個回撥引數引數。

這看起來像這樣 (或類似的東西)

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'陣列鍵以通常的方式訪問您的回撥引數,就像這樣

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 );
}

或者回撥引數可以是我們使用的陣列本身:

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 時,它會按照 Bainternet 的說法透過 $sections 引數,這意味著我們在 my_add_settings_section()中新增到 $wp_settings_sections 的整個陣列被傳遞到我們的回撥中,這意味著我們可以訪問我們新增到的每個新的陣列成員,如 callbackargs,允許我們的功能有一個完整的回撥。

即使我確信這可能是明顯的,我以為我會解釋它,以防萬一有困惑的人看。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。