Dizi dizisi ile API ayarları


32

Wrox WordPress eklenti geliştirme kitabını yeni bir eklentiye başlamak için birincil referans olarak kullanıyorum ve tüm ayarların 1 dizi olarak kaydedilebileceğini anlıyorum ancak kitap buna ve benim yaptığım her şeye örnek vermiyor İnternette bulmak bir örnekten diğerine çok farklı görünüyor. Konstantin’in gönderdiği yazının ikinci yarısı beni yaklaştırıyor, ancak çok alanlı daha eksiksiz bir örnek görmek istiyorum.

Yanıtlar:


32

Kısa cevap: nameözellik değerleriniz şema kullanmalıdır option_name[array_key]. Yani, kullandığınızda ...

<input name="option_name[key1]">
<input name="option_name[key2]">

… Doğrulama fonksiyonunuzda bir seçenek değeri olarak bir dizi elde edersiniz:

array (
    'key1' => 'some value',
    'key2' => 'some other value'
)

PHP sizin için yapar, bu bir WordPress özelliği değildir. :)

Bunun ayar API'si ile çalışması nasıl yapılır?

Diyelim ki bu seçenekler sayfasını istiyoruz ve tüm değerler bir seçenekte saklanmalı ve bir işlevde doğrulanmalıdır.

görüntü tanımını buraya girin

Seçenekler sayfası

Kancaya admin_menuve iki işleve ihtiyacımız var : biri sayfayı kaydetmek, biri çıktı oluşturmak için.

add_action( 'admin_menu', 't5_sae_add_options_page' );

function t5_sae_add_options_page()
{
    add_options_page(
        'T5 Settings API Example', // $page_title,
        'T5 SAE',                  // $menu_title,
        'manage_options',          // $capability,
        't5_sae_slug',             // $menu_slug
        't5_sae_render_page'       // Callback
    );
}

function t5_sae_render_page()
{
    ?>
    <div class="wrap">
        <h2><?php print $GLOBALS['title']; ?></h2>
        <form action="options.php" method="POST">
            <?php 
            settings_fields( 'plugin:t5_sae_option_group' );
            do_settings_sections( 't5_sae_slug' ); 
            submit_button(); 
            ?>
        </form>
    </div>
    <?php
}

Form actionolmalı options.php, yoksa doğrulama aranmayacak. PHP kaynağına bakın wp-admin/options-permalink.php- gizli bir tuzak var do_settings_sections('permalink');- ancak form actionyanlış olduğu için çalışamıyor .

Şimdi özel sayfamıza dönün. WordPress'ten daha iyi duruma getirdik.

Ayarları, bölümleri ve alanları kaydet

İhtiyacımız admin_init olduğunda bağ kurar ve bir kayıt fonksiyonu çağırırız.

if ( ! empty ( $GLOBALS['pagenow'] )
    and ( 'options-general.php' === $GLOBALS['pagenow']
        or 'options.php' === $GLOBALS['pagenow']
    )
)
{
    add_action( 'admin_init', 't5_sae_register_settings' );
}

Burada önemli bir parçasıdır: $GLOBALS['pagenow']ya olmalıdır options-general.php(çıkış) veya options.php(doğrulama için). Her istekte aşağıdaki kodların tümünü arama. Çoğu öğretici ve hemen hemen tüm eklentiler bunu yanlış anlıyor.

Tamam, hadi deli gibi kayıt olalım:

  1. Sayfamız için seçenek değerlerini alıyoruz ve bunları bazı varsayılanlara göre ayrıştırıyoruz. Oldukça basit.

  2. İsmi olan bir ayar grubunu kaydettik plugin:t5_sae_option_group. Öneki isimleri severim, sıralama ve bu şekilde anlamaları daha kolaydır.

  3. Sonra 1 ve 2 olmak üzere iki bölüm kaydettik.

  4. Ve ilk bölüm için iki, ikinci bölüm için üç bölüm ekledik. Seçenek adını ve kaçan değeri, her alan için geri çağırma işlevlerine geçiririz. Çıktı işleyicileri verileri değiştirmemelidir, sadece biraz HTML ekleyin.

function t5_sae_register_settings()
{
    $option_name   = 'plugin:t5_sae_option_name';

    // Fetch existing options.
    $option_values = get_option( $option_name );

    $default_values = array (
        'number' => 500,
        'color'  => 'blue',
        'long'   => ''
    );

    // Parse option values into predefined keys, throw the rest away.
    $data = shortcode_atts( $default_values, $option_values );

    register_setting(
        'plugin:t5_sae_option_group', // group, used for settings_fields()
        $option_name,  // option name, used as key in database
        't5_sae_validate_option'      // validation callback
    );

    /* No argument has any relation to the prvious register_setting(). */
    add_settings_section(
        'section_1', // ID
        'Some text fields', // Title
        't5_sae_render_section_1', // print output
        't5_sae_slug' // menu slug, see t5_sae_add_options_page()
    );

    add_settings_field(
        'section_1_field_1',
        'A Number',
        't5_sae_render_section_1_field_1',
        't5_sae_slug',  // menu slug, see t5_sae_add_options_page()
        'section_1',
        array (
            'label_for'   => 'label1', // makes the field name clickable,
            'name'        => 'number', // value for 'name' attribute
            'value'       => esc_attr( $data['number'] ),
            'option_name' => $option_name
        )
    );
    add_settings_field(
        'section_1_field_2',
        'Select',
        't5_sae_render_section_1_field_2',
        't5_sae_slug',  // menu slug, see t5_sae_add_options_page()
        'section_1',
        array (
            'label_for'   => 'label2', // makes the field name clickable,
            'name'        => 'color', // value for 'name' attribute
            'value'       => esc_attr( $data['color'] ),
            'options'     => array (
                'blue'  => 'Blue',
                'red'   => 'Red',
                'black' => 'Black'
            ),
            'option_name' => $option_name
        )
    );

    add_settings_section(
        'section_2', // ID
        'Textarea', // Title
        't5_sae_render_section_2', // print output
        't5_sae_slug' // menu slug, see t5_sae_add_options_page()
    );

    add_settings_field(
        'section_2_field_1',
        'Notes',
        't5_sae_render_section_2_field_1',
        't5_sae_slug',  // menu slug, see t5_sae_add_options_page()
        'section_2',
        array (
            'label_for'   => 'label3', // makes the field name clickable,
            'name'        => 'long', // value for 'name' attribute
            'value'       => esc_textarea( $data['long'] ),
            'option_name' => $option_name
        )
    );
}

Bölümler ve alanlar için tüm bu geri arama işleyicileri, do_settings_sections( 't5_sae_slug' );sayfamızı ziyaret ettiğimizde otomatik olarak aranacaktır . Bunu zaten yaptık, bu yüzden sadece…

Alanları yazdır

nameNiteliklerin nasıl oluşturulduğuna dikkat edin : geçen option_nameilk kısım, dizi anahtarı köşeli parantez içinde izlenir [].

function t5_sae_render_section_1()
{
    print '<p>Pick a number between 1 and 1000, and choose a color.</p>';
}
function t5_sae_render_section_1_field_1( $args )
{
    /* Creates this markup:
    /* <input name="plugin:t5_sae_option_name[number]"
     */
    printf(
        '<input name="%1$s[%2$s]" id="%3$s" value="%4$s" class="regular-text">',
        $args['option_name'],
        $args['name'],
        $args['label_for'],
        $args['value']
    );
    // t5_sae_debug_var( func_get_args(), __FUNCTION__ );
}
function t5_sae_render_section_1_field_2( $args )
{
    printf(
        '<select name="%1$s[%2$s]" id="%3$s">',
        $args['option_name'],
        $args['name'],
        $args['label_for']
    );

    foreach ( $args['options'] as $val => $title )
        printf(
            '<option value="%1$s" %2$s>%3$s</option>',
            $val,
            selected( $val, $args['value'], FALSE ),
            $title
        );

    print '</select>';

    // t5_sae_debug_var( func_get_args(), __FUNCTION__ );
}
function t5_sae_render_section_2()
{
    print '<p>Makes some notes.</p>';
}

function t5_sae_render_section_2_field_1( $args )
{
    printf(
        '<textarea name="%1$s[%2$s]" id="%3$s" rows="10" cols="30" class="code">%4$s</textarea>',
        $args['option_name'],
        $args['name'],
        $args['label_for'],
        $args['value']
    );
}

Oh, bir fonksiyon tanıttım t5_sae_debug_var(). İşte burada:

function t5_sae_debug_var( $var, $before = '' )
{
    $export = esc_html( var_export( $var, TRUE ) );
    print "<pre>$before = $export</pre>";
}

Beklediklerimizi alıp almadığımızı görmek için kullanışlıdır.

Şimdi, bu oldukça iyi çalışıyor, tek bir şeye ihtiyacımız var:

Seçenek dizisini doğrula

Parantez gösterimini kullandığımız için, değerimiz bir dizidir. Sadece her elementin içinden geçip onaylamamız gerekiyor.

function t5_sae_validate_option( $values )
{
    $default_values = array (
        'number' => 500,
        'color'  => 'blue',
        'long'   => ''
    );

    if ( ! is_array( $values ) ) // some bogus data
        return $default_values;

    $out = array ();

    foreach ( $default_values as $key => $value )
    {
        if ( empty ( $values[ $key ] ) )
        {
            $out[ $key ] = $value;
        }
        else
        {
            if ( 'number' === $key )
            {
                if ( 0 > $values[ $key ] )
                    add_settings_error(
                        'plugin:t5_sae_option_group',
                        'number-too-low',
                        'Number must be between 1 and 1000.'
                    );
                elseif ( 1000 < $values[ $key ] )
                    add_settings_error(
                        'plugin:t5_sae_option_group',
                        'number-too-high',
                        'Number must be between 1 and 1000.'
                    );
                else
                    $out[ $key ] = $values[ $key ];
            }
            elseif ( 'long' === $key )
            {
                $out[ $key ] = trim( $values[ $key ] );
            }
            else
            {
                $out[ $key ] = $values[ $key ];
            }
        }
    }

    return $out;
}

Bu oldukça çirkin; Bu tür kodları üretimde kullanmam. Ancak yapması gerekeni yapar: doğrulanmış bir değerler dizisi döndürür. WordPress, diziyi seri hale getirecek, veritabanımızdaki seçenek adımızın altına kaydedecek ve aradığımızda dizileştirilmemiş olarak döndürecektir get_option().


Bunların hepsi işe yarıyor ama gereksiz bir karmaşıklık var, 1998'den ( <tr valign="top">) işaretlendik ve birçok işten çıkarmalar alıyoruz .

Yapmanız gerektiğinde ayarlar API'sini kullanın. Alternatif admin_url( 'admin-post.php' )olarak form eylemi olarak kullanın (kaynağına bakın) ve tüm ayarlar sayfasını kendi, muhtemelen daha şık kodunuzla oluşturun.

Aslında, bir ağ eklentisi yazarken bunu yapmanız gerekir, çünkü ayarlar API'si burada çalışmaz.

Ayrıca burada bahsetmediğim bazı uç kısımlar ve eksik parçalar da var - ihtiyacınız olduğunda onları bulacaksınız. :)


Vay, teşekkürler. Bu çok yardımcı. Okuduğum diğer yayınların hiçbiri ağ eklentileri hakkında bir şeyden bahsetmedi; bu, gelecek için aklımda tutulacak önemli bir not.
Bjorn

Bunun için bir zeyilname. Onay kutularını görüntülemeye / kaydetmeye çalışıyorsanız geri arama kodunu değiştirdim: '<input type = "checkbox" id = "% 3 $ s" name = "% 1 $ s [% 2 $ s] value =" % 4 $ s "'. Kontrol edildi (' açık ', $ args [' değer '], yanlış).' /> '
joesk

Yanıtı gözden geçirme Eklenti kullanımı beni şaşırtıyor: t5_sae_option_group tek bir kolon içeren. Ayrıntılı bir şekilde baktım ve bu sözdiziminin bir açıklamasını bulamadım. Lütfen bunun açıklamalarına PHP belgelerinde yer verebilir misiniz? Thanks

@ user50909: Bunlar bana basit dize tanımlayıcıları gibi görünüyor. PHP sözdizimi bir faktör olmamalıdır.
s_ha_dum

1
@Dan deneyin basename( $_SERVER['REQUEST_URI'] ).
fuxia
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.