Come passare la variabile al callback add_settings_section ()?


16

Sto tentando di automatizzare, per quanto possibile, la funzione API Impostazioni richiede ogni impostazione in un plugin. Passare in rassegna l'array di opzioni e generare add_settings_section()ed add_settings_field()è abbastanza semplice:

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

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

Con add_settings_field(), posso facilmente scrivere un callback generico, passando la $hookvariabile al callback, come il quinto parametro nella chiamata di funzione:

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 
}

Tuttavia, sembra che add_settings_section()non abbia un $argsparametro analogo ; quindi, non posso usare lo stesso metodo per passare la $sectionvariabile al callback.

Quindi, la mia domanda: esiste un modo per passare una variabile al add_settings_section()callback o un altro modo per creare un callback analogo a quello che sto facendo add_settings_field()?

MODIFICARE:

@Bainternet l'ha inchiodato! Ecco il mio codice di lavoro:

/**
 * 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
Solo un sidenote: perché non extract( $args, EXTR_SKIP );all'inizio oenology_hooks_setting_callback(), quindi non è necessario salvare ogni parte dell'array in una nuova $var? Questi saranno quindi disponibili con $'name_inside_the_array, ad es. '$ title , $ tab`, ecc.
kaiser,

... perché in realtà non sono così intelligente con PHP? :) Ci proverò; Grazie!
Chip Bennett,

Forse vuoi dare un'occhiata a questo Gist , che mostra alcuni esempi di "forse best practice" su come aggiungere filtri e hook, analizzare argomenti e gestire l'input della stringa di query. È un po 'vecchio e probabilmente lo rielaborerò quando avrò tempo, ma vale la pena dare un'occhiata. :)
Kaiser

Questo è in realtà solo un plug-in che aggiunge l'interfaccia utente per gli hook che ho aggiunto a Enologia. Sono abbastanza a mio agio con il modo in cui ho effettivamente aggiunto i ganci al tema. Ora sto solo cercando di fornire un modo conveniente per esporli agli utenti finali.
Chip Bennett,

Non ti ho frainteso. Volevo solo mostrarti questo nel caso in cui ti possa essere di qualche aiuto (ogni volta). Vedo questo codice come qualcosa di ironico - dai un'occhiata a quanti sforzi è necessario per ottenere tutti e tutti per tutti nel modo wordpress ...
Kaiser

Risposte:


18

se si osserva la funzione do_settings_sections in particolare la riga 1164 in cui viene eseguita la funzione di callback:

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

si può vedere che l'array $ section viene passato alla funzione di callback, quindi è possibile identificare il callback da $section['id']

spero che questo faccia da allora.

Aggiornare

ecco un esempio, se il tuo callback add_settings_section per tutte le sezioni è stato nominato oenology_hooks_section_callbackallora puoi identificarlo in questo modo:

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

e per fare le cose intendo fare qualunque cosa tu voglia fare con quella sezione callback.


Hmm ... sembra promettente. Come posso determinare $section['id']?
Chip Bennett,

@Chip Bennett idsarà il primo argomento a cui passiadd_settings_section()
Rarst

@Chip Bennett Ho aggiunto un esempio per cercare di spiegare meglio.
Bainternet,

@Bainternet: Fantastico! Ho uno script di opzioni e ho riscontrato lo stesso problema di Chip Bennett. Ora funziona perfettamente. Grazie.
Anh Tran,

Okay, quindi alla fine è scattato durante il fine settimana; fammi provare il codice che ho in mente e riporterò indietro.
Chip Bennett,

4

So che questa è una vecchia domanda, ma io lancerò i miei due centesimi, nel caso in cui qualcuno si presenti; un modo più semplice per farlo sarebbe quello di scrivere la propria modifica della add_settings_section()funzione, che aggiungerebbe un parametro args di callback alla fine di esso.

Questo sarebbe simile a questo (o qualcosa del genere)

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

Ora dovresti semplicemente usare questo invece della funzione wordpress nativa e accedere ai tuoi argomenti di callback tramite la 'callbackargs'chiave di matrice in un modo normale, come questo

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

Che potremmo usare per passare ad altre funzioni:

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

Oppure i callback args potrebbero essere essi stessi un array che usiamo:

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

Tutto ciò è possibile perché tutto add_settings_section()ciò che fa è aggiungere un nuovo membro dell'array alla $wp_settings_sectionsvariabile globale, quel nuovo membro dell'array potrebbe essere un array stesso contenente un numero qualsiasi di chiavi con nomi diversi, che potrebbero essere utilizzate da qualsiasi funzione che sapesse che erano lì. Quando do_settings_sectionschiama la call_user_func_arraypassa un $sectionsparamater come notato Bainternet, questo significa che l'intero array abbiamo aggiunto a $wp_settings_sectionsin my_add_settings_section()è passato nel nostro richiamata, il che significa che abbiamo accesso a ogni nuovo membro di matrice aggiungiamo ad esso come ad esempio lacallbackargs permettere nostra funzione di avere una completa callback a tutti gli effetti.

Anche se sono sicuro che questo potrebbe essere ovvio, ho pensato che lo avrei spiegato nel caso qualcuno si confondesse.


0

Puoi anche utilizzare sempre un approccio più generale, non cercando l'implementazione della funzione particolare (ovvero, senza verificare se add_settings_section passa qualcosa di implicitamente). Questo approccio generale utilizza la chiusura di PHP.

Come usarlo: in ogni luogo, dove si passa un nome di funzione, invece di passare una funzione anonima, con l' uso in esso.

Esempio:

invece di

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

function callback_name() {
    do_something();
}

Puoi usare:

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 );
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.