Was sind die Vorteile der Einstellungs-API?


13

Lassen Sie mich vorwegnehmen, dass ich kaum mit WordPress arbeite - tatsächlich war das letzte Mal, dass ich eine Site in WordPress erstellte, 2.2. Gestern habe ich alles durcheinander gebracht und hier einige Fragen gestellt, um ein einfaches Menü-Plugin zum Laufen zu bringen.

Ich habe jetzt das Plugin voll funktionsfähig und verhalte mich genau so, wie ich es erwartet habe. Daher habe ich mich dazu entschlossen, hier und da kleinere Änderungen vorzunehmen, um Funktionalität und Kompatibilität hinzuzufügen - einschließlich der Verwendung der Einstellungs-API. Ein sehr kurzer Moment, in dem ich Tutorials zu dieser API gelesen hatte, und ich war ziemlich verwirrt, dann wurde diese Verwirrung nur noch größer, als ich weiterlas und versuchte, die Beispiele zu implementieren - was durch die Tatsache, dass mein Plugin als Klasse implementiert ist, noch schwieriger wurde .

Sofern ich nichts falsch mache, muss nach meinem Verständnis für die Verwendung der Einstellungs-API eine neue Funktion PRO EINSTELLUNG erstellt werden. Dies bedeutet 3-5 Funktionen für das durchschnittliche Plugin und bis zu Hunderten für fortgeschrittenere Plugins. Es erscheint einfach lächerlich, so viele Funktionen zu schreiben (und ein Benennungssystem zu entwickeln, um sie nicht zu verwirren), wenn Sie genauso einfach alle anwendbaren $_POSTVariablen in ein Array importieren und auf das gesamte Durcheinander verzichten können.

Vielleicht bin ich altmodisch, aber wenn ich nicht etwas davon habe, sehe ich keinen Grund, wie viel Code ich schreibe, um das Dreifache oder Vierfache zu erhöhen. So verwaltete ich Optionen, bevor ich versuchte, die Einstellungs-API hinzuzufügen:

    function __construct() {
        /* constructor stuff */
        $this->options = $this->db_options = get_option( 'de-menu-options' );
        if( $this->options === false ){
            $this->options = $this->defaults;
        }
        if (is_admin()) {
            add_action('admin_menu', array(&$this, 'admin_menu'));
        }   
        /* more stuff */

        // When WordPress shuts down we store changes to options
        add_action('shutdown', array(&$this, 'update'));
    }

    public function admin_menu() {
        add_options_page('DE Menu Options', 'DE Menu', 'manage_options', 'de-menu-options', array(&$this, 'options'));
        add_option('de-menu-options', $this->options);
    }

    public function options() {
        if (!current_user_can('manage_options')) {
            wp_die( __('You do not have sufficient permissions to access this page.') );
        }
        if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
            // These options are saved to the database at shutdown
            $this->options = array(
                "columns" => $_POST["de-menu-columns"],
                "maintenance" => $_POST["de-menu-maintenance"]
            );
            echo 'DE Menu options saved';
        }
?>

<div class="wrap">
    <h2>DE Menu Plugin</h2>
    <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
        <?php settings_fields('de-menu-options'); ?>
        <input type="checkbox" name="de-menu-maintenance" />
        <label for="de-menu-columns">Columns:</label>
        <input type="text" name="de-menu-columns" value="<?php echo $this->options['columns']; ?>" />
        <p class="submit">
        <input type="submit" name="de-menu-submit" value="Update Options »" />
        </p>
    </form>
</div>
<?php
    }

    function update() {
        // By storing all changes at the end we avoid multiple database calls
        $diff = array_diff( $this->options, $this->db_options );
        if( !empty( $diff )  ){
            update_option('de-menu-options', $this->options);
        }
    }

Jetzt habe ich mit der Einstellungs-API etwas Ähnliches:

    function __construct() {
        /* constructor stuff */
        // Do I load options? Will they be loaded for me? Who knows?
        if (is_admin()) {
            add_action('admin_menu', array(&$this, 'admin_menu'));
            add_action('admin_init', array(&$this, 'admin_init'));
        }   
        /* more stuff */
        // Settings API should update options for me... I think
    }

    public function admin_menu() {
        add_options_page('DE Menu Options', 'DE Menu', 'manage_options', 'de-menu-options', array(&$this, 'options'));
        add_option('de-menu-options', $this->options);
    }

    public function admin_init() {
        register_setting('de-menu-options','de-menu-options',array(&$this,'validate'));
        add_settings_section('de-menu-main-options', 'Main Settings', 'options_section', 'de-menu-options');
        add_settings_field('de-menu-maintenance', 'Maintenance Mode', array(&$this,'options_maintenance'), 'de-menu-options', 'de-menu-main-options');
        add_settings_field('de-menu-columns', 'Columns', array(&$this,'options_columns'), 'de-menu-options', 'de-menu-main-options');
    }

    public function options() {
        if (!current_user_can('manage_options')) {
            wp_die( __('You do not have sufficient permissions to access this page.') );
        }
        if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
            // These options are saved to the database at shutdown
            $this->options = array(
                "columns" => $_POST["de-menu-columns"],
                "maintenance" => $_POST["de-menu-maintenance"]
            );
            echo 'DE Menu options saved';
        }
?>

<div class="wrap">
    <h2>DE Menu Plugin</h2>
    <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
        <?php settings_fields('de-menu-options'); ?>
        <?php do_settings_sections('de-menu-options'); ?>
        <p class="submit">
        <input type="submit" name="de-menu-submit" value="Update Options »" />
        </p>
    </form>
</div>
<?php
    }

    public function options_section() {
        echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>';
    }

    public function options_maintenance() {
        echo "<input id='de-menu-maintenance' name='options[maintenance]' type='checkbox' />";
    }

    public function options_columns() {
        echo "<input id='de-menu-columns' name='options[columns]' type='checkbox' value=".$this->options['columns']."/>";
    }

    function validate($options) {
        return $options; // I guess?
    }

An den Bildlaufleisten ist wahrscheinlich schmerzlich zu erkennen, dass der Code mit nur zwei Optionen bereits länger ist. Aus den Kommentaren geht ebenfalls hervor, dass ich nicht ganz verstehe, was ich tue. Dann muss man 5 neue Funktionen haben (und nur 1 entfernen), um all dies zu erreichen.

Welchen Vorteil habe ich von all dieser zusätzlichen Arbeit?


Verwenden Sie sie nicht für solche Fälle. Ich denke, sie sind für PHP-Anfänger gedacht, die 3-4 Optionen in ihrem Plugin / Theme benötigen. Dies ist eine der "Funktionen", die niemals implementiert werden sollten ... Es ist im Grunde eine API für eine andere API :)
onetrickpony

3
Ich verwende die Einstellungen API für alles , was ich schreibe, es hängt alles wie Sie es verwenden, beachten Sie die API ohne auch nur mit verwenden können , add_settings_sectionund add_settings_fielddiese beiden Funktionen hinzufügen aufblasen , um Ihren Code mehr als alles andere, vermeiden diese und Sie die aufblasen vermeiden ..
T31OS

1
Ich mache dasselbe wie t3los: registriere die Einstellung selbst, dann codiere ich einfach die Formulare in HTML auf meiner Einstellungsseite. Wenn Sie eine wirklich einfache Möglichkeit suchen, dies zu tun und den Code für später aufzubewahren, schauen Sie sich das WordPress SEO-Plugin von Yoast an.
Chrisguitarguy

Antworten:


8

Meiner Ansicht nach besteht der Hauptzweck und Nutzen der Einstellungs-API in der Struktur .

Es hilft, komplexe Einstellungs-Setups beizubehalten:

  • ordentlich (Logik der Registrierung und Abschnitte);
  • sicher (Nonces, Validierungs-Callbacks);
  • erweiterbar (in eine andere Seite einbinden oder einbinden lassen).

Wie bei jedem derartigen strukturellen Aufwand ergeben sich Vorteile für komplexere Anwendungsfälle und für weniger einfache.

Sie können also alles implementieren, was die Einstellungs-API tut, ohne sie zu verwenden. Die Frage ist, ob Sie dies auf zuverlässige, sichere und erweiterbare Weise erreichen können.


Mit Hilfe dieses Tutorials habe ich endlich meine Einstellungsseite zum Laufen gebracht : alisothegeek.com/2011/01/wordpress-settings-api-tutorial-1 und mit Hilfe der switch-Anweisungen und der Hilfsfunktionen muss ich sagen, dass die Dinge jetzt geordneter sind in meinem Code (was schön ist, da ich vorhabe, von meinen beiden Testeinstellungen auf 15-20 Gesamteinstellungen zu wechseln).
Stevendesu

1
@steven_desu yep, der letzte Scherz ist, dass jeder, der die Settings API verwendet, ein Framework dafür schreibt. :) Paar Hilfsfunktionen sind fast unvermeidlich. Beachten Sie auch, dass die Einstellungs-API nicht als abgeschlossen gilt und es (vage) Pläne gibt, sie in Zukunft zu verbessern (ich denke, dies wurde im Zusammenhang mit 3.3-Plänen erwähnt).
Rarst

1
Ich hoffe auf jeden Fall, dass es besser wird. Ich sehe ehrlich gesagt keine Vorteile für die Einstellungs-API, aber jeder Vorteil, den ich jetzt genieße, ist das Ergebnis des Frameworks, das ich dafür ausgeliehen habe. Mir gefällt, dass jetzt alle Formularelemente dynamisch mit demselben Erscheinungsbild generiert werden ... aber das ist keine Einstellungs-API. Ich mag, dass Standardeinstellungen und Registrierungseinstellungen von denselben Definitionen behandelt werden ... aber das ist keine Einstellungs-API. Ich mag, dass jQuery nicht nur die Formulare hübsch macht, sondern progressiv verbessert wird - aber ich musste die progressive Verbesserung manuell codieren ...
stevendesu

5

Wenn Sie Rückrufe ordnungsgemäß verwenden, ist nicht der gesamte redundante Code erforderlich. So implementiere ich die Einstellungs-API auf eine Weise, die vollständig skalierbar ist .

Vorteile (unter anderem):

  • Die Einstellungs-API erzwingt die Bereinigung nicht vertrauenswürdiger Benutzerdaten.
  • Die Einstellungs-API erzwingt die Registrierung von Optionen als Optionsarray. Dies führt zu einem einzelnen wp_options-DB-Eintrag und nicht zu diskreten DB-Einträgen für jede Option
  • Die Einstellungs-API erleichtert die Sicherheit des Einstellungsformulars
  • Die Einstellungs-API vereinfacht die Benutzeroberfläche für Administratoren im Einklang mit der zentralen Benutzeroberfläche für Administratoren, was zu einer besseren Benutzeroberfläche führt

Erzwingt es also im Wesentlichen Sicherheits- und ästhetische Standards, denen ich bereits ohne seine Hilfe gefolgt bin? Ich werde das Tutorial durchlesen, das Sie verlinkt haben. Wenn es die Einstellungen-API so einfach macht wie das manuelle Codieren der Formulare (oder einfacher), akzeptiere ich diese Antwort
stevendesu

Sind Sie sich bewusst , dass der Quellcode Sie wies die Funktionen implementiert oenology_get_settings_by_tab()und oenology_get_default_optionsohne jemals zuerst definieren sie? Bei 209 Codezeilen (nach dem Entfernen von Kommentaren und Leerzeilen) fand ich das schon schlimm genug, aber wenn diese Funktionen erst einmal definiert sind, wird es noch länger dauern ... Für vier Optionen?
Stevendesu

Sie sind anderswo definiert. Das oenology_get_settings_by_tab()ist nicht wirklich relevant für das, was du tust. Aber Sie haben Ihr Formular-Feld Markup definieren irgendwo , so wie Sie haben zu validate / sanitize Benutzereingabe irgendwie , also wenn Sie es richtig machen, werden Sie alle am selben Code wie gut.
Chip Bennett

0

Danke, dass du das gepostet hast, ich habe mich genau das Gleiche gefragt. Viele Funktionen.

Um sie zu reduzieren, können Sie Ihre Optionen als Arrays speichern. Wordpress serialisiert die Daten für Sie. Dies spart Code (oder Funktionen), verschlechtert jedoch die Datenqualität. Wenn Sie beispielsweise Ihre Tabellen sortieren, von Hand bearbeiten, exportieren usw. möchten, haben sie diese serialisierten Werte. Auf der anderen Seite fügt Ihr Plugin der Optionstabelle weniger Einträge hinzu und sie sind einfacher zu bereinigen.

Also hier ist dein Code neu geschrieben. Ein paar Anmerkungen:

  • Mein Beispiel zeigt sowohl einfache Optionen (de_w, de_h) als auch eine Array-Option (de_width_height).
  • Benutzereingaben immer bereinigen. In diesem Beispiel habe ich Ganzzahlen verwendet, da diese leicht zu bereinigen sind.
  • Für die Verwendung der Einstellungs-API benötigen Sie nicht $ _POST, nonces, check_admin_referer (), update_option () usw.
  • Das Speichern erfolgt beim nächsten Laden der Seite, nicht beim Herunterfahren. Dann führt WP eine Weiterleitung zu Ihrer Seite durch. Drucken Sie zum Debuggen eine Ausgabe aus und rufen Sie wp_die () in einer der Validierungsfunktionen auf.
  • Die Formularaktion lautet immer "options.php". So funktioniert das Settings API. Verwenden Sie nichts anderes. Nun, Sie können admin_url ('options.php') verwenden, wenn Sie möchten.
  • WP druckt die Sicherungsnachricht für Sie aus.
  • Verbesserungen, die hier nicht enthalten sind: Verwendung <label>für die Barrierefreiheit. Mit add_settings_error (), settings_error (), die sowohl Nachrichten als auch Fehler behandeln. Dies ist oft der einzige Grund, für jede Option separate Validierungsfunktionen zu haben. Unten sehen Sie, dass validate_w () und validate_h () eine Funktion sein können. Ich habe versucht, die Nachrichten zu abstrahieren, aber ich erinnere mich, dass der Validierungsrückruf nicht genügend Informationen enthält. Zum Beispiel, auf welchem ​​Gebiet Sie gerade arbeiten.
  • Die Validierungsrückruffunktionen erhalten einen unformatierten $ _POST-Wert von der Einstellungs-API. Ich nenne den Parameter gerne $ raw. Für die Array-Option erhalten Sie ein Array wie Magic.
  • Bearbeiten: $ das ist besser als & $ das.

Code:

<?php
$foo= new de_Foo();
class de_Foo {
function __construct() {
    if (is_admin()) {
        add_action('admin_menu', array($this, 'admin_menu'));
        add_action('admin_init', array($this, 'admin_init'));
    } 
}
public function admin_menu() {
    add_options_page(
       'DE Menu Options',
       'DE Menu',
       'manage_options',
       'de-menu-options',
       array($this,'xoxptions')
    );
    // add_option('de-menu-options', $this->options);
}
public function admin_init() {
 register_setting(
      'de-menu-settings-group',
      'de_w',
      array($this, 'validate_w')
 );
 register_setting(
      'de-menu-settings-group',
      'de_h',
      array($this, 'validate_h')
 );
 register_setting(
      'de-menu-settings-group',
      'de_width_height',
      array($this, 'validate_width_height')
 );
 add_settings_section(
      'de-menu-settings-section-size',
      'Size',
      array($this, 'settings_section_size_render'),
      'de-menu-options'
 );
 add_settings_field(
      'de_w',
      'W',
      array($this, 'w_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_h',
      'H',
      array($this, 'h_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_width_height',
      'Width / Height',
      array($this, 'width_height_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
}
public function options() {
    if (!current_user_can('manage_options')) {
        wp_die( __('You do not have sufficient permissions to access this page.') );
    }
////////////////////////////
// no no no
////////////////////////////
//         if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
//             // These options are saved to the database at shutdown
//             $this->options = array(
//                 "columns" => $_POST["de-menu-columns"],
//                 "maintenance" => $_POST["de-menu-maintenance"]
//             );
//             echo 'DE Menu options saved';
//         }
////////////////////////////
?>
<div class="wrap">
<h2>DE Menu Plugin</h2>
<form method="post" action="<?php echo admin_url('options.php'); ?>">
    <?php settings_fields('de-menu-settings-group'); ?>
    <?php do_settings_sections('de-menu-options'); ?>
    <p class="submit">
    <input type="submit" name="de-menu-submit" value="Update Options" />
    </p>
</form>
</div>
<?php
}
public function settings_section_size_render() {
    echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>';
}
public function w_render() {
 $w= esc_attr( get_option('de_w') );
 echo "<p><input name='de_w' value='$w'></p>\n";
}
public function h_render() {
 $h= esc_attr( get_option('de_h') );
 echo "<p><input name='de_h' value='$h'></p>\n";
}
public function width_height_render() {
 $width_height= get_option('de_width_height', array());
 $width= esc_attr( @$width_height['width'] );
 $height= esc_attr( @$width_height['height'] );
 echo "<p>Width: <input name='de_width_height[width]' value='$width'></p>\n";
 echo "<p>Height: <input name='de_width_height[height]' value='$height'></p>\n";
}
function validate_w($raw) {
 return (int)$raw;
}
function validate_h($raw) {
 return (int)$raw;
}
function validate_width_height($raw) {
 is_array($raw) or $raw= array();
 $result= array();
 $result['width']= (int)@$raw['width'];
 $result['height']= (int)@$raw['height'];
 return $result;
}
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.