설정 API의 장점은 무엇입니까?


13

WordPress에서 거의 작업하지 않는다는 말로이 서문을 시작하겠습니다. 실제로 WordPress에서 사이트를 마지막으로 방문했을 때 2.2로 돌아 왔습니다. 어제 나는 모든 것을 엉망으로 만들고 기본 메뉴 플러그인을 작동 시키려고 몇 가지 질문을했습니다.

이제 플러그인이 제대로 작동하고 예상대로 작동하므로 Settings API 사용을 포함하여 기능과 호환성을 추가하기 위해 여기에서 약간 변경하기로 결정했습니다. 그러나이 API에 대한 자습서를 읽는 순간이 매우 혼란스러워서 혼란스러워졌고 예제를 읽고 구현하려고 시도했을 때만 혼란이 심화되었습니다. .

내가 잘못하고 있지 않는 한, 설정 API를 사용하는 것으로 이해하려면 새로운 설정 PER 기능을 만들어야합니다. 이는 평균 플러그인의 경우 3-5 개의 기능을, 고급 플러그인의 경우 최대 수백 가지를 의미합니다. 적용 가능한 모든 $_POST변수를 배열 로 쉽게 가져 와서 전체 혼란을 포기할 수있을 때이 많은 함수를 작성하고 혼동하지 않도록 명명 시스템을 개발하는 것이 터무니없는 것 같습니다 .

아마도 나는 구식이지만, 얻을 것이 없다면, 내가 쓰고있는 코드의 양을 3 배 또는 4 배로 늘릴 이유를 알지 못합니다. 설정 API를 추가하기 전에 옵션을 관리하는 방법은 다음과 같습니다.

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

이제 설정 API를 사용하면 다음과 같은 것이 더 있습니다.

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

스크롤바에서 코드가 이미 두 가지 옵션으로 더 길다는 것은 고통 스럽습니다. 내가하고있는 일을 완전히 이해하지 못한다는 의견에서 마찬가지로 분명합니다. 그런 다음이 모든 기능을 수행하기 위해 5 개의 새로운 기능을 갖추어야합니다 (1 만 제거).

그렇다면이 모든 추가 작업에서 어떤 이점이 있습니까?


그러한 경우에는 사용하지 마십시오. 플러그인 / 테마 안에 3-4 옵션이 필요한 PHP 초보자를위한 것이라고 생각합니다. 이것은 구현되지
않았어야

3
난 내가, 모두가 당신이 그것을 사용하는 방법을 따라, 쓰기 당신도 사용하지 않고 API를 사용할 수 있습니다 모든 것을 설정 API를 사용 add_settings_section하고 add_settings_field더 무엇보다, 사람들을 피하고 당신이 팽창하지 않도록,이 두 기능은 코드에 부풀게를 추가 ..
t31os

1
t3los와 동일한 작업을 수행합니다. 설정 자체를 등록한 다음 설정 페이지에서 HTML 형식으로 코드를 작성합니다. 이 작업을 수행하고 나중에 코드를 유지하는 가장 쉬운 방법을 보려면 Yoast의 WordPress SEO 플러그인을 확인하십시오.
chrisguitarguy

답변:


8

내 관점은 Settings API의 주요 목적과 이점이 구조라는 것 입니다.

복잡한 설정을 유지하는 데 도움이됩니다.

  • 질서 정연한 (등록 및 섹션의 논리);
  • 보안 (nonces, 유효성 검사 콜백);
  • 확장 가능 (다른 페이지에 연결하거나 연결 가능).

이러한 구조적 오버 헤드와 마찬가지로보다 복잡한 사용 사례에 도움이되고 덜 간단한 경우에 이점이 있습니다.

따라서 설정 API를 사용하지 않고 수행하는 모든 것을 구현할 수 있습니다. 문제는 신뢰할 수 있고 안전하며 확장 가능한 방식으로이를 달성 할 수 있는지입니다.


마지막 으로이 튜토리얼의 alisothegeek.com/2011/01/wordpress-settings-api-tutorial-1 에서 Settings 페이지와 help 문을 사용하고 switch 문과 helper 함수를 사용하여 설정이 더 정돈되었다고 말해야합니다. 내 코드에서 (두 테스트 설정에서 15-20 총 설정으로 이동하려고 계획 한 이후로 좋습니다).
stevendesu

1
@steven_desu yep, 실행 농담은 Settings API를 사용하는 모든 사람이 프레임 워크를 작성한다는 것입니다. :) 커플 도우미 기능은 거의 불가피합니다. 또한 설정 API는 확정 된 것으로 간주되지 않으며 향후 개선 계획이 모호합니다 (3.3 계획의 맥락에서 언급 된 것 같습니다).
Rarst

1
확실히 개선되기를 바랍니다. 솔직히 Settings API에는 이점이 없지만 지금 즐기고있는 모든 이점은 내가 빌린 프레임 워크의 결과입니다. 모든 양식 요소가 동일한 모양으로 동적으로 생성되는 것을 좋아하지만 설정 API는 아닙니다. 나는 기본 설정과 등록 설정이 동일한 정의로 처리되는 것을 좋아하지만 설정 API는 아닙니다. 내가 jQuery를 꽤 양식을 만들지 만, 점진적으로 향상뿐만 아니라 같은 - ...하지만 수동으로 코드에 점진적 향상이 있었다
stevendesu

5

콜백을 올바르게 사용하면 모든 중복 코드가 필요하지 않습니다. 완전히 확장 가능한 방식으로 설정 API를 구현하는 방법은 다음과 같습니다 .

장점 (다른 것들 중에서) :

  • 설정 API는 신뢰할 수없는 사용자 데이터를 강제로 삭제합니다.
  • 설정 API는 옵션을 옵션 배열로 강제 등록하여 각 옵션에 대한 개별 DB 항목이 아닌 단일 wp_options DB 항목을 생성합니다.
  • 설정 API는 설정 양식의 보안 강화를 용이하게합니다
  • 설정 API는 관리 UI를 핵심 관리 UI와 일치하게하여 UX 개선

그래서 그것은 본질적으로 내가 도움없이 이미 따르고있는 보안 및 미적 표준을 강요합니까? 그래도 당신이 연결 한 튜토리얼을 읽겠습니다. 수동으로 양식을 코딩하는 것만큼이나 쉽게 설정 API를 만드는 경우이 답변을 수락하겠습니다
stevendesu

당신은 소스 코드는 구현 기능을 지적 알고 있습니다 oenology_get_settings_by_tab()oenology_get_default_options적들을 먼저 정의하지 않고? 주석과 빈 줄을 제거한 후 209 줄의 코드에서 충분하지 않다고 생각했지만 해당 함수가 정의되면 더 길어질 것입니다 ... 네 가지 옵션의 경우?
stevendesu

그들은 다른 곳에 정의되어 있습니다. 은 oenology_get_settings_by_tab()당신이 무슨 일을하는지 정말 관련이 없습니다. 하지만 당신은 양식 필드 마크 업 정의 할 곳을 당신이하는 것처럼, 검증 / 살균 사용자 입력에 어떻게 든 당신이 바로 그 일을하고 만약 그렇다면, 당신은 모두 같은 코드를 가지고뿐만 아니라 수 있습니다.
칩 베넷

0

이것을 게시 해 주셔서 감사합니다. 똑같은 것이 궁금합니다. 많은 기능.

이를 줄이려면 옵션을 배열로 저장할 수 있습니다. 워드 프레스가 데이터를 직렬화합니다. 이것은 코드를 저장하거나 어쨌든 기능하지만 데이터를 악화시킵니다. 예를 들어, 테이블을 정렬, 수동 편집, 내보내기 등을 수행하려는 경우 이러한 직렬화 된 값을 갖습니다. 반면, 플러그인은 옵션 테이블에 적은 수의 항목을 추가하여 정리하기가 더 쉽습니다.

여기 코드가 다시 완성되었습니다. 몇 가지 참고 사항 :

  • 내 예제는 간단한 옵션 (de_w, de_h)과 배열 옵션 (de_width_height)을 보여줍니다.
  • 항상 사용자 입력을 삭제하십시오. 소독하기 쉽기 때문에 예제에서 정수를 사용했습니다.
  • 설정 API를 사용할 때 $ _POST, nonces, check_admin_referer (), update_option () 등이 필요하지 않습니다.
  • 저장은 종료 시가 아니라 다음 페이지로드시 발생합니다. 그런 다음 WP는 페이지로 리디렉션합니다. 따라서 디버그하려면 일부 출력을 인쇄하고 유효성 검증 함수 중 하나에서 wp_die ()를 호출하십시오.
  • 폼 액션은 항상 "options.php"입니다. 이것이 설정 API의 작동 방식입니다. 다른 것을 사용하지 마십시오. 원하는 경우 admin_url ( 'options.php')을 사용할 수 있습니다.
  • WP가 저장 메시지를 인쇄합니다.
  • 여기에 포함되지 않은 개선 사항 : <label>접근성 사용. add_settings_error (), settings_error ()를 사용하여 오류 및 메시지를 처리합니다. 각 옵션마다 별도의 유효성 검사 기능이있는 유일한 이유입니다. 아래에서 validate_w () 및 validate_h ()는 하나의 함수가 될 수 있습니다. 메시징을 추상화하려고 시도했지만 리콜 할 때 유효성 검사 콜백에 충분한 정보를 얻지 못했습니다. 어떤 분야에서 일하고 있는가처럼.
  • 유효성 검사 콜백 함수는 설정 API에서 $ _POST 값을 가져옵니다. 매개 변수의 이름을 $ raw로 지정하고 싶습니다. 배열 옵션의 경우 마술과 같은 배열을 얻습니다.
  • 편집 : $ 이것은 & $ this보다 낫습니다.

암호:

<?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;
}
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.