API การตั้งค่าพร้อมตัวอย่างอาร์เรย์


32

ฉันใช้หนังสือการพัฒนาปลั๊กอิน Wrox WordPress เป็นข้อมูลอ้างอิงหลักสำหรับการเริ่มต้นใช้งานปลั๊กอินใหม่และฉันเข้าใจว่าการตั้งค่าทั้งหมดสามารถบันทึกเป็น 1 อาร์เรย์ได้ แต่หนังสือไม่ได้ยกตัวอย่างของสิ่งนี้และทุกสิ่งที่ฉันต้องการ การค้นหาบนเว็บนั้นแตกต่างจากตัวอย่างหนึ่งไปอีกอย่างหนึ่ง ช่วงครึ่งหลังของการโพสต์โดย Konstantinทำให้ฉันเข้ามาใกล้ แต่ฉันอยากเห็นตัวอย่างที่สมบูรณ์มากขึ้นด้วยหลาย ๆ ฟิลด์

คำตอบ:


32

คำตอบสั้น ๆ : คุณค่าแอตทริบิวต์ต้องใช้คีname option_name[array_key]ดังนั้นเมื่อคุณใช้ ...

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

... คุณได้รับอาร์เรย์เป็นค่าตัวเลือกในฟังก์ชันการตรวจสอบของคุณ:

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

PHP ทำเพื่อคุณนี่ไม่ใช่คุณสมบัติ WordPress :)

วิธีที่จะทำให้การทำงานกับ API การตั้งค่า?

สมมติว่าเราต้องการหน้าตัวเลือกนี้และควรเก็บค่าทั้งหมดไว้ในตัวเลือกเดียวและผ่านการตรวจสอบในฟังก์ชั่นเดียว

ป้อนคำอธิบายรูปภาพที่นี่

หน้าตัวเลือก

เราต้องการadmin_menuฟังก์ชั่นhook และสองฟังก์ชั่นหนึ่งอันเพื่อลงทะเบียนหน้าหนึ่งฟังก์ชั่นเพื่อแสดงผล

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
}

แบบฟอร์มactionต้องเป็นoptions.phpมิฉะนั้นจะไม่สามารถตรวจสอบความถูกต้องได้ ดูที่แหล่ง PHP ของwp-admin/options-permalink.php- มีกับดักที่ซ่อนอยู่do_settings_sections('permalink');- แต่มันไม่สามารถทำงานได้เพราะรูปแบบที่actionผิด

ตอนนี้กลับไปที่หน้ากำหนดเองของเรา เราทำให้ดีกว่า WordPress

ลงทะเบียนการตั้งค่าส่วนและฟิลด์

เราขอadmin_init เมื่อเราต้องการและเรียกฟังก์ชั่นการลงทะเบียน

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

ส่วนที่สำคัญคือ: $GLOBALS['pagenow']ต้องเป็นoptions-general.php(สำหรับเอาต์พุต) หรือoptions.php(สำหรับการตรวจสอบ) อย่าเรียกรหัสต่อไปนี้ทั้งหมดในแต่ละคำขอ บทเรียนส่วนใหญ่และปลั๊กอินเกือบทั้งหมดผิดพลาด

โอเคลองลงทะเบียนกันอย่างบ้าคลั่ง:

  1. เราดึงค่าตัวเลือกสำหรับหน้าของเราและแยกวิเคราะห์ค่าเริ่มต้น ค่อนข้างธรรมดา

  2. plugin:t5_sae_option_groupเราลงทะเบียนกลุ่มการตั้งค่าที่มีชื่อ ฉันชอบชื่อนำหน้าพวกเขาเรียงลำดับได้ง่ายขึ้นและเข้าใจด้วยวิธีนี้

  3. จากนั้นเราลงทะเบียนสองส่วน 1 และ 2

  4. และเราเพิ่มสามส่วนสองส่วนสำหรับส่วนแรกหนึ่งส่วนสำหรับสอง เราส่งชื่อตัวเลือกและค่าEscapeไปยังฟังก์ชันการโทรกลับสำหรับแต่ละฟิลด์ เครื่องมือจัดการผลลัพธ์ไม่ควรเปลี่ยนแปลงข้อมูลเพียงเพิ่ม HTML

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

ตัวจัดการการติดต่อกลับทั้งหมดสำหรับส่วนและฟิลด์จะถูกเรียกโดยอัตโนมัติเมื่อเราโทรdo_settings_sections( 't5_sae_slug' );ในหน้าของเรา เราทำไปแล้วดังนั้นเราต้อง ...

พิมพ์ฟิลด์

หมายเหตุวิธีการnameคุณสมบัติได้รับการสร้างขึ้น: ที่ผ่านมาเป็นส่วนแรกที่สำคัญดังต่อไปนี้อาร์เรย์ในวงเล็บoption_name[]

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

t5_sae_debug_var()โอ้ผมแนะนำฟังก์ชั่น นี่มันคือ:

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

มีประโยชน์เพื่อดูว่าเราได้สิ่งที่เราคาดหวังหรือไม่

ตอนนี้ใช้งานได้ดีเราต้องการเพียงสิ่งเดียว:

ตรวจสอบอาร์เรย์ตัวเลือก

เนื่องจากเราใช้เครื่องหมายวงเล็บค่าของเราจึงเป็นอาร์เรย์ เราแค่ต้องเดินผ่านแต่ละองค์ประกอบและตรวจสอบมัน

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

มันค่อนข้างน่าเกลียด ฉันจะไม่ใช้รหัสดังกล่าวในการผลิต แต่มันทำในสิ่งที่มันควรจะ: มันจะส่งกลับอาร์เรย์ของค่า WordPress จะเรียงลำดับอาเรย์เป็นลำดับเก็บไว้ภายใต้ชื่อตัวเลือกของเราในฐานข้อมูลและส่งคืนค่าแบบไม่ระบุเวลาเมื่อเราเรียกget_option()ใช้


งานทั้งหมดนี้ แต่มันไม่ซับซ้อนที่ไม่จำเป็นเราได้รับมาร์กอัปจากปี 1998 ( <tr valign="top">) และความซ้ำซ้อนมากมาย

ใช้ API การตั้งค่าเมื่อคุณต้องการ เพื่อใช้เป็นทางเลือกadmin_url( 'admin-post.php' )ในการดำเนินการกับแบบฟอร์ม (ดูแหล่งที่มาของมัน) และสร้างหน้าการตั้งค่าที่สมบูรณ์ด้วยโค้ดของคุณเองซึ่งอาจจะดูหรูหรากว่า

ที่จริงแล้วคุณต้องทำอย่างนั้นเมื่อคุณเขียนปลั๊กอินเครือข่ายเนื่องจาก API การตั้งค่าไม่ทำงาน

นอกจากนี้ยังมีเคสขอบและชิ้นส่วนที่ไม่สมบูรณ์ที่ฉันไม่ได้พูดถึงที่นี่คุณจะพบพวกเขาเมื่อคุณต้องการ :)


ว้าวขอบคุณ. สิ่งนี้มีประโยชน์มาก ไม่มีการโพสต์อื่น ๆ ที่ฉันอ่านได้พูดถึงสิ่งใดเกี่ยวกับปลั๊กอินเครือข่ายซึ่งเป็นข้อความสำคัญที่ฉันจะระลึกถึงในอนาคต
Bjorn

เพียงแค่ภาคผนวกของสิ่งนี้ หากคุณพยายามที่จะแสดง / ช่องทำเครื่องหมายเก็บฉันได้เปลี่ยนรหัสโทรกลับเป็น: '<input type = "checkbox" id = "% 3 $ s" name = "% 1 $ s [% 2 $ s] value =" % 4 $ s "'. ถูกทำ
เครื่องหมาย

ตรวจสอบคำตอบที่ฉันสับสนโดยใช้ปลั๊กอิน: t5_sae_option_groupซึ่งรวมถึงโคลอนเดียว ฉันดูละเอียดและไม่พบคำอธิบายของไวยากรณ์นี้ คุณช่วยอธิบายเกี่ยวกับเอกสาร PHP ได้ไหม? ขอบคุณ

@ user50909: สิ่งเหล่านั้นดูเหมือนตัวระบุสตริงแบบง่ายสำหรับฉัน ไวยากรณ์ของ PHP ไม่ควรเป็นปัจจัย
s_ha_dum

1
@ ลองbasename( $_SERVER['REQUEST_URI'] )แล้ว
fuxia
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.