Ayarlar API'sının avantajları nelerdir?


13

WordPress ile neredeyse hiç çalışmadığımı söyleyerek önceden haber vereyim - aslında, WordPress'te son kez bir site yaptığımda 2.2 sırasında geri döndüm. Dün her şeyden bir karışıklık yaptım ve burada temel bir menü eklentisi çalışmaya çalışırken birkaç soru sordum.

Şimdi eklentiyi tamamen işlevsel ve beklediğim gibi davranıyorum, bu yüzden burada ve orada işlevsellik ve uyumluluk eklemeye karar verdim - Ayarlar API'sını kullanmak da dahil. Ancak bu API ile ilgili dersleri okumak için çok kısa bir süre ve oldukça karışık hale geldim, o zaman bu karışıklık sadece okuduğumda derinleşti ve örnekleri uygulamaya çalıştım - bu da eklentimin bir sınıf olarak uygulanmasıyla daha da zorlaştı .

Yanlış bir şey yapmadıkça, Ayarlar API'sini kullanmayı anladığım kadarıyla SETTING başına yeni bir işlev oluşturulmasını gerektirir. Bu, ortalama eklenti için 3-5 işlev ve daha gelişmiş eklentiler için yüzlerce işlev anlamına gelir. Uygulanabilir tüm $_POSTdeğişkenleri bir diziye kolayca aktarabildiğinizde ve tüm karmaşadan vazgeçebildiğinizde, bu birçok işlevi yazmak (ve kafa karıştırmaktan kaçınmak için bir adlandırma sistemi geliştirmek) gülünç görünüyor .

Belki de eski modayım, ama kazanacak bir şey olmadıkça, ne kadar kod yazdığımı üçe katlamak ya da dört katlamak için bir neden görmüyorum. Ayarlar API'sını eklemeye çalışmadan önce seçenekleri şu şekilde yönettim:

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

Şimdi ayarlar API'si ile aşağıdakine benzer bir şeyim var:

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

Kaydırma çubuklarından, kodun zaten iki seçenekle daha uzun olduğu muhtemelen acı verici bir şekilde açıktır. Ne yaptığımı tam olarak anlamadığım yorumlardan anlaşılıyor. Sonra, tüm bunları gerçekleştirmek için 5 yeni fonksiyona sahip olmak (ve sadece 1'i kaldırmak) var.

Peki tüm bu ekstra işlerden ne gibi bir avantaj elde ediyorum?


Bu gibi durumlar için kullanmayın. Bence kendi eklenti / tema içinde 3-4 seçenek ihtiyacı olan PHP yeni başlayanlar için tasarlanmıştır. Bu hiç uygulanmamış olması gereken "özellik" biridir ... Temelde başka bir API için bir API :)
onetrickpony

3
Yazdığım her şey için ayarlar API'sini kullanıyorum, hepsi nasıl kullandığınıza bağlı, API'yı bile kullanmadan kullanabileceğinizi add_settings_sectionve add_settings_fieldbu iki fonksiyonun kodunuza her şeyden daha fazla bloat eklediğini, bunlardan kaçındığını ve şişmeyi önlediğinizi unutmayın.
t31os

1
T3los ile aynı şeyi yapıyorum: ayarın kendisini kaydedin, sonra sadece ayarları sayfamdaki HTML'deki formları kodlarım. Bunu yapmak ve daha sonra kod tutmak için gerçekten kolay bir yol görmek istiyorsanız, Yoast'ın WordPress SEO eklentisine göz atın.
chrisguitarguy

Yanıtlar:


8

Benim bakış açım, Ayarlar API'sının ana amacının ve faydasının yapı olmasıdır .

Karmaşık ayarların korunmasına yardımcı olur:

  • düzenli (kayıt mantığı ve bölümler);
  • güvenli (nonces, validasyon geri aramaları);
  • genişletilebilir (başka bir sayfaya takma veya kancalanmaya izin verme).

Bu tür yapısal yüklerde olduğu gibi, daha karmaşık kullanım durumlarına ve daha az basit olanlara yarar sağlar.

Böylece Ayarlar API'sının herhangi bir şeyi kullanmadan uygulayabilirsiniz. Soru, bunu güvenilir, güvenli ve genişletilebilir bir şekilde gerçekleştirip gerçekleştiremeyeceğinizdir.


Sonunda Ayarlar sayfamı bu öğreticinin yardımıyla çalıştırabildim: alisothegeek.com/2011/01/wordpress-settings-api-tutorial-1 ve anahtar deyimleri ve yardımcı işlevlerin yardımıyla artık şeylerin daha düzenli olduğunu söylemeliyim (iki test ayarımdan 15-20 toplam ayarlara geçmeyi planladığımdan beri güzel).
stevendesu

1
@steven_desu evet, çalışan şaka, Ayarlar API'sini kullanan herkesin bir çerçeve yazmasıdır. :) Çift yardımcı fonksiyonları neredeyse kaçınılmazdır. Ayrıca Ayarlar API'sının sonlandırılmış olarak kabul edilmediğini ve gelecekte geliştirilmesine yönelik (belirsiz) planların olduğunu unutmayın (3.3 plan bağlamında bahsedildiğini düşünüyorum).
Rarst

1
Umarım iyileşmiştir. Dürüst olmak gerekirse, Ayarlar API'sına hiçbir avantaj görmüyorum, ancak şimdi zevk aldığım her avantaj, bunun için ödünç aldığım çerçevenin sonucudur. Tüm form öğelerinin artık aynı görünümde dinamik olarak oluşturulduğunu seviyorum ... ancak bu Ayarlar API'sı değil. Varsayılan ayarların ve kayıt ayarlarının aynı tanımlarla işlenmesini seviyorum ... ancak bu Ayarlar API'sı değil. Ben jQuery sadece formları güzel hale getirmek gibi, ama giderek geliştirilir - ama el ile aşamalı geliştirme kodlamak zorunda ...
stevendesu

5

Geri aramaları doğru kullanırsanız, tüm yedek koda gerek yoktur. Ayarlar API'sını tamamen ölçeklenebilir bir şekilde nasıl uygulayacağım .

Avantajları (diğer şeylerin yanı sıra):

  • Ayarlar API'sı güvenilir olmayan kullanıcı verilerinin dezenfekte edilmesini zorlar.
  • Ayarlar API'sı seçenekleri bir seçenekler dizisi olarak kaydedilmeye zorlar ve her seçenek için ayrı DB girişleri yerine tek bir wp_options DB girişi sağlar.
  • Ayarlar API'sı, ayarlar formunun güvenlikle sertleştirilmesini kolaylaştırır
  • Ayarlar API'sı, çekirdek yönetici kullanıcı arayüzüyle tutarlı yönetici kullanıcı arayüzünü kolaylaştırır ve daha iyi kullanıcı arayüzü sağlar

Yani esasen zaten izlemediğim güvenlik ve estetik standartları onun yardımı olmadan zorlar mı? Bununla birlikte, bağlandığınız öğreticiyi okuyacağım. Ayarlar API'sını formları manuel olarak kodlamak (veya daha kolay) kadar kolay hale
getirirse,

Eğer kaynak kodu uygular işlevlere işaret farkında mısınız oenology_get_settings_by_tab()ve oenology_get_default_optionsşimdiye kadar ilk tanımlayarak olmadan? Ben (yorum ve boş satırları kaldırdıktan sonra) 209 kod satırında yeterince kötü olduğunu düşündüm, ama bu fonksiyonlar tanımlandıktan sonra daha uzun olacak ... Dört seçenek için?
stevendesu

Başka bir yerde tanımlanmışlar. oenology_get_settings_by_tab()Ne yaptığını gerçekten ilgili değildir. Ama sahip formunuz alan biçimlendirme tanımlamak için bir yere sen gibi, sahip validate / sterilize kullanıcı girişine nasılsa sen doğru yapıyoruz eğer öyleyse, tüm bu kodları aynıdır yanı edeceğiz.
Chip Bennett

0

Bunu gönderdiğiniz için teşekkürler, aynı şeyi merak ediyordum. Birçok işlev.

Bunları azaltmak için seçeneklerinizi diziler olarak saklayabilirsiniz. Wordpress verileri sizin için serileştirir. Bu, koddan (veya işlevlerden zaten) tasarruf sağlar, ancak verileri daha da kötüleştirir. Örneğin, tablolarınızı sıralamak, el ile düzenlemek, dışa aktarmak vb. İstiyorsanız, bu serileştirilmiş değerlere sahip olacaklardır. Öte yandan, eklentiniz seçenekler tablosuna daha az girdi ekler ve bunların temizlenmesi daha kolaydır.

İşte kodunuz yeniden yapıldı. Birkaç not:

  • Örneğim hem basit seçenekleri (de_w, de_h) hem de bir dizi seçeneğini (de_width_height) gösterir.
  • Kullanıcı girişini daima sterilize edin. Örnekte tamsayılar kullandım çünkü sanitasyonu kolay.
  • Ayarlar API'sını kullanırken $ _POST, nonces, check_admin_referer (), update_option (), vb. Gerekmez.
  • Kaydetme işlemi, bir sonraki sayfa yüklemesinde gerçekleşir, kapatma sırasında değil. Ardından WP sayfanıza bir yönlendirme yapar. Hata ayıklamak için, bazı çıktıları yazdırın ve doğrulama işlevlerinden birinde wp_die () öğesini çağırın.
  • Form eylemi her zaman "options.php" dir. Ayarlar API'sı bu şekilde çalışır. Başka bir şey kullanmayın. İsterseniz admin_url ('options.php') kullanabilirsiniz.
  • WP sizin için kaydetme mesajını yazdıracaktır.
  • Burada bulunmayan geliştirmeler: <label>erişilebilirlik için kullanma . İletileri ve hataları işleyen add_settings_error (), settings_error () öğesini kullanın. Her seçenek için ayrı doğrulama işlevlerine sahip olmanın tek nedeni genellikle budur. Aşağıda validate_w () ve validate_h () işlevlerinden biri olabilir. Mesajlaşmayı özetlemeye çalıştım, ancak hatırladığım gibi doğrulama geri aramasında yeterli bilgi alamıyorsunuz. Hangi alanda çalıştığın gibi.
  • Doğrulama geri çağırma işlevleri, Ayarlar API'sından ham bir _POST değeri alır. Parametreyi böyle adlandırmak istiyorum, $ raw. Dizi seçeneği için, sihir gibi bir dizi alırsınız.
  • Düzenleme: $ this & $ this daha iyidir.

Kod:

<?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;
}
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.