Những lợi thế của API cài đặt là gì?


13

Hãy để tôi nói trước điều này bằng cách nói rằng tôi hầu như không bao giờ làm việc với WordPress - thực tế, lần cuối cùng tôi làm một trang web trong WordPress đã trở lại trong suốt 2.2. Hôm qua tôi đã làm khá nhiều thứ lộn xộn và hỏi một số câu hỏi ở đây để cố gắng để một plugin menu cơ bản hoạt động.

Bây giờ tôi có plugin đầy đủ chức năng và hoạt động chính xác như tôi mong đợi, vì vậy tôi quyết định thực hiện các thay đổi nhỏ ở đây và ở đó để thêm chức năng và khả năng tương thích - bao gồm sử dụng API Cài đặt. Tuy nhiên, một thời gian rất ngắn để đọc hướng dẫn về API này và tôi đã khá bối rối, sau đó sự nhầm lẫn này chỉ sâu sắc hơn khi tôi đọc và cố gắng thực hiện các ví dụ - điều này thậm chí còn khó khăn hơn bởi thực tế là plugin của tôi được triển khai như một lớp .

Trừ khi tôi đang làm gì đó sai, từ những gì tôi hiểu để sử dụng API Cài đặt yêu cầu tạo ra một chức năng mới PER SETTING. Điều này có nghĩa là 3-5 chức năng cho plugin trung bình và lên đến hàng trăm cho các plugin nâng cao hơn. Việc viết nhiều hàm này có vẻ lố bịch (và phát triển một hệ thống đặt tên để tránh nhầm lẫn chúng) khi bạn có thể dễ dàng nhập tất cả các $_POSTbiến có thể vào một mảng và từ bỏ toàn bộ mớ hỗn độn.

Có lẽ tôi đã lỗi thời, nhưng trừ khi có thứ gì đó để kiếm được từ nó, tôi không thấy lý do để tăng gấp ba hoặc gấp bốn lần số lượng mã tôi đang viết. Đây là cách tôi quản lý các tùy chọn trước khi thử thêm API Cài đặt:

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

Bây giờ với API cài đặt, tôi có một cái gì đó giống như sau:

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

Có lẽ rất rõ ràng từ các thanh cuộn rằng mã đã dài hơn chỉ với hai tùy chọn. Rõ ràng là rất rõ ràng từ những bình luận rằng tôi hoàn toàn không hiểu những gì tôi đang làm. Sau đó, có vấn đề về việc có 5 chức năng mới (và chỉ loại bỏ 1) để thực hiện tất cả điều này.

Vì vậy, tôi có được lợi thế gì từ tất cả các công việc làm thêm này?


Không sử dụng chúng cho các trường hợp như vậy. Tôi nghĩ rằng chúng được dành cho người mới bắt đầu PHP, những người cần 3-4 tùy chọn bên trong plugin / theme của họ. Đây là một trong những "tính năng" không bao giờ được triển khai ... Về cơ bản, đó là API cho một API khác :)
onetrickpony

3
Tôi sử dụng API cài đặt cho mọi thứ tôi viết, tất cả phụ thuộc vào cách bạn sử dụng nó, lưu ý rằng bạn có thể sử dụng API mà không cần sử dụng add_settings_sectionadd_settings_fieldhai chức năng đó thêm mã hóa vào mã của bạn hơn bất cứ điều gì, tránh những điều đó và bạn tránh sự phình to ..
t31os

1
Tôi làm điều tương tự như t3los: tự đăng ký cài đặt, sau đó tôi chỉ viết mã trong các biểu mẫu trong HTML trên trang cài đặt của mình. Nếu bạn muốn xem một cách thực sự dễ dàng để làm điều này và giữ mã cho lần sau, hãy xem plugin WordPress SEO của Yoast.
chrisguitarguy

Câu trả lời:


8

Quan điểm của tôi là mục đích và lợi ích chính của API cài đặt là cấu trúc .

Nó giúp giữ các thiết lập cài đặt phức tạp:

  • có trật tự (logic đăng ký và các phần);
  • an toàn (nonces, gọi lại xác nhận);
  • mở rộng (móc vào một trang khác hoặc cho phép được nối vào).

Như với bất kỳ chi phí cấu trúc như vậy, nó mang lại lợi ích cho các trường hợp sử dụng phức tạp hơn và lợi ích cho những trường hợp đơn giản hơn.

Vì vậy, bạn có thể thực hiện bất kỳ điều gì API cài đặt không cần sử dụng. Câu hỏi là nếu bạn có thể thực hiện điều đó theo cách đáng tin cậy, an toàn và mở rộng.


Cuối cùng tôi đã có trang Cài đặt của mình hoạt động với sự trợ giúp từ hướng dẫn này: alisothegeek.com/2011/01/wordpress-sinstall-api-tutorial-1 và với sự trợ giúp của các câu lệnh chuyển đổi và các hàm trợ giúp Tôi phải nói rằng mọi thứ giờ đã có trật tự hơn trong mã của tôi (điều này thật tuyệt vì tôi dự định chuyển từ hai cài đặt thử nghiệm sang tổng số 15-20 cài đặt).
stevendesu

1
@steven_desu yep, trò đùa đang diễn ra là mọi người sử dụng API Cài đặt đều viết một khung cho nó. :) Chức năng trợ giúp cặp đôi là gần như không thể tránh khỏi. Cũng lưu ý rằng API Cài đặt không được xem là hoàn thiện và có các kế hoạch (mơ hồ) để cải thiện nó trong tương lai (tôi nghĩ rằng nó đã được đề cập trong bối cảnh 3,3 kế hoạch).
Hiếm

1
Tôi chắc chắn hy vọng nó được cải thiện. Tôi thực sự thấy không có lợi thế nào đối với API Cài đặt, nhưng thay vào đó, mọi lợi thế tôi đang tận hưởng là kết quả của khung mà tôi đã mượn cho nó. Tôi thích rằng tất cả các thành phần của biểu mẫu hiện được tạo động với cùng một ngoại hình ... nhưng đó không phải là API cài đặt. Tôi thích các cài đặt mặc định và cài đặt đăng ký được xử lý theo cùng một định nghĩa ... nhưng đó không phải là API cài đặt. Tôi thích rằng jQuery không chỉ làm cho các biểu mẫu đẹp hơn, mà còn được tăng cường dần dần - mà tôi phải tự viết mã tăng cường lũy ​​tiến ...
stevendesu

5

Nếu bạn sử dụng các cuộc gọi lại đúng cách, sẽ không cần tất cả các mã dự phòng. Đây là cách tôi triển khai API Cài đặt, theo cách hoàn toàn có thể mở rộng .

Ưu điểm (trong số những thứ khác):

  • API Cài đặt buộc vệ sinh dữ liệu người dùng không tin cậy.
  • API Cài đặt buộc các tùy chọn phải được đăng ký dưới dạng một mảng tùy chọn, dẫn đến một mục nhập DB wp_options duy nhất, thay vì các mục DB riêng biệt cho mỗi tùy chọn
  • API Cài đặt tạo điều kiện tăng cường bảo mật cho biểu mẫu cài đặt
  • API Cài đặt tạo điều kiện cho UI quản trị viên phù hợp với UI quản trị viên cốt lõi, dẫn đến UX tốt hơn

Vì vậy, về cơ bản, nó buộc các tiêu chuẩn an ninh và thẩm mỹ mà tôi đã tuân theo mà không có sự giúp đỡ của nó? Tôi sẽ đọc qua hướng dẫn mà bạn liên kết, mặc dù. Nếu nó làm cho API Cài đặt dễ dàng như mã hóa thủ công các biểu mẫu (hoặc dễ dàng hơn) thì tôi sẽ chấp nhận câu trả lời này
stevendesu

Bạn có biết rằng mã nguồn mà bạn đã chỉ ra để thực hiện các chức năng oenology_get_settings_by_tab()oenology_get_default_optionskhông bao giờ xác định chúng trước? Tôi nghĩ rằng nó đủ tệ ở 209 dòng mã (sau khi xóa nhận xét và dòng trống), nhưng một khi các chức năng đó được xác định, nó sẽ còn dài hơn nữa ... Đối với bốn tùy chọn?
stevendesu

Chúng được định nghĩa ở nơi khác. Điều đó oenology_get_settings_by_tab()không thực sự phù hợp với những gì bạn đang làm. Nhưng bạn phải xác định đánh dấu trường biểu mẫu của mình ở đâu đó , giống như bạn phải xác thực / vệ sinh đầu vào của người dùng bằng cách nào đó , vì vậy nếu bạn làm đúng, bạn cũng sẽ có tất cả mã đó.
Chip Bennett

0

Cảm ơn đã đăng bài này, tôi đã tự hỏi điều tương tự chính xác. Rất nhiều chức năng.

Để giảm chúng, bạn có thể lưu trữ các tùy chọn của mình dưới dạng mảng. Wordpress tuần tự hóa dữ liệu cho bạn. Điều này tiết kiệm mã (hoặc chức năng nào), nhưng làm cho dữ liệu tồi tệ hơn. Chẳng hạn, nếu bạn muốn sắp xếp, chỉnh sửa bằng tay, xuất, v.v., các bảng của bạn, chúng sẽ có các giá trị nối tiếp này. Mặt khác, plugin của bạn thêm ít mục vào bảng tùy chọn và chúng dễ dàng dọn dẹp hơn.

Vì vậy, đây là mã của bạn được thực hiện lại. Một vài lưu ý:

  • Ví dụ của tôi cho thấy cả hai tùy chọn đơn giản (de_w, de_h) và tùy chọn mảng (de_ rắc_height).
  • Luôn vệ sinh đầu vào của người dùng. Tôi đã sử dụng các số nguyên trong ví dụ vì chúng dễ vệ sinh.
  • Bạn không cần $ _POST, nonces, check_admin_Vferer (), update_option (), v.v., khi sử dụng API Cài đặt.
  • Việc lưu xảy ra ở lần tải trang tiếp theo, không phải lúc tắt máy. Sau đó, WP thực hiện chuyển hướng đến trang của bạn. Vì vậy, để gỡ lỗi, in một số đầu ra và gọi wp_die () trong một trong các hàm xác thực.
  • Hành động biểu mẫu luôn là "tùy chọn.php." Đó là cách API Cài đặt hoạt động. Không sử dụng bất cứ thứ gì khác. Chà, bạn có thể sử dụng admin_url ('tùy chọn.php') nếu bạn muốn.
  • WP sẽ in thông báo lưu cho bạn.
  • Cải tiến không bao gồm ở đây: sử dụng <label>cho khả năng tiếp cận. Sử dụng add_sinstall_error (), settings_error (), xử lý các thông báo cũng như các lỗi. Đó thường là lý do duy nhất để có các chức năng xác nhận riêng cho từng tùy chọn. Bạn có thể thấy bên dưới validate_w () và validate_h () có thể là một hàm. Tôi đã xem xét việc cố gắng trừu tượng hóa tin nhắn, nhưng bạn không có đủ thông tin trong cuộc gọi lại xác nhận khi tôi nhớ lại. Giống như lĩnh vực bạn đang làm việc.
  • Các hàm gọi lại xác thực nhận được giá trị $ _POST thô từ API Cài đặt. Tôi thích đặt tên tham số như vậy, $ raw. Đối với tùy chọn mảng, bạn nhận được một mảng, như ma thuật.
  • Chỉnh sửa: $ này tốt hơn & $ này.

Mã số:

<?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;
}
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.