Apa keuntungan dari Pengaturan API?

13

Saya perkenalkan ini dengan mengatakan bahwa saya hampir tidak pernah bekerja dengan WordPress - pada kenyataannya, terakhir kali saya melakukan situs di WordPress adalah kembali selama 2.2. Kemarin saya membuat segalanya berantakan dan mengajukan beberapa pertanyaan di sini mencoba untuk membuat plugin menu dasar berfungsi.

Saya sekarang memiliki plugin berfungsi penuh dan berperilaku tepat seperti yang saya harapkan, jadi saya memutuskan untuk membuat perubahan kecil di sana-sini untuk menambah fungsionalitas dan kompatibilitas - termasuk menggunakan Pengaturan API. Namun sesaat yang sangat singkat dalam membaca tutorial tentang API ini dan saya menjadi sangat bingung, maka kebingungan ini semakin dalam ketika saya membaca dan mencoba mengimplementasikan contoh-contoh - yang menjadi lebih sulit oleh fakta bahwa plugin saya diimplementasikan sebagai sebuah kelas .

Kecuali jika saya melakukan sesuatu yang salah, dari apa yang saya pahami menggunakan Pengaturan API membutuhkan pembuatan fungsi baru PER SETTING. Ini berarti 3-5 fungsi untuk plugin rata-rata, dan hingga ratusan untuk plugin yang lebih maju. Tampaknya konyol untuk menulis banyak fungsi ini (dan mengembangkan sistem penamaan agar tidak membingungkan mereka) ketika Anda bisa dengan mudah mengimpor semua $_POSTvariabel yang berlaku ke dalam array dan melepaskan seluruh kekacauan.

Mungkin saya kuno, tetapi kecuali ada sesuatu yang bisa saya peroleh, saya tidak melihat alasan untuk melipatgandakan atau melipatgandakan berapa banyak kode yang saya tulis. Inilah cara saya mengelola opsi sebelum mencoba menambahkan API Pengaturan:

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

Sekarang dengan pengaturan API saya memiliki sesuatu yang lebih seperti berikut ini:

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

Mungkin sangat jelas dari scrollbar bahwa kode sudah lebih lama hanya dengan dua opsi. Sangat bijaksana dari komentar bahwa saya tidak sepenuhnya mengerti apa yang saya lakukan. Lalu ada masalah memiliki 5 fungsi baru (dan menghapus hanya 1) untuk mencapai semua ini.

Jadi, apa keuntungan yang saya dapatkan dari semua pekerjaan ekstra ini?

stevendesu
sumber
Jangan menggunakannya untuk kasus-kasus seperti itu. Saya pikir mereka ditujukan untuk pemula PHP, yang membutuhkan 3-4 pilihan di dalam plugin / tema mereka. Ini adalah salah satu "fitur" yang seharusnya tidak pernah diimplementasikan ... Ini pada dasarnya adalah API untuk API lain :)
onetrickpony
3
Saya menggunakan pengaturan API untuk semua yang saya tulis, itu semua tergantung bagaimana Anda menggunakannya, perhatikan Anda dapat menggunakan API bahkan tanpa menggunakan add_settings_sectiondan add_settings_field, kedua fungsi menambahkan mengasapi kode Anda lebih dari apa pun, hindari itu dan Anda menghindari mengasapi ..
t31os
1
Saya melakukan hal yang sama seperti t3los: daftarkan pengaturan itu sendiri, lalu saya hanya kode dalam bentuk HTML di halaman pengaturan saya. Jika Anda ingin melihat cara yang sangat mudah untuk melakukan ini dan menyimpan kode untuk nanti, lihat plugin WordPress SEO Yoast.
chrisguitarguy

Jawaban:

8

Pandangan saya adalah bahwa tujuan utama dan manfaat Pengaturan API adalah struktur .

Ini membantu untuk menjaga pengaturan pengaturan yang kompleks:

  • tertib (logika pendaftaran dan seksi);
  • secure (nonces, validback callbacks);
  • extensible (menghubungkan ke halaman lain atau memungkinkan untuk dihubungkan ke).

Seperti halnya overhead struktural seperti itu, manfaat kasus penggunaan lebih kompleks dan manfaat yang kurang sederhana.

Jadi Anda dapat mengimplementasikan apa pun yang dilakukan Pengaturan API tanpa menggunakannya. Pertanyaannya adalah apakah Anda dapat melakukannya dengan cara yang dapat diandalkan, aman, dan dapat diperluas.

Jarang
sumber
Saya akhirnya mendapatkan halaman Pengaturan saya bekerja dengan bantuan dari tutorial ini: alisothegeek.com/2011/01/wordpress-settings-api-tutorial-1 dan dengan bantuan pernyataan pergantian dan fungsi pembantu saya harus mengatakan bahwa semuanya sekarang lebih teratur dalam kode saya (yang bagus karena saya berencana untuk pindah dari dua pengaturan tes saya ke pengaturan total 15-20).
stevendesu
1
@steven_desu ya, lelucon yang berjalan adalah bahwa semua orang yang menggunakan Pengaturan API menulis kerangka kerja untuk itu. :) Fungsi pasangan pembantu hampir tidak bisa dihindari. Juga perhatikan bahwa Pengaturan API tidak dianggap selesai dan ada (tidak jelas) rencana untuk memperbaikinya di masa mendatang (saya pikir itu disebutkan dalam konteks 3,3 rencana).
Rarst
1
Saya tentu berharap ini membaik. Jujur saya tidak melihat keuntungan dari Pengaturan API, tetapi setiap keuntungan yang saya nikmati sekarang adalah hasil dari kerangka kerja yang saya pinjam untuk itu. Saya suka bahwa semua elemen formulir sekarang dihasilkan secara dinamis dengan tampilan yang sama ... tapi itu bukan Pengaturan API. Saya suka bahwa pengaturan default dan pengaturan registrasi ditangani oleh definisi yang sama ... tapi itu bukan Pengaturan API. Saya suka jQuery tidak hanya membuat formulir cantik, tetapi semakin ditingkatkan - tetapi saya harus secara manual kode peningkatan progresif ...
stevendesu
5

Jika Anda menggunakan panggilan balik dengan benar, tidak perlu untuk semua kode yang berlebihan. Inilah cara saya menerapkan API Pengaturan, dengan cara yang sepenuhnya dapat diskalakan .

Keuntungan (antara lain):

  • Pengaturan API memaksa sanitasi data pengguna yang tidak dipercaya.
  • Pengaturan API memaksa opsi untuk didaftarkan sebagai array opsi, menghasilkan entri DB wp_options tunggal, daripada entri DB diskrit untuk setiap opsi
  • Pengaturan API memfasilitasi pengerasan keamanan dari bentuk pengaturan
  • Pengaturan API memfasilitasi admin UI konsisten dengan UI admin inti, menghasilkan UX yang lebih baik
Chip Bennett
sumber
Jadi itu pada dasarnya memaksa standar keamanan dan estetika yang sudah saya ikuti tanpa bantuannya? Saya akan membaca tutorial yang Anda tautkan. Jika itu membuat Pengaturan API semudah mengkode formulir secara manual (atau lebih mudah) maka saya akan menerima jawaban ini
stevendesu
Apakah Anda sadar bahwa kode sumber yang Anda tunjuk mengimplementasikan fungsi oenology_get_settings_by_tab()dan oenology_get_default_optionstanpa terlebih dahulu mendefinisikannya? Saya pikir itu cukup buruk pada 209 baris kode (setelah menghapus komentar dan baris kosong), tetapi begitu fungsi-fungsi itu didefinisikan akan lebih lama lagi ... Untuk empat opsi?
stevendesu
Mereka didefinisikan di tempat lain. Tidak oenology_get_settings_by_tab()benar-benar relevan dengan apa yang Anda lakukan. Tetapi Anda harus mendefinisikan markup formulir-bidang Anda di suatu tempat , sama seperti Anda harus memvalidasi / membersihkan input pengguna entah bagaimana , jadi jika Anda melakukannya dengan benar, Anda akan memiliki semua kode yang sama juga.
Chip Bennett
0

Terima kasih telah memposting ini, saya ingin tahu hal yang persis sama. Banyak sekali fungsi.

Untuk menguranginya, Anda dapat menyimpan opsi sebagai array. Wordpress membuat serial data untuk Anda. Ini menghemat kode (atau fungsi tetap), tetapi membuat data lebih buruk. Misalnya, jika Anda ingin mengurutkan, mengedit tangan, mengekspor, dll, tabel Anda, mereka akan memiliki nilai-nilai serial ini. Di sisi lain, plugin Anda menambahkan lebih sedikit entri ke tabel opsi dan lebih mudah dibersihkan.

Jadi, inilah kode Anda yang dilakukan ulang. Beberapa catatan:

  • Contoh saya menunjukkan opsi sederhana (de_w, de_h) dan opsi array (de_width_height).
  • Selalu bersihkan input pengguna. Saya menggunakan bilangan bulat dalam contoh karena mereka mudah dibersihkan.
  • Anda tidak perlu $ _POST, nonces, check_admin_referer (), update_option (), dll., Saat menggunakan API Pengaturan.
  • Simpan terjadi pada pemuatan halaman berikutnya, bukan pada saat shutdown. Kemudian WP melakukan redirect ke halaman Anda. Jadi untuk debug, cetak beberapa output dan panggil wp_die () di salah satu fungsi validasi.
  • Bentuk tindakan selalu "options.php." Begitulah cara kerja Pengaturan API. Jangan gunakan yang lain. Nah, Anda dapat menggunakan admin_url ('options.php') jika Anda mau.
  • WP akan mencetak pesan penyimpanan untuk Anda.
  • Perangkat tambahan tidak termasuk di sini: menggunakan <label> untuk aksesibilitas. Menggunakan add_settings_error (), settings_error (), yang menangani pesan dan juga kesalahan. Itu sering menjadi satu-satunya alasan untuk memiliki fungsi validasi yang terpisah untuk setiap opsi. Anda dapat melihat di bawah ini validate_w () dan validate_h () bisa menjadi satu fungsi. Saya melihat mencoba abstrak keluar pesan, tetapi Anda tidak mendapatkan info yang cukup dalam panggilan balik validasi seingat saya. Seperti bidang apa yang sedang Anda kerjakan.
  • Fungsi panggilan balik validasi mendapatkan nilai $ _POST mentah dari API Pengaturan. Saya suka memberi nama parameternya, $ raw. Untuk opsi larik, Anda mendapatkan larik, seperti sulap.
  • Sunting: $ ini lebih baik dari & $ ini.

Kode:

<?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;
}
}
Kitchin
sumber