Bagaimana cara mengirimkan variabel ke add_settings_section () callback?

16

Saya mencoba untuk mengotomatisasi, sebanyak mungkin, fungsi Pengaturan API membutuhkan setiap pengaturan dalam Plugin. Looping melalui array opsi, dan keluaran add_settings_section()dan add_settings_field()cukup sederhana:

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

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

Dengan add_settings_field(), saya dapat dengan mudah menulis panggilan balik generik, dengan meneruskan $hookvariabel ke panggilan balik, sebagai parameter kelima dalam panggilan fungsi:

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 
}

Namun, tampaknya add_settings_section()tidak memiliki $argsparameter analog ; jadi, saya tidak bisa menggunakan metode yang sama untuk meneruskan $sectionvariabel ke panggilan balik.

Jadi, pertanyaan saya: apakah ada cara untuk mengirimkan variabel ke add_settings_section()callback, atau cara lain untuk membuat callback analog dengan apa yang saya lakukan add_settings_field()?

EDIT:

@ Netternet berhasil! Ini kode kerja saya:

/**
 * 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
            }
        }
    }
}
Chip Bennett
sumber
1
Hanya sidenote: Mengapa Anda tidak extract( $args, EXTR_SKIP );di awal oenology_hooks_setting_callback(), jadi Anda tidak harus menyimpan setiap bagian dari array ke yang baru $var? Ini kemudian akan tersedia dengan $'name_inside_the_array, misalnya. '$ title , $ tab`, dll.
kaiser
... karena saya sebenarnya tidak terlalu pintar dengan PHP? :) Saya akan mencobanya; Terima kasih!
Chip Bennett
Mungkin Anda ingin melihat intisari ini , yang menunjukkan beberapa contoh "mungkin praktik terbaik" tentang cara menambahkan filter & kait, mengurai argumen dan menangani input string kueri. Ini sedikit tua dan saya kemungkinan akan mengerjakannya kembali ketika saya punya waktu, tetapi saya perlu melihatnya. :)
kaiser
Ini sebenarnya hanya sebuah Plugin yang menambahkan UI untuk kait yang telah saya tambahkan ke Oenology. Saya cukup nyaman dengan cara saya menambahkan kait ke Tema. Sekarang, saya hanya mencoba memberikan cara yang nyaman untuk mengekspos mereka kepada pengguna akhir.
Chip Bennett
Saya belum salah paham dengan Anda. Saya hanya ingin menunjukkan ini kepada Anda jika mungkin ada bantuan (kapan saja) untuk Anda. Saya melihat kode ini sebagai sesuatu yang ironis - coba lihat betapa banyak upaya untuk mendapatkan masing-masing dan semua orang di wordpress ...
kaiser

Jawaban:

18

jika Anda melihat fungsi do_settings_sections lebih khusus baris 1164 di mana fungsi callback sedang dijalankan:

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

Anda dapat melihat bahwa array $ section sedang diteruskan ke fungsi panggilan balik, sehingga Anda dapat mengidentifikasi panggilan balik oleh $section['id']

harap ini membuat sejak.

Memperbarui

di sini adalah contoh, jika callback add_settings_section Anda untuk semua bagian diberi nama oenology_hooks_section_callbackmaka Anda dapat mengidentifikasinya seperti ini:

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

dan dengan melakukan hal-hal yang saya maksud melakukan apa pun yang ingin Anda lakukan dengan bagian panggilan balik itu.

Bainternet
sumber
Hmm ... itu terlihat menjanjikan. Bagaimana saya menentukan $section['id']?
Chip Bennett
@Chip Bennett idakan menjadi argumen pertama yang Anda berikanadd_settings_section()
Rarst
@Chip Bennett Saya menambahkan contoh untuk mencoba dan menjelaskan dengan lebih baik.
Bainternet
@Bainternet: Luar Biasa! Saya memiliki skrip opsi dan menemui masalah yang sama dengan Chip Bennett. Sekarang ini berfungsi seperti pesona. Terima kasih.
Anh Tran
Oke, jadi akhirnya diklik akhir pekan; izinkan saya mencoba kode yang ada dalam pikiran saya, dan saya akan melaporkan kembali.
Chip Bennett
4

Saya tahu ini adalah pertanyaan lama tapi saya akan memasukkan dua sen saya, kalau-kalau ada orang lain datang; cara yang lebih sederhana untuk melakukannya adalah dengan menulis sendiri modifikasi add_settings_section()fungsi Anda, yang hanya akan menambahkan parameter args callback di akhir itu.

Ini akan terlihat seperti ini (atau sesuatu seperti itu)

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

Sekarang Anda cukup menggunakan ini alih-alih fungsi wordpress asli dan mengakses arg callback Anda melalui 'callbackargs'kunci array dengan cara yang biasa, seperti ini

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

Yang bisa kita gunakan untuk meneruskan ke beberapa fungsi lain:

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

Atau arg callback bisa berupa array sendiri yang kami gunakan:

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

Ini semua dimungkinkan karena semua yang add_settings_section()dilakukan adalah menambahkan anggota array baru ke $wp_settings_sectionsvariabel global, bahwa anggota array baru dapat berupa array itu sendiri yang berisi sejumlah kunci dengan nama yang berbeda, yang dapat digunakan, oleh fungsi apa pun yang tahu mereka ada di sana. Ketika do_settings_sectionsmenyebut call_user_func_arraymelewati sebuah $sectionsparamater sebagai Bainternet dicatat, ini berarti bahwa seluruh array kita ditambahkan ke $wp_settings_sectionsdalam my_add_settings_section()dilewatkan ke callback kami, berarti kita memiliki akses ke setiap anggota array baru kita menambahkan untuk itu seperti callbackargsmemungkinkan fungsi kita untuk memiliki penuh panggilan balik baku.

Meskipun aku yakin ini mungkin sudah jelas, kupikir aku akan menjelaskannya kalau-kalau ada orang yang bingung.

Cikica
sumber
0

Anda juga dapat selalu menggunakan pendekatan yang lebih umum, tidak mencari implementasi fungsi tertentu (artinya, tanpa memeriksa apakah add_settings_section melewati sesuatu secara implisit). Pendekatan umum ini menggunakan penutupan PHP.

Cara menggunakannya: di setiap tempat, tempat Anda menyampaikan nama fungsi, alih-alih memberikan fungsi anonim, dengan menggunakannya .

Contoh:

dari pada

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

function callback_name() {
    do_something();
}

kamu bisa memakai:

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 );
}
Olga Farber
sumber