Wie übergebe ich eine Variable an den Rückruf von add_settings_section ()?

16

Ich versuche, die Einstellungen-API-Funktion für jede Einstellung in einem Plugin so weit wie möglich zu automatisieren. Das Options-Array durchlaufen und ausgeben add_settings_section()und add_settings_field()ist einfach genug:

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

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

Mit add_settings_field()kann ich einfach einen generischen Callback schreiben, indem ich die $hookVariable an den Callback als fünften Parameter im Funktionsaufruf übergebe:

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 
}

Es scheint jedoch, dass add_settings_section()es keinen analogen $argsParameter gibt. Daher kann ich nicht dieselbe Methode verwenden, um die $sectionVariable an den Rückruf zu übergeben.

Daher meine Frage: Gibt es eine Möglichkeit, eine Variable an den add_settings_section()Rückruf zu übergeben, oder eine andere Möglichkeit, einen Rückruf zu erstellen, die der Vorgehensweise entspricht add_settings_field()?

BEARBEITEN:

@Bainternet hat es geschafft! Hier ist mein Arbeitscode:

/**
 * 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
quelle
1
Nur eine Randnotiz: Warum nicht extract( $args, EXTR_SKIP );am Anfang von oenology_hooks_setting_callback(), damit Sie nicht jeden Teil des Arrays in einem neuen speichern müssen $var? Diese werden dann zum Beispiel mit verfügbar sein $'name_inside_the_array. "$ title , $ tab" usw.
Kaiser
... weil ich mit PHP eigentlich gar nicht so schlau bin? :) Ich werde es versuchen; Vielen Dank!
Chip Bennett
Vielleicht möchten Sie einen Blick auf diese Gist werfen , die ein Beispiel für bewährte Methoden zum Hinzufügen von Filtern und Hooks, zum Parsen von Argumenten und zum Umgang mit der Eingabe von Abfragezeichenfolgen zeigt. Es ist ein bisschen alt und ich werde es wahrscheinlich überarbeiten, wenn ich Zeit habe, aber imo ist es einen Blick wert. :)
Kaiser
Dies ist eigentlich nur ein Plugin, das die Benutzeroberfläche für Hooks hinzufügt, die ich zu Oenology hinzugefügt habe. Ich bin ziemlich zufrieden damit, wie ich die Hooks tatsächlich zum Theme hinzugefügt habe . Jetzt versuche ich nur eine bequeme Möglichkeit zu bieten, um sie Endbenutzern zugänglich zu machen.
Chip Bennett
Ich habe dich nicht missverstanden. Ich wollte dir das nur zeigen, falls es dir (wann immer) helfen könnte. Ich sehe diesen Code als etwas Ironisches - sehen Sie sich nur an, wie viel Aufwand es bedeutet, alles und jeden auf WordPress- Art und Weise zu erreichen ...
kaiser

Antworten:

18

Wenn Sie sich die Funktion do_settings_sections genauer ansehen, sehen Sie sich die Zeile 1164 an, in der die Rückruffunktion ausgeführt wird:

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

Sie können sehen, dass das Array "$ section" an die Rückruffunktion übergeben wird, sodass Sie den Rückruf anhand von identifizieren können $section['id']

hoffe das macht da.

Aktualisieren

Hier ein Beispiel: Wenn Ihr Rückruf für add_settings_section für alle Abschnitte benannt wurde oenology_hooks_section_callback, können Sie ihn folgendermaßen identifizieren:

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

und mit "do stuff" meine ich, mach was du willst mit diesem Abschnitt Rückruf.

Bainternet
quelle
Hmm ... das sieht vielversprechend aus. Wie bestimme ich $section['id']?
Chip Bennett
@Chip Bennett idist das erste Argument, an das Sie sich add_settings_section()
wenden
@Chip Bennett Ich habe ein Beispiel hinzugefügt, um es besser zu erklären.
Bainternet
@Bainternet: Super! Ich habe ein Optionsskript und habe das gleiche Problem wie Chip Bennett. Jetzt funktioniert es wie ein Zauber. Vielen Dank.
Anh Tran
Okay, also hat es am Wochenende endlich geklickt. Lassen Sie mich den Code ausprobieren, den ich mir vorgestellt habe, und ich melde mich zurück.
Chip Bennett
4

Ich weiß, dass dies eine alte Frage ist, aber ich werfe meine zwei Cent ein, nur für den Fall, dass jemand anderes mitkommt. Eine einfachere Möglichkeit besteht darin, eine eigene Modifikation der add_settings_section()Funktion zu schreiben , bei der nur am Ende ein Callback-Parameter args hinzugefügt wird.

Das würde so aussehen (oder so ähnlich)

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

Jetzt würden Sie einfach diese Funktion anstelle der nativen WordPress-Funktion verwenden und wie folgt über die 'callbackargs'Array-Taste auf Ihre Callback-Argumente zugreifen

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

Womit wir eine andere Funktion übergeben könnten:

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

Oder die Callback-Argumente könnten selbst ein Array sein, das wir verwenden:

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

Dies ist alles möglich, da add_settings_section()der $wp_settings_sectionsglobalen Variablen lediglich ein neues Arraymitglied hinzugefügt wird. Dieses neue Arraymitglied kann ein Array sein, das eine beliebige Anzahl von Schlüsseln mit unterschiedlichen Namen enthält, die von jeder Funktion verwendet werden können, die wusste, dass sie vorhanden sind. Wenn do_settings_sectionsdie Anrufe call_user_func_arrayübergibt es eine $sectionsParamater wie Bainternet erwähnt, bedeutet dies , dass das gesamte Array fügten wir $wp_settings_sectionsin my_add_settings_section()in unserem Rückruf geführt wird, bedeutet , dass wir Zugang zu jedem neuen Array Mitglied haben wir es wie die hinzufügen , callbackargsso dass unsere Funktion eine vollständige haben flügge Rückruf.

Obwohl ich mir sicher bin, dass dies offensichtlich sein könnte, dachte ich, dass ich es nur erklären würde, falls jemand, der verwirrt ist, hereinschaut.

Cikica
quelle
0

Sie können auch immer einen allgemeineren Ansatz verwenden und nicht nach der bestimmten Funktionsimplementierung suchen (dh ohne zu prüfen, ob add_settings_section implizit etwas übergibt). Dieser allgemeine Ansatz verwendet PHP-Closure.

So verwenden Sie es: Übergeben Sie an jeder Stelle, an der Sie einen Funktionsnamen übergeben, eine anonyme Funktion, die Sie verwenden.

Beispiel:

Anstatt von

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

function callback_name() {
    do_something();
}

Sie können verwenden:

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
quelle