WordPress 플러그인에 구성 가능한 필드를 추가하는 3가지 방법

게시 됨: 2022-03-10
빠른 요약 ↬ WordPress 플러그인을 만든 사람이라면 누구나 플러그인 작동 방식을 수정하기 위해 구성 가능한 필드를 생성해야 할 필요성을 이해합니다. 플러그인에서 구성 가능한 옵션에 대한 용도는 셀 수 없이 많으며, 해당 옵션을 구현하는 방법도 거의 같습니다. WordPress를 사용하면 플러그인 작성자가 설정 페이지 내에서 고유한 마크업을 만들 수 있습니다. 부작용으로 설정 페이지는 플러그인마다 크게 다를 수 있습니다. 이 기사에서는 플러그인을 구성할 수 있는 세 가지 일반적인 방법을 살펴보겠습니다. 먼저 설정 페이지를 만들고 기본 WordPress 설정 API를 사용하여 필드를 만듭니다. 그런 다음 사용자 지정 처리기로 필드를 설정하는 방법을 안내합니다. 마지막으로 훌륭한 구성 가능한 필드 플러그인 ACF(Advanced Custom Fields)를 자신의 플러그인에 통합하는 방법을 보여 드리겠습니다.

WordPress 플러그인을 만든 사람은 플러그인 작동 방식을 수정하기 위해 구성 가능한 필드를 생성해야 할 필요성을 이해합니다. 플러그인에서 구성 가능한 옵션에 대한 용도는 셀 수 없이 많으며, 해당 옵션을 구현하는 방법도 거의 같습니다. WordPress를 사용하면 플러그인 작성자가 설정 페이지 내에서 고유한 마크업을 만들 수 있습니다. 부작용으로 설정 페이지는 플러그인마다 크게 다를 수 있습니다.

이 기사에서는 플러그인을 구성할 수 있는 세 가지 일반적인 방법을 살펴보겠습니다. 먼저 설정 페이지를 만들고 기본 WordPress 설정 API를 사용하여 필드를 만듭니다.

SmashingMag에 대한 추가 정보:

  • 사용자 정의 필드로 WordPress 확장
  • WordPress에 대한 사용자 정의 필드 해킹
  • 자신의 컨트롤로 고급 사용자 정의 필드 확장
  • 사용자 정의 포스트 유형에 대한 완전한 가이드

그런 다음 사용자 지정 처리기로 필드를 설정하는 방법을 안내합니다. 마지막으로 훌륭한 구성 가능한 필드 플러그인 ACF(Advanced Custom Fields)를 자신의 플러그인에 통합하는 방법을 보여 드리겠습니다.

점프 후 더! 아래에서 계속 읽기 ↓

이것은 긴 게시물이므로 다음은 각 주요 섹션에 대한 링크가 있는 목차입니다.

  • 플러그인 및 설정 페이지 만들기
  • 접근 방식 1: 내장 WordPress 기능 사용
  • 접근 방식 2: 사용자 지정 양식 및 처리기 설정
  • 접근 방식 3: 플러그인에 ACF(Advanced Custom Fields) 통합

코드 예제는 이 게시물과 함께 제공하기 위해 설정한 저장소를 참조하십시오.

플러그인 및 설정 페이지 만들기

가장 먼저 해야 할 일은 플러그인을 설정하고 설정 페이지를 만드는 것입니다. 이 기사에서 설명하는 세 가지 접근 방식은 모두 아래 플러그인 구조로 시작합니다. 이 플러그인 구조는 객체 지향 이므로 플러그인이 절차적으로 작성된 경우 코드에 약간의 차이가 있을 수 있습니다. 작업 및 필터의 콜백 함수 형식에 특히 주의하십시오.

 /* Plugin Name: Smashing Fields Plugin description: >- Setting up configurable fields for our plugin. Author: Matthew Ray Version: 1.0.0 */ class Smashing_Fields_Plugin { // Our code will go here } new Smashing_Fields_Plugin();

클래스 내에서 설정 페이지를 추가하기 위한 작업 후크를 추가할 것입니다.

 public function __construct() { // Hook into the admin menu add_action( 'admin_menu', array( $this, 'create_plugin_settings_page' ) ); }

작업의 콜백이 create_plugin_settings_page 임을 알 수 있으므로 해당 메서드를 생성해 보겠습니다. 참고: 코드에 컨텍스트를 제공하기 위해 인수를 별도의 명명된 변수로 설정했지만 메모리를 절약하기 위해 함수에 값을 직접 배치할 수 있습니다.

 public function create_plugin_settings_page() { // Add the menu item and page $page_title = 'My Awesome Settings Page'; $menu_title = 'Awesome Plugin'; $capability = 'manage_options'; $slug = 'smashing_fields'; $callback = array( $this, 'plugin_settings_page_content' ); $icon = 'dashicons-admin-plugins'; $position = 100; add_menu_page( $page_title, $menu_title, $capability, $slug, $callback, $icon, $position ); }

자세한 내용은 add_menu_page 에 대한 WP 코덱을 살펴보십시오.

이 기능은 페이지와 메뉴 항목을 생성합니다. 여기서 중요한 부분은 슬러그, 기능 및 콜백 인수입니다. 슬러그는 나중에 필드를 등록하는 데 사용할 것이므로 어딘가에 적어 두십시오. 다른 사용자 수준에서 설정 페이지에 액세스할 수 있도록 기능을 변경할 수 있습니다. 콜백에 관해서는 곧 그 메소드를 생성할 것입니다. 메뉴의 아이콘을 변경하기 위해 함수에 직접 dashicon 클래스를 넣을 수도 있습니다. 마지막 인수는 메뉴 내 메뉴 항목의 위치입니다. 이 숫자를 가지고 놀아 메뉴에서 설정을 적용하고 싶은 지점을 찾으세요. 참고: 십진수 값을 사용하여 다른 메뉴 항목과의 충돌을 방지할 수 있습니다.

다음 단계는 설정 페이지에 대한 plugin_settings_page_content 콜백 메서드를 만드는 것입니다.

 public function plugin_settings_page_content() { echo 'Hello World!'; }

플러그인을 저장하고 WordPress 관리자 패널을 새로 고치면 다음이 표시되어야 합니다.

설정 페이지의 시작 레이아웃
설정 페이지의 시작 상태입니다. (큰 버전 보기)

설정 페이지가 최상위 메뉴 항목임을 알 수 있습니다. 설정 페이지의 필요에 따라 이 방법을 그대로 두는 것이 좋습니다. 그러나 다른 메뉴 항목에서 플러그인 설정을 원할 수도 있습니다. 이 경우 create_plugin_settings_page 메서드의 마지막 줄을 다음과 같이 변경하면 됩니다.

 add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $slug, $callback );

여기에서 add_submenu_page 함수를 add_menu_page 로 변경하고 새 인수를 추가합니다. 해당 인수는 새 설정 페이지가 있는 상위 메뉴 항목입니다. add_submenu_page 문서에서 상위 메뉴 항목과 해당 슬러그에 대한 꽤 좋은 목록을 볼 수 있습니다. 또한 더 이상 마지막 두 인수 $icon$position 이 없다는 것을 알 수 있습니다. 이제 하위 메뉴 섹션에 있으므로 더 이상 요소의 위치를 ​​제어할 수 없습니다. 또한 하위 메뉴에는 사용할 수 있는 아이콘이 없으므로 해당 인수가 필요하지 않습니다.

이 새 코드를 저장하면 설정 메뉴 항목 아래에 설정 페이지가 표시되는 것을 볼 수 있습니다.

하위 메뉴 페이지는 이제 설정 아래에 있습니다.
이제 설정 페이지가 설정 메뉴 아래에 배치되었습니다. (큰 버전 보기)

대부분의 경우 플러그인 설정 페이지를 추가하기에 가장 적절한 위치는 설정 항목 아래입니다. WordPress 코덱스에서는 설정 섹션이 "관리자만 볼 수 있는 플러그인 옵션 표시"에 사용된다고 설명합니다. 그러나 이것은 지침일 뿐 규칙이 아닙니다.

이제 설정 페이지가 설정되고 항목을 이동하는 방법을 알았으므로 필드 작업을 시작할 수 있습니다. 우리가 지금까지 한 작업은 아래의 다양한 방법에 재사용될 것입니다.

접근 방식 1: 내장 WordPress 기능 사용

코드에 대해 더 깊이 들어가기 전에 이 접근 방식을 사용할 때의 장단점을 살펴보겠습니다.

장점

  • 기존 설정 페이지에 쉽게 통합
  • 소독은 당신을 위해 이루어집니다
  • 코드가 워드프레스에서 관리되기 때문에 깨지지 않을 것
  • 테마와 플러그인 모두에 사용할 수 있습니다.
  • 유연하고 안전하며 확장 가능

단점

  • 사용자 지정 데이터 유효성 검사는 수동입니다.
  • 고급 필드 유형(리피터, 지도, 업로드 등)은 구현하기가 더 어렵습니다.

언제 이 접근 방식을 사용해야 합니까?

이 접근 방식은 매우 간단하거나 매우 고급 설정 페이지에 맞게 사용자 지정할 수 있을 만큼 충분히 유연합니다. 수동으로 몇 가지 작업을 수행하는 것이 마음에 들지 않으면 대부분의 상황에서 이 방법을 사용할 수 있습니다.

시작하기

이 접근 방식을 사용하면 WordPress의 자체 옵션 페이지에서 사용하는 것과 동일한 마크업을 따라야 합니다. plugin_settings_page_content 메소드를 다음과 같이 수정해야 합니다.

 public function plugin_settings_page_content() { ?> <div class="wrap"> <h2>My Awesome Settings Page</h2> <form method="post" action="options.php"> <?php settings_fields( 'smashing_fields' ); do_settings_sections( 'smashing_fields' ); submit_button(); ?> </form> </div> <?php }

위의 마크업은 옵션 페이지 생성에 대한 WordPress 코덱스에서 직접 가져온 것입니다. 메소드 이름은 위의 add_menu_page 함수에 넣은 콜백 이름과 일치해야 합니다. 래퍼 div 는 실제로 기본 WordPress 양식과 동일하며 해당 섹션에서 스타일을 가져옵니다. form 태그는 WordPress의 기본 옵션 양식 처리기를 가리키고 있습니다.

PHP의 세 줄은 다음과 같은 몇 가지 작업을 수행합니다.

  • settings_fields 함수는 기본적으로 나머지 필드에 대한 참조입니다. 해당 함수에 입력한 문자열 인수는 이전에 설정한 $slug 변수와 일치해야 합니다. 이는 나중에 플러그인에서 등록하는 모든 필드에 있습니다. 이 함수는 또한 nonce, 양식 작업 및 옵션 페이지에 대한 몇 가지 기타 필드에 대한 몇 가지 숨겨진 입력을 출력합니다.
  • 다음 함수인 do_settings_sections 는 플러그인의 다른 곳에 등록할 섹션과 필드의 자리 표시자입니다.
  • 마지막 함수인 submit_button 은 제출 입력을 출력하지만 페이지 상태에 따라 일부 클래스도 추가합니다. submit_button 함수에 전달하려는 다른 인수가 있을 수 있습니다. 코덱스에 설명되어 있습니다.

설정 페이지를 새로 고치면 다음과 같이 표시됩니다.

빈 WordPress 설정 페이지
섹션 및 필드를 등록하기 전에 설정 페이지.

조금 밋밋해 보이네요! 이제 필드 설정을 시작하겠습니다.

섹션 및 필드

WordPress는 옵션 페이지를 섹션으로 나눕니다. 각 섹션에는 연관된 필드 목록이 있을 수 있습니다. 필드 추가를 시작하기 전에 플러그인에 섹션을 등록해야 합니다. 생성자 함수에 다음 코드를 추가합니다.

 add_action( 'admin_init', array( $this, 'setup_sections' ) );

이 후크는 페이지의 섹션을 설정합니다. 다음은 콜백 코드입니다.

 public function setup_sections() { add_settings_section( 'our_first_section', 'My First Section Title', false, 'smashing_fields' ); }

첫 번째 인수는 섹션의 고유 식별자이며 섹션에 할당하려는 필드에 이를 사용합니다. 이러한 식별자는 이 페이지의 모든 새 섹션에 대해 고유해야 합니다. 다음 인수는 섹션 위에 생성된 제목입니다. 원하는 대로 만들 수 있습니다. 세 번째 인수는 콜백입니다. 지금은 false 로 설정했지만 곧 다시 살펴보겠습니다. 네 번째 인수는 옵션이 추가될 옵션 페이지입니다(이전의 $slug 변수).

그렇다면 왜 콜백에 false 가 있습니까? 문서를 사용하여 WordPress 옵션을 설정할 때 명확하지 않은 점은 여러 섹션에서 콜백을 공유할 수 있다는 것입니다. 종종 콜백을 설정할 때 후크와 콜백 사이에 일대일 관계가 있습니다. 예를 들어 동일한 콜백으로 세 개의 섹션을 만들어 보겠습니다.

 public function setup_sections() { add_settings_section( 'our_first_section', 'My First Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); add_settings_section( 'our_second_section', 'My Second Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); add_settings_section( 'our_third_section', 'My Third Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); }

이 세 섹션 모두 세 번째 인수 슬롯에 콜백 section_callback 이 설정되어 있습니다. 그런 다음 해당 콜백과 일치하는 메서드를 만들고 거기에 "Hello World"를 드롭하면:

 public function section_callback( $arguments ) { echo '

헬로월드

'; }

우리는 다음과 같은 것을 얻습니다.

동일한 콜백 함수를 공유하는 세 섹션
동일한 콜백을 공유하는 세 개의 섹션.

"도대체 내 모든 섹션 아래에 동일한 텍스트를 표시하려는 이유는 무엇입니까?"라고 생각하는 것을 압니다. 대답은 아마도 당신이하지 않을 것입니다. 여기에서 add_settings_section 함수를 사용하여 약간 까다로울 수 있습니다. 해당 함수에 대한 문서를 보면 페이지의 Notes 부분에서 콜백 함수에 후크의 인수와 직접적으로 상관되는 인수 배열이 할당된다는 것을 알 수 있습니다. 들어가서 var_dump( $arguments ) 함수에 전달되는 모든 인수를 볼 수 있습니다.

그런 다음 전달된 ID를 기반으로 텍스트를 변경하기 위해 콜백에 간단한 스위치를 작성할 수 있습니다.

 public function section_callback( $arguments ) { switch( $arguments['id'] ){ case 'our_first_section': echo 'This is the first description here!'; break; case 'our_second_section': echo 'This one is number two'; break; case 'our_third_section': echo 'Third time is the charm!'; break; } }

이제 하나의 기능에서 변경할 수 있는 각 섹션에 대한 사용자 정의 텍스트가 있습니다!

각 섹션 아래의 사용자 정의 텍스트
각 섹션 아래의 사용자 정의 텍스트.

물론 이러한 섹션에 대해 고유한 콜백을 지정할 수도 있지만 이 방법을 사용하면 코드를 단일 함수로 통합할 수 있습니다. 이 아이디어는 필드를 설정할 때도 동일하게 작동합니다. 모든 필드가 콜백을 공유하고 전달한 인수를 기반으로 올바른 필드 유형을 출력하도록 할 수 있습니다. 필드를 생성자 메서드에 추가해 보겠습니다. 생성자에서 섹션 후크 바로 뒤에 이 코드를 삽입하세요.

 add_action( 'admin_init', array( $this, 'setup_fields' ) );

드릴을 이미 알고 있으므로 작업에 대한 콜백을 제공하겠습니다.

 public function setup_fields() { add_settings_field( 'our_first_field', 'Field Name', array( $this, 'field_callback' ), 'smashing_fields', 'our_first_section' ); }

이 함수의 인수는 섹션 함수의 인수와 유사합니다. 첫 번째 인수는 필드의 고유 식별자입니다. 두 번째는 필드 옆에 표시되는 레이블입니다. 세 번째 인수에서 내가 field_callback 메서드를 호출하고 있음을 알 수 있습니다. 우리는 잠시 후에 해당 콜백을 생성할 것입니다. 네 번째는 우리가 사용하려는 옵션 페이지입니다(이전의 $slug ). 다섯 번째 인수는 이 필드를 할당하려는 섹션의 고유 식별자입니다 .

다음은 세 번째 인수의 콜백 코드입니다.

 public function field_callback( $arguments ) { echo '<input name="our_first_field" type="text" value="' . get_option( 'our_first_field' ) . '" />'; }

여기서는 필드의 고유 식별자를 이름, ID 및 get_option 함수에 복사하기만 하면 됩니다. 새 필드가 연결된 페이지가 어떻게 보이는지 봅시다.

첫 번째 필드가 있는 설정 페이지.
첫 번째 필드가 첨부된 설정 페이지.

굉장합니다. 페이지에 우리 필드가 있습니다! 콘텐츠를 추가하고 변경 사항 저장을 눌러 보세요. 여기서 기다리겠습니다...

당신은 그것을 했는가? 지금까지 모든 작업을 수행했다면 ERROR: options page not found 또는 이와 유사한 오류가 발생했을 것입니다. 이것이 발생하는 이유는 실제로 WordPress의 보안 기능입니다.

이 기능이 없으면 사용자가 HTML로 이동하여 필드 이름을 원하는 대로 변경하고 저장을 누르면 주어진 이름으로 데이터베이스에 해당 옵션을 입력할 수 있습니다(유효한 옵션 이름). 이렇게 하면 모든 사용자가 필드에 올바른 이름을 입력하고 저장을 눌러 다른 페이지(일반적으로 액세스할 수 없는 페이지 포함)의 옵션을 변경할 수 있습니다.

이 문제는 register_setting 이라는 함수를 추가하여 해결됩니다. 특별히 WordPress에 "이 필드는 이 페이지에 저장할 수 있습니다"라고 말하지 않는 한 WordPress는 데이터베이스의 필드를 업데이트하지 않습니다. 따라서 필드 마크업 아래에 이 새 기능을 추가합니다. 코드를 추가한 후의 콜백은 다음과 같습니다.

 public function field_callback( $arguments ) { echo '<input name="our_first_field" type="text" value="' . get_option( 'our_first_field' ) . '" />'; register_setting( 'smashing_fields', 'our_first_field' ); }

새 함수의 첫 번째 인수는 필드를 저장하려는 옵션 페이지(이전의 $slug )이고 두 번째 인수는 저장하려는 필드입니다. 이제 필드를 업데이트하고 시도하십시오. 작동했습니다!

축하합니다! WordPress 설정 API를 사용하여 첫 번째 필드를 저장했습니다. 이제 텍스트 대신 다른 필드 유형을 사용하려면 어떻게 해야 할까요? 필드 콜백을 다시 방문하여 함수에 전달되는 $arguments 변수에 대해 이야기해 보겠습니다.

필드 인수

필드 콜백 및 var_dump( $arguments ) 로 이동하면 빈 배열이 표시됩니다. 무엇을 제공합니까? 섹션 콜백에서 섹션에 대한 많은 정보를 얻었습니다. 글쎄요, 여기서 뭔가 다른 일이 벌어지고 있습니다. add_settings_field 에 대한 문서를 확인하면 함수에 전달할 수 있는 다섯 번째 인수가 있습니다. 이 변수는 콜백의 $arguments 변수와 직접적으로 연관됩니다. 그래서 우리는 거기에 우리의 새로운 것들을 넣고 싶어할 것입니다.

WordPress 설정 페이지의 기본 필드 중 하나를 보면 기본 형식을 얻기 위해 필드에 추가할 수 있는 여러 영역이 있음을 알 수 있습니다. 다음은 일반 설정 페이지의 시간대 필드 스크린샷입니다.

WordPress 시간대 필드
WordPress 시간대 필드. (큰 버전 보기)

이 필드를 시작점으로 사용하여 필드 콜백에 ​​전달할 데이터를 살펴보겠습니다.

  • 고유 식별자
  • 필드 레이블(예제에서는 시간대)
  • 어떤 부분에 들어가야 하는지
  • 필드 유형(텍스트, 텍스트 영역, 선택 등)
  • 여러 옵션이 있는 경우 해당 옵션을 원할 것입니다.
  • 필드 유형이 하나를 지원하는 경우 자리 표시자일 수 있습니다.
  • 도우미 텍스트(예제에서 필드 오른쪽)
  • 추가 텍스트(예제에서 필드 아래)
  • 하나가 있는 경우 기본 선택일 수 있습니다.

이 목록에서 콜백에 전달할 수 있는 필드와 값의 연관 배열을 설정할 수 있습니다.

 public function setup_fields() { $fields = array( array( 'uid' => 'our_first_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'text', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ) ); foreach( $fields as $field ){ add_settings_field( $field['uid'], $field['label'], array( $this, 'field_callback' ), 'smashing_fields', $field['section'], $field ); register_setting( 'smashing_fields', $field['uid'] ); } }

따라서 여기서 가장 먼저 우리가 만들고자 하는 모든 필드를 보유할 $fields 라는 변수가 있습니다. 해당 배열 내부에는 각 필드에 대한 특정 데이터를 보유하는 또 다른 배열이 있습니다. 위의 목록과 정확히 일치하도록 데이터를 설정했습니다. 그런 다음 배열의 각 필드(곧 더 추가할 예정)를 반복하고 필드를 추가하고 등록합니다. add_settings_field 함수의 끝에서 콜백 함수에서 몇 가지 작업을 수행할 수 있도록 해당 특정 필드에 대한 전체 데이터 배열도 추가합니다. 여기에서 해당 콜백 함수를 살펴보겠습니다.

 public function field_callback( $arguments ) { $value = get_option( $arguments['uid'] ); // Get the current value, if there is one if( ! $value ) { // If no value exists $value = $arguments['default']; // Set to our default } // Check which type of field we want switch( $arguments['type'] ){ case 'text': // If it is a text field printf( '<input name="%1$s" type="%2$s" placeholder="%3$s" value="%4$s" />', $arguments['uid'], $arguments['type'], $arguments['placeholder'], $value ); break; } // If there is help text if( $helper = $arguments['helper'] ){ printf( '<span class="helper"> %s</span>', $helper ); // Show it } // If there is supplemental text if( $supplimental = $arguments['supplemental'] ){ printf( '<p class="description">%s</p>', $supplimental ); // Show it } }

위의 예에서 우리는 몇 가지 일을 하고 있습니다. 필드가 비어 있고 도우미 및 보충 텍스트를 추가하는 경우 필드의 기본값을 설정하고 있습니다. 하지만 우리 코드에서 가장 중요한 부분은 switch 문입니다. 이 문에서 우리는 우리가 원하는 필드 유형을 기반으로 인수를 처리하는 방법을 간략하게 설명합니다.

예를 들어 텍스트 필드가 있는 경우 여러 옵션이 필요하지 않습니다. 그러나 <select> 드롭다운이 제대로 작동하려면 옵션이 있어야 합니다. 텍스트 유형이 이미 설정되어 있으므로 이 코드를 실행하고 결과를 살펴보겠습니다.

자리 표시자를 포함하여 채워진 필드
자리 표시자 텍스트를 포함하여 필드가 채워졌습니다. (큰 버전 보기)

플러그인 설정 페이지를 로드하면 이 이미지의 상단 필드가 표시되어야 합니다. 맨 아래는 필드(즉, 자리 표시자)에서 콘텐츠를 제거하면 표시되는 것입니다. 필드 배열에서 helper 또는 supplimental 인수를 제거하면 설정 페이지에서 사라져야 합니다. section 인수를 변경하고 섹션에서 필드의 위치를 ​​이동할 수도 있습니다.

자, 텍스트 필드가 있습니다. 좀 더 복잡한 필드 유형은 어떻습니까? switch 문을 다시 살펴보고 텍스트 영역 및 단일 선택에 대한 옵션을 추가해 보겠습니다.

 switch( $arguments['type'] ){ case 'text': // If it is a text field printf( '<input name="%1$s" type="%2$s" placeholder="%3$s" value="%4$s" />', $arguments['uid'], $arguments['type'], $arguments['placeholder'], $value ); break; case 'textarea': // If it is a textarea printf( '<textarea name="%1$s" placeholder="%2$s" rows="5" cols="50">%3$s</textarea>', $arguments['uid'], $arguments['placeholder'], $value ); break; case 'select': // If it is a select dropdown if( ! empty ( $arguments['options'] ) && is_array( $arguments['options'] ) ){ $options_markup = '; foreach( $arguments['options'] as $key => $label ){ $options_markup .= sprintf( '<option value="%s" %s>%s</option>', $key, selected( $value, $key, false ), $label ); } printf( '<select name="%1$s">%2$s</select>', $arguments['uid'], $options_markup ); } break; }

위의 코드에서 각 필드 유형 간에 몇 가지 차이점이 있음을 알 수 있습니다. 텍스트 영역은 기능적으로 일반 텍스트 필드와 유사하지만 다른 마크업이 필요합니다. 선택 드롭다운은 옵션 때문에 완전히 다른 동물입니다. 옵션을 반복하고 값, 선택한 상태 및 레이블을 설정해야 합니다. 따라서 마크업이 크게 다릅니다.

이제 콜백 함수를 업데이트했으므로 필드 데이터가 어떻게 변경되었는지 보겠습니다.

 $fields = array( array( 'uid' => 'our_first_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'text', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ), array( 'uid' => 'our_second_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'textarea', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ), array( 'uid' => 'our_third_field', 'label' => 'Awesome Select', 'section' => 'our_first_section', 'type' => 'select', 'options' => array( 'yes' => 'Yeppers', 'no' => 'No way dude!', 'maybe' => 'Meh, whatever.' ), 'placeholder' => 'Text goes here', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => 'maybe' ) );

다음은 플러그인에서 각기 다른 필드 유형을 사용하는 세 개의 필드입니다. 첫 번째 것은 이미 지나쳤습니다. 두 번째는 새로운 textarea 필드입니다. 배열과 함께 동일한 매개변수를 전달할 수 있지만(UID 제외), 유형을 간단히 변경하면 대신 textarea 을 얻게 됩니다. 이 배열의 마지막 필드는 선택 드롭다운입니다. 여기서 주요 업데이트는 옵션 배열이 추가된 것입니다. HTML 옵션 값으로 배열 키와 레이블이 있는 간단한 연관 배열을 추가합니다. 이 배열을 사용하면 필드가 다음과 같이 표시됩니다.

필드가 채워진 후 설정 페이지
필드가 있는 설정 페이지. (큰 버전 보기)

거의 완료!

이제 작동하는 플러그인 설정 페이지가 있습니다. 페이지에 대한 섹션, 옵션, 모든 콜백을 설정하고 필드를 등록했습니다. 남은 것은 다른 곳에서 설정 값을 가져오는 것뿐입니다. 믿거나 말거나, 우리는 이미 이것을 했습니다. 필드 콜백 상단에서 데이터베이스 값을 확인하는 것을 볼 수 있습니다.

 $value = get_option( $arguments['uid'] );

플러그인(또는 테마)에서 동일한 코드를 사용하고 단순히 uid 를 함수에 전달할 수 있습니다. 따라서 our_first_field 의 값을 얻으려면 간단히 다음과 같이 작성합니다.

 get_option('our_first_field')

헤이 프레스토! 멋진 플러그인과 멋진 설정이 있습니다! 분명히 우리는 몇 가지 필드 유형만 설정했지만 이 접근 방식(특히 텍스트 필드, 암호, 숫자, 텍스트 영역, 선택 드롭다운, 다중 선택, 라디오 버튼 및 확인란)에 대한 코드 저장소를 살펴보고 추가했습니다.

접근 방식 2: 사용자 지정 양식 및 처리기 설정

과거에는 이 접근 방식이 설정 페이지를 추가하는 유일한 방법이었습니다. WordPress 2.7 이전에는 플러그인 작성자가 고유한 사용자 정의 양식과 핸들러를 만들어야 했습니다. 이로 인해 플러그인 간에 많은 버그와 불일치가 발생했습니다. 이 접근 방식은 더 이상 사용되지 않지만 일부 경우에는 여전히 실행 가능한 옵션입니다.

장점

  • 사용자 지정 및 원격 처리기에 양식을 제출할 수 있습니다.
  • 기본 제공 설정 API 제한 중 일부를 우회할 수 있습니다.

단점

  • 개발자가 호환성을 유지해야 합니다.
  • 수동으로 살균 및 검증해야 함

언제 이 접근 방식을 사용해야 합니까?

사용자 정의 처리기 또는 고도로 사용자 정의된 인터페이스가 반드시 있어야 하는 경우 이 접근 방식을 사용하십시오. 대부분의 경우 접근 방식 1을 사용하지 않을 수 있지만 이 방법을 사용하면 유효성 검사 및 처리에 더 많은 유연성이 있습니다.

시작하기

세부 사항에 들어가기 전에 사용자 정의 핸들러를 사용할 시나리오를 생각해 내야 합니다. 편의상 사용자 이름과 이메일 주소를 확인하는 양식을 만들어 보겠습니다. 데이터베이스 또는 원격 서버에서 데이터를 가져올 있습니다. 이 경우 유효한 사용자 이름과 이메일 주소로 배열을 설정하여 확인할 수 있습니다. 그런 다음 사용자가 입력한 필드 값을 저장하고 데이터베이스에 저장합니다.

양식 만들기

이전에 언급했듯이 "플러그인 및 설정 페이지 만들기"에서 수행한 것과 동일한 단계를 따릅니다. 이 접근 방식을 위해 정적 HTML 마크업을 사용하여 필드를 설정합니다. 다음과 같이 plugin_settings_page_content 함수의 콜백에 이 코드를 추가합니다.

 public function plugin_settings_page_content() { ?> <div class="wrap"> <h2>My Awesome Settings Page</h2> <form method="POST"> <table class="form-table"> <tbody> <tr> <th><label for="username">Username</label></th> <td><input name="username" type="text" value="" class="regular-text" /></td> </tr> <tr> <th><label for="email">Email Address</label></th> <td><input name="email" type="text" value="" class="regular-text" /></td> </tr> </tbody> </table> <p class="submit"> <input type="submit" name="submit" class="button button-primary" value="Check My Info!"> </p> </form> </div> <?php }

위에서 필드에 정적 HTML을 추가하고 있음을 알 수 있습니다. 핵심 WordPress 설정 페이지에서 마크업을 복제하고 있습니다. 또한 기본 options.php 핸들러가 아닌 현재 페이지에 양식을 제출하도록 양식 작업을 생략합니다.

사용자 지정 처리기를 작성하기 전에 몇 가지 빠른 보안 기능을 넣어 보겠습니다. 우리가 해야 할 첫 번째 일은 우리 양식에 nonce를 넣는 것입니다. Nonce는 사용자 스푸핑 또는 재생 공격과 유사한 사이트 간 요청 위조 시도로부터 보호합니다. HTML에 nonce를 넣어봅시다.

 <form method="POST"> <?php wp_nonce_field( 'awesome_update', 'awesome_form' ); ?> <table class="form-table">

wp_nonce_field 는 두 개의 숨겨진 필드를 양식에 추가합니다. 논스와 리퍼러. 핸들러 코드를 살펴볼 때 nonce로 다시 돌아올 것입니다.

다음으로 양식이 업데이트되었을 때 감지할 필드를 추가해야 합니다. 양식 상단에 숨겨진 필드를 추가하기만 하면 됩니다.

 <form method="POST"> <input type="hidden" name="updated" value="true" /> <?php wp_nonce_field( 'awesome_update', 'awesome_form' ); ?> <table class="form-table">

이제 페이지 상단에 코드 스니펫을 넣어 양식이 제출될 때 감지하고 사용자 정의 핸들러로 보낼 수 있습니다.

 public function plugin_settings_page_content() { if( $_POST['updated'] === 'true' ){ $this->handle_form(); } ?> <div class="wrap"> <h2>My Awesome Settings Page</h2>

여기서 우리는 단순히 숨겨진 updated 필드가 제출되었는지 확인하고 제출된 경우 플러그인에서 handle_form 이라는 메서드를 호출합니다. 여기에서 커스텀 핸들러 작성을 시작할 수 있습니다.

핸들러 생성

실제로 양식 데이터를 관리하기 전에 핸들러에서 확인해야 할 몇 가지 사항이 있습니다. 먼저 nonce가 존재하고 유효한지 확인해야 합니다.

 public function handle_form() { if( ! isset( $_POST['awesome_form'] ) || ! wp_verify_nonce( $_POST['awesome_form'], 'awesome_update' ) ){ ?> <div class="error"> <p>Sorry, your nonce was not correct. Please try again.</p> </div> <?php exit; } else { // Handle our form data } }

위의 코드는 nonce가 올바른지 확인합니다. 유효하지 않은 경우 양식이 업데이트되지 않은 이유에 대한 메시지를 사용자에게 제공합니다. nonce가 존재하고 정확하면 양식을 처리할 수 있습니다. 이제 양식 처리기에 대한 코드를 작성해 보겠습니다(이 코드는 위 스니펫의 주석을 대체합니다).

 $valid_usernames = array( 'admin', 'matthew' ); $valid_emails = array( '[email protected]', '[email protected]' ); $username = sanitize_text_field( $_POST['username'] ); $email = sanitize_email( $_POST['email'] ); if( in_array( $username, $valid_usernames ) && in_array( $email, $valid_emails ) ){ update_option( 'awesome_username', $username ); update_option( 'awesome_email', $email );?> <div class="updated"> <p>Your fields were saved!</p> </div> <?php } else { ?> <div class="error"> <p>Your username or email were invalid.</p> </div> <?php }

이 섹션의 코드를 살펴보겠습니다. 처음 몇 줄은 확인할 유효한 사용자 이름/이메일의 배열입니다. 이러한 배열 값은 어디에서나 채울 수 있습니다.

다음 두 줄은 사용자가 양식에 입력한 값입니다. WordPress에서 제공하는 내장된 살균 기능을 사용하고 있습니다. 이 단계는 웹 양식의 여러 취약점을 방지하는 데 중요합니다. 다음으로 사용자가 제공한 값이 허용 가능한 값 배열에 있는지 확인합니다. 그렇다면 데이터베이스에서 양식 옵션을 업데이트하십시오. 이 단계는 사용자 지정 저장 메커니즘으로 대체될 수도 있습니다. 또한 사용자에게 필드가 저장되었다는 메시지를 제공합니다. 사용자의 입력이 유효하지 않으면 우리는 그들에게 그렇게 말합니다.

마지막으로 해야 할 일은 입력된 후 양식에 저장된 필드를 표시하는 것입니다. 플러그인의 다른 곳에서 이러한 필드를 검색하는 것과 동일한 방식으로 get_option 함수를 사용하여 이를 수행합니다. 올바른 코드를 추가한 후의 필드는 다음과 같습니다.

 <tr> <th><label for="username">Username</label></th> <td><input name="username" type="text" value="<?php echo get_option('awesome_username'); ?>" class="regular-text" /></td> </tr> <tr> <th><label for="email">Email Address</label></th> <td><input name="email" type="text" value="<?php echo get_option('awesome_email'); ?>" class="regular-text" /></td> </tr>

이제 양식을 테스트할 준비가 되었습니다. 사용자 이름 admin 과 이메일 주소 [email protected] 을 입력해 보십시오. 양식에서 다음을 얻어야 합니다.

올바른 값을 입력한 후 저장된 필드
올바른 값을 입력한 후 저장된 필드. (큰 버전 보기)

두 필드 중 하나를 잘못된 값으로 설정하려고 하면 오류 메시지가 표시되고 사용자 지정 핸들러로 인해 필드가 업데이트되지 않아야 합니다.

이것이 우리의 두 번째 접근 방식입니다! 이제 플러그인 필드를 관리하기 위해 사용자 정의 양식과 핸들러를 설정했습니다. 이 접근 방식에 대한 완성된 코드는 이 기사의 리포지토리에서 찾을 수 있습니다. 이제 최종 접근 방식으로 넘어갑니다.

접근 방식 3: 플러그인에 ACF(Advanced Custom Fields) 통합

Elliot Condon의 ACF를 아직 사용하지 않았다면 소개하겠습니다. ACF는 WordPress의 훌륭한 현장 관리자입니다. 가장 좋은 점 중 하나는 현장 구성 인터페이스입니다. 이것은 WordPress 내의 다양한 페이지(게시물, 페이지, 사용자, 분류, 심지어 자체 통합 옵션 페이지 등)에 대한 필드를 스핀업하는 것을 매우 쉽게 만듭니다. "나는 다른 사람의 플러그인을 내 플러그인에 통합할 수 없습니다. 그건 애매해요!"라고 생각할 수도 있습니다. 그러나 Condon 씨는 동료 개발자들의 곤경을 이해하고 그의 플러그인에서 이를 계획했습니다. 이 주제에 대한 그의 문서를 볼 수 있지만 여기에서 일부를 다시 설명하겠습니다. 규칙을 살펴보겠습니다.

  1. 먼저 무료 플러그인을 배포하는 경우 ACF의 무료 버전을 사용해야 합니다. 이것은 사람들이 무료 플러그인에서 PRO 버전을 얻을 수 없도록 하기 위한 것입니다. 프리미엄 플러그인 및 테마에서 PRO 버전을 문제 없이 사용할 수 있습니다. 개발자 라이선스를 구입하기만 하면 됩니다.
  2. 둘째, ACF의 저작권 정보를 수정하지 마십시오. 그 남자에게 약간의 신용을 줘!
  3. 마지막으로 플러그인과 함께 라이센스 키를 배포하지 마십시오.

이제 이 접근 방식의 장단점:

장점

  • 테마 및 플러그인에 매우 쉽게 통합
  • ACF의 일부인 고급 필드를 활용할 수 있습니다.
  • 코드 및 보안 업데이트는 ACF 팀에서 관리합니다.
  • ACF는 막히는 경우 훌륭한 애드온과 지원을 제공합니다.
  • 필드 구성 UI로 인해 필드 구성이 매우 간단합니다.

단점

  • 마크업에 대한 제한된 액세스
  • 플러그인 또는 테마에 대한 종속성을 생성합니다.
  • ACF를 최신 상태로 유지하려면 플러그인/테마 파일에서 업데이트된 상태로 유지해야 합니다(자세한 정보는 아래 참조).

언제 이 접근 방식을 사용해야 합니까?

고급 설정 인터페이스를 매우 빠르게 구축하려는 경우 모양과 느낌을 사용자 지정할 필요가 없습니다.

시작하기

이 접근 방식을 위해 무료 버전의 ACF에 대한 옵션 페이지를 설정하는 방법을 보여 드리겠습니다. To view a guide on setting up the PRO version check out the ACF documentation. To get started we will be adding ACF to our plugin directory. First, download the latest version of ACF and unzip its contents. In your plugin directory create a (큰 버전 보기)

Again, we will follow the steps we did in “Creating Our Plugin And Settings Page”. Before we get into that, though, we should include ACF in our plugin.

Include ACF In Your Plugin

It's actually pretty easy to include ACF in your plugin – there are only three steps. First we have to include the main ACF file with PHP. Add the following code to the bottom of our constructor function:

 include_once( plugin_dir_path( __FILE__ ) . 'vendor/advanced-custom-fields/acf.php' );

If you refresh the admin you should see a new menu item titled Custom Fields . Before we go into that page and start setting up our fields we need to update a couple of paths in ACF. We need to tell ACF to look for its front-end assets and file includes in our plugin directory instead of its normal place. Add these two hooks to your constructor:

 add_filter( 'acf/settings/path', array( $this, 'update_acf_settings_path' ) ); add_filter( 'acf/settings/dir', array( $this, 'update_acf_settings_dir' ) );

And the callbacks for those hooks:

 public function update_acf_settings_path( $path ) { $path = plugin_dir_path( __FILE__ ) . 'vendor/advanced-custom-fields/'; return $path; } public function update_acf_settings_dir( $dir ) { $dir = plugin_dir_url( __FILE__ ) . 'vendor/advanced-custom-fields/'; return $dir; }

The first callback updates the include paths for the PHP files within the ACF plugin. The second updates the URIs for the ACF assets. Now we can set up our fields.

Configuring Your Fields

Now comes the fun part: the ACF field configuration UI. Add a title and any fields you'd like in your form. There is a great walkthrough of what everything on this page does in the ACF documentation. Here's how I have set up mine:

ACF fields configured
My ACF fields in the configuration UI. (큰 버전 보기)

Once you are ready hit the Publish button on the right and your fields will be saved. Now we have to get the fields we set up into our plugin. Right now they only exist in the database. On the left-hand navigation, click the Tools item. On the new page, select the field group we just created and hit Generate Export Code . This will create a chunk of PHP code that we can now include in our plugin.

To add the options, we need to add a method call to our constructor. Add this line to the end of your constructor after our ACF include:

 $this->setup_options();

Then we can create the method that will wrap our options:

 public function setup_options() { if( function_exists( 'register_field_group' ) ) { register_field_group(array ( 'id' => 'acf_awesome-options', 'title' => 'Awesome Options', 'fields' => array ( array ( 'key' => 'field_562dc35316a0f', 'label' => 'Awesome Name', 'name' => 'awesome_name', 'type' => 'text', 'default_value' => ', 'placeholder' => ', 'prepend' => ', 'append' => ', 'formatting' => 'html', 'maxlength' => ', ), array ( 'key' => 'field_562dc9affedd6', 'label' => 'Awesome Date', 'name' => 'awesome_date', 'type' => 'date_picker', 'date_format' => 'yymmdd', 'display_format' => 'dd/mm/yy', 'first_day' => 1, ), array ( 'key' => 'field_562dc9bffedd7', 'label' => 'Awesome WYSIWYG', 'name' => 'awesome_wysiwyg', 'type' => 'wysiwyg', 'default_value' => ', 'toolbar' => 'full', 'media_upload' => 'yes', ), ), 'location' => array ( array ( array ( 'param' => 'options_page', 'operator' => '==', 'value' => 'smashing_fields', ), ), ), 'menu_order' => 0, 'position' => 'normal', 'style' => 'default', 'label_placement' => 'top', 'instruction_placement' => 'label', 'hide_on_screen' => ', 'active' => 1, 'description' => ', )); } }

Now that we have our fields ready to go, we can add them to the settings page.

Modifying The Settings Page Code

To add the fields we just created to the page we will need to update our plugin_settings_page_content method.

Previously, we set up the form tag for our page. In this case we will let ACF do that part for us. Here is what our updated function should look like:

public function plugin_settings_page_content() { do_action('acf/input/admin_head'); // Add ACF admin head hooks do_action('acf/input/admin_enqueue_scripts'); // Add ACF scripts $options = array( 'id' => 'acf-form', 'post_id' => 'options', 'new_post' => false, 'field_groups' => array( 'acf_awesome-options' ), 'return' => admin_url('admin.php?page=smashing_fields'), 'submit_value' => 'Update', ); acf_form( $options ); }

함수의 처음 두 줄은 설정 필드에 필요한 스크립트와 스타일을 추가하는 것입니다. 그런 다음 양식에 대한 옵션을 구성합니다. field_groups 인수의 값이 register_field_group 함수의 ID와 일치함을 알 수 있습니다. 다른 구성 매개변수를 보려면 acf_form 설명서를 살펴보십시오. 함수의 마지막 줄은 실제로 양식을 렌더링할 것입니다.

지금 설정 페이지를 로드하려고 하면 실제로 페이지가 깨져 있는 것을 볼 수 있습니다. ACF는 JavaScript에 대해 몇 가지 변수를 현지화해야 하기 때문입니다. 이렇게 하려면 생성자에 다른 후크를 추가해야 합니다.

 add_action( 'admin_init', array( $this, 'add_acf_variables' ) );

이제 콜백을 설정해야 합니다.

 public function add_acf_variables() { acf_form_head(); }

콘텐츠를 추가하고 저장을 시도할 수 있으며 다른 두 가지 접근 방식처럼 작동해야 합니다. 다음은 우리 페이지의 모습입니다.

완성된 ACF 양식
완성된 ACF 양식. (큰 버전 보기)

해결해야 할 몇 가지 정리 항목이 있습니다.

  • 플러그인에 ACF를 사용하고 있다는 사실을 숨기고 싶을 수 있습니다. 이 경우 사용자 정의 필드 메뉴 항목을 숨겨야 합니다. 생성자 함수에 이 스니펫을 추가하면 됩니다.

     add_filter( 'acf/settings/show_admin', '__return_false' );
  • 필드 그룹의 데이터베이스 버전을 제거해야 합니다. 사용자 정의 필드 섹션으로 이동하여 휴지통 버튼을 누르십시오. 이 단계는 플러그인을 빌드한 환경에만 영향을 미치므로 선택 사항이지만 동일한 환경에서 플러그인을 테스트하는 경우 문제가 발생할 수 있습니다.

플러그인 내에서 ACF 필드 사용

생성한 ACF 필드를 가져오려면 기본 ACF get_field 함수를 사용하기만 하면 됩니다. 첫 번째 옵션은 필드의 고유 ID여야 하고 두 번째 인수는 'option' 으로 설정되어야 합니다. 굉장한 날짜 필드를 얻는 방법은 다음과 같습니다.

 get_field( 'awesome_date', 'option' )

그리고 그게 다야. 이제 ACF 설정으로 플러그인을 설정했습니다! 저장소에서 이 접근 방식에 대한 코드를 볼 수 있습니다.

결론

플러그인을 구성 가능하게 만드는 세 가지 방법이 있습니다. 이러한 방법을 사용하여 만들 수 있는 플러그인에 대해 듣고 싶습니다. 다시 한 번, 이러한 각 접근 방식에 대한 코드를 보관하는 저장소를 설정했습니다. 자유롭게 포크하고 자신의 필요에 맞게 사용자 정의하십시오.

이러한 접근 방식에 대한 개인적인 선호도는 접근 방식 1에 치우치는 경향이 있습니다. 플러그인의 종속성을 가능한 한 적게 유지하는 것을 선호하며 사용자 지정 프로젝트의 설정 페이지를 테마로 마크업을 사용자 지정할 수 있습니다. 빠른 프로토타입이나 매우 고급 필드를 설정해야 하는 프로젝트의 경우 ACF를 사용하지만 플러그인 업데이트 관리에 복잡성 수준이 추가됩니다.

Scott Clark의 Fields API 제안도 언급할 가치가 있습니다. 현재 여전히 진행 중인 작업이지만 API는 기본적으로 플러그인 및 테마 개발자가 사용자 지정 API와 동일한 인터페이스를 사용하여 관리자 패널의 다른 영역에 설정 필드를 생성할 수 있도록 합니다.

ACF 대안

아래 주석에서 지적한 바와 같이 개발자에게 ACF 접근 방식과 유사한 다른 옵션을 제공하기 위해 다른 기능을 제공할 수 있는 몇 가지 대안을 확인할 수 있습니다. 더 있으면 아래 의견에 제출하십시오! 여기에서는 특별한 순서가 없습니다.

  • WebDevStudios의 CMB2
  • Tran Ngoc Tuan Anh(릴위스)의 Meta Box