การสร้างวิดเจ็ตการค้นหาโดยใช้ WordPress REST API
เผยแพร่แล้ว: 2016-03-28นักพัฒนา WordPress จะทราบดีว่า REST API มีมาระยะหนึ่งแล้ว แต่เมื่อปลายปีที่แล้วได้มีการรวมเข้ากับแกนหลัก ซึ่งหมายความว่าขณะนี้สามารถใช้ประโยชน์ได้ในวิดเจ็ตและปลั๊กอิน
ในบทความนี้ เราจะสร้างวิดเจ็ตการค้นหาแบบง่ายที่มีความแตกต่าง การใช้ WordPress REST API วิดเจ็ตนี้จะค้นหาเว็บไซต์ WordPress ภายนอกและแสดงผลลัพธ์ในวิดเจ็ต
โพสต์นี้ต่อจากบทความล่าสุดของฉันเกี่ยวกับ สิ่งที่คุณต้องรู้เกี่ยวกับ WordPress REST API
สร้างฐานความรู้ที่สามารถค้นหาได้และช่วยให้ลูกค้าของคุณช่วยเหลือตนเอง
รับปลั๊กอินการสร้างปลั๊กอินวิดเจ็ต
ตามบทความที่แล้ว จะถือว่ามีความรู้พื้นฐานเกี่ยวกับการสร้างปลั๊กอินและวิดเจ็ต หากคุณไม่แน่ใจ มีบางสิ่งที่คุณแนะนำให้อ่านที่ส่วนท้ายของบทความนี้
มาดูปลั๊กอินที่เราสร้างไว้ในบทความที่แล้วกัน รหัสของคุณควรมีลักษณะดังนี้:
/**
* Plugin Name: KB - REST API Widget
* Author: Kirsty Burgoine
*/
class REST_API_Widget extends WP_Widget {
/**
* Sets up the widgets name etc
*/
public function __construct() {
$widget_ops = array(
'classname' => 'rest-api-widget',
'description' => 'A REST API widget that pulls posts from a different website'
);
parent::__construct( 'rest_api_widget', 'REST API Widget', $widget_ops );
}
/**
* Outputs the content of the widget
*
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
// outputs the content of the widget
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2 /ht_kb/' );
if( is_wp_error( $response ) ) {
return;
}
$posts = json_decode( wp_remote_retrieve_body( $response ) );
if( empty( $posts ) ) {
return;
}
echo $args['before_widget'];
if( !empty( $instance['title'] ) ) {
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $args['after_title'];
}
// Main Widget Content Here
if( !empty( $posts ) ) {
echo '<ul>';
foreach( $posts as $post ) {
echo '<li><a href="' . $post->link. '">' . $post->title->rendered . '</a></li>';
}
echo '</ul>';
}
echo $args['after_widget'];
}
/**
* Outputs the options form on admin
*
* @param array $instance The widget options
*/
public function form( $instance ) {
//outputs the options form on admin
$title = ( !empty( $instance['title'] ) ) ? $instance['title'] : '';
?>
<label for="<?php echo $this->get_field_name( 'title' ); ?>">Title: </label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
<?php
}
}//end class
add_action( 'widgets_init', function(){
register_widget( 'REST_API_Widget' );
});
โดยพื้นฐานแล้ว เราได้สร้างปลั๊กอินใหม่ ในปลั๊กอินนั้น เราได้สร้างวิดเจ็ตที่แสดงรายการโพสต์ที่กำหนดเองจากฐานความรู้ Heroic จากเว็บไซต์อื่น
สิ่งที่เราจะทำตอนนี้คือแก้ไขเพื่อสร้างคุณลักษณะการค้นหาด้วย
ขั้นตอนที่ 1: แก้ไขข้อความค้นหาพื้นฐานเพื่อให้ได้ผลลัพธ์ที่แตกต่างกัน
ในบทความที่แล้ว คุณจะจำได้ว่าเราได้พูดถึงวิธีรับรายการโพสต์และวิธีเปลี่ยนพารามิเตอร์เพื่อให้เราได้รับประเภทโพสต์ที่กำหนดเองของฐานข้อมูลความรู้แทน
การเรียนรู้อาจไม่น่าแปลกใจเท่าไร แต่นั่นไม่ใช่ทั้งหมดที่เราสามารถทำได้ด้วยวิธี GET ด้วยการใช้พารามิเตอร์การกรอง เราสามารถใช้อาร์กิวเมนต์ใดๆ ที่มีอยู่ได้เมื่อเรียก WP_Query ตัวอย่างเช่น หากเราต้องการเปลี่ยนจำนวนโพสต์ที่แสดง คุณสามารถเพิ่ม:
/posts?filter[posts_per_page]=5
การโทรทางไกลมีลักษณะดังนี้:
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[posts_per_page]=5' );
หรือถ้าเราต้องการแสดงโพสต์แบบสุ่มเพียงโพสต์เดียว เราสามารถเพิ่ม:
/posts?filter[orderby]=rand&amp;filter[posts_per_page]=1
และนี่ก็เหมือนกันสำหรับพารามิเตอร์การค้นหา ใน WP Query มาตรฐาน พารามิเตอร์จะมีลักษณะดังนี้:
's' => 'keyword'
ดังนั้น การโทรทางไกลของเราต้องมีลักษณะดังนี้:
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[s]=keyword');
มันค่อนข้างง่ายเมื่อคุณได้แปลงพารามิเตอร์จาก WP_Query เป็นสตริง URL ของ API
สำหรับรายละเอียดทั้งหมดเกี่ยวกับพารามิเตอร์ที่ใช้ได้ โปรดดูที่ WP_Query codex guide
เราไม่ได้ต้องการค้นหาโพสต์มาตรฐาน แต่เราต้องการค้นหาประเภทโพสต์ที่กำหนดเองของฐานข้อมูลความรู้ อย่างไรก็ตาม ตามที่เราเห็นในบทความก่อนหน้านี้ การทำเช่นนี้ทำได้ง่ายเพราะเราทำให้โพสต์ประเภทที่กำหนดเองของเราเป็นแบบสาธารณะได้โดยการเพิ่มตัวกรอง ดังนั้น สิ่งที่เราต้องทำที่นี่คือสอบถามประเภทโพสต์ที่กำหนดเองของฐานข้อมูลความรู้โดยสลับ /posts/ ด้วยชื่อของประเภทโพสต์ที่กำหนดเอง ในกรณีนี้ /ht_kb/ การโทรทางไกลจะมีลักษณะดังนี้:
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]=keyword' );
ขั้นตอนที่ 2: ช่องค้นหาและผลลัพธ์การปรับแต่ง
ตอนนี้ เราได้ดูการแก้ไขข้อความค้นหาเพื่อกรองตามข้อความค้นหาที่กำหนด ขั้นตอนต่อไปคือการสร้างวิธีเพื่อให้ได้ข้อความค้นหานั้น
ประการแรก เราต้องเพิ่มช่องค้นหาให้กับปลั๊กอิน เนื่องจากนี่เป็นเพียงแบบฟอร์มการค้นหาทั่วไป เราจึงสามารถใช้ฟังก์ชัน get_search_form() ที่ WordPress ตั้งค่าไว้แล้ว แทนที่จะสร้างแบบฟอร์มการค้นหาแยกต่างหาก
ในไฟล์ปลั๊กอิน ให้มองหาบรรทัดที่มีความคิดเห็น // เนื้อหาวิดเจ็ตหลักที่นี่ภายในฟังก์ชันวิดเจ็ตของคุณและเพิ่ม get_search_form(); และแก้ไขด้านล่างโดยตรงเพื่อให้มีลักษณะดังนี้:
// Main Widget Content Here
get_search_form();
if( !empty( $posts ) ) {
echo '<ul>';
foreach( $posts as $post ) {
echo '<li><a href="' . $post->link. '">' . $post->title->rendered . '</a></li>';
}
echo '</ul>';
}
ตอนนี้เมื่อเราดูวิดเจ็ตบนหน้า คุณจะเห็นแบบฟอร์มการค้นหามาตรฐานและรายการโพสต์จากฐานความรู้ด้านล่าง

เรารู้จากการใช้ get_search_form(); เมื่อเราค้นหาบางสิ่ง พารามิเตอร์การค้นหาจะปรากฏใน url ดังนี้:
/?s=test
' เป็นพารามิเตอร์ $_GET และ 'ทดสอบ' เป็นข้อความค้นหาของคุณ ดังนั้น เหลือเพียงหยิบคำค้นหาจาก URL และใช้ในการตอบกลับดังนี้:
if ( isset ( $_GET['s'] ) && !empty( $_GET['s'] ) ) {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]='.$_GET['s'] );
}
else {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb/' );
}
รหัสนี้ทำอะไรได้บ้าง ตรวจสอบว่า $_GET['s'] ถูกตั้งค่าและไม่ว่างเปล่าหรือไม่ หากมี/เป็น แสดงว่าคุณรวมไว้ในคำตอบของคุณ หากไม่ แสดงว่าไม่มีการค้นหาและคุณต้องการแสดงโพสต์ในฐานข้อมูลความรู้ทั้งหมดตามปกติ
รายละเอียดเพิ่มเติมเกี่ยวกับฟังก์ชัน get_search_form() สามารถพบได้ที่นี่
นี่คือจุดที่เราคาดหวังว่าบทความนี้จะจบลงใช่ไหม ท้ายที่สุด เราได้ตั้งค่าแบบฟอร์มการค้นหาที่ค้นหาโพสต์บนเว็บไซต์ภายนอกโดยใช้ WordPress REST API แล้วส่งคืนผลลัพธ์เหล่านั้นตามพารามิเตอร์การค้นหา อย่างไรก็ตาม…
ขั้นตอนที่ 3: การแก้ไขผลลัพธ์ที่แสดง
หากเราทดสอบวิดเจ็ตการค้นหาใหม่ เราจะเห็นว่าวิดเจ็ตทำงานตามที่คาดไว้ อย่างไรก็ตาม วิดเจ็ตจะแสดงผลลัพธ์จากเว็บไซต์ปัจจุบันในเนื้อหาของหน้าหลักด้วย

นี่เป็นเพราะระบบเทมเพลตของ WordPress WordPress ใช้สตริงการสืบค้นเพื่อกำหนดเทมเพลตหรือชุดเทมเพลตที่จะใช้ เนื่องจากเมื่อส่งแบบฟอร์มการค้นหาจะเพิ่มพารามิเตอร์ 's' ลงใน URL เป็นการบอกให้ WordPress ทำการค้นหาและเปลี่ยนเส้นทางไปยังหน้าผลการค้นหา ซึ่งในธีม TwentySixteen คือ search.php

สำหรับข้อมูลเพิ่มเติม โปรดดูเอกสารลำดับชั้นเทมเพลต
เป็นสิ่งที่ดีถ้าเราต้องการค้นหาบนเว็บไซต์ท้องถิ่นและเว็บไซต์ภายนอกโดยใช้ API ในเวลาเดียวกันเพราะผลลัพธ์ของทั้งสองจะแสดงขึ้น อย่างไรก็ตาม ในกรณีนี้ เราไม่ต้องการทำเช่นนั้น เราต้องการให้ผลลัพธ์ส่งคืนโดยใช้ API เพื่อแสดงในวิดเจ็ตเท่านั้น หน้าหลักไม่ควรได้รับผลกระทบ
มีหลายวิธีในการทำเช่นนี้ สำหรับตัวอย่างนี้ เราจะมาดูวิธีการแก้ไข get_search_form(); ฟังก์ชั่นที่จะไม่ใช้ 's' เป็นพารามิเตอร์การค้นหาอีกต่อไป แต่จะเปลี่ยนเป็น 'a' เพื่อข้ามปัญหา
ขั้นตอนแรกคือการปรับเปลี่ยนแบบฟอร์มโดยการสร้างฟังก์ชันใหม่
function api_search_form( $form ) {
$form = '<form role="search" method="get" class="search-form" action="' . home_url( '/' ) . '">
<label>
<span class="screen-reader-text">' . _x( 'Search for:', 'label' ) . '</span>
<input type="search" class="search-field" placeholder="' . esc_attr_x( 'Search …', 'placeholder' ) .'" value="' . get_search_query() . '" name="a" title="' . esc_attr_x( 'Search for:', 'label' ) .'" />
</label>
<button type="submit" class="search-submit"><span class="screen-reader-text">Search</span></button>
</form>';
return $form;
}
add_filter( 'get_search_form', 'api_search_form', 100 );
ฟังก์ชันนี้ค่อนข้างเรียบง่าย โดยพื้นฐานแล้วจะเป็นรูปแบบใหม่ที่จะใช้แทนรูปแบบเริ่มต้น หากเราดูที่ชุดรูปแบบอ้างอิง TwentySixteen และตรวจสอบแบบฟอร์มการค้นหาที่มีอยู่ เราทราบว่าความแตกต่างเพียงอย่างเดียวในรหัสคือชื่อของอินพุตการค้นหา เดิมทีมันคือ 'name=s' และตอนนี้คือ 'name=a' การดำเนินการนี้จะลบพารามิเตอร์ 's' ออกจาก URL
หมายเหตุ: ด้วยวิธีนี้ เราแก้ไขแบบฟอร์มการค้นหาหลักเพื่อค้นหาโดยใช้ API แทนการค้นหาเว็บไซต์โฮสต์ ดังนั้น จึงเป็นสิ่งสำคัญที่จะต้องพิจารณาว่า หากเราใช้แบบฟอร์มการค้นหาหลักที่อื่นบนเว็บไซต์ จะไม่เปลี่ยนเส้นทางไปยังผลการค้นหาจากเว็บไซต์ของโฮสต์เว็บไซต์อีกต่อไป เพื่อให้มีการค้นหาที่แตกต่างกันสองครั้ง วิธีแก้ปัญหาที่ง่ายที่สุดคือการเพิ่มโค้ดสำหรับแบบฟอร์มใหม่นี้โดยตรงในวิดเจ็ต แทนที่จะแก้ไข get_search_form();
ขั้นตอนสุดท้ายคือการเพิ่มตัวกรอง สิ่งนี้บอกให้ WordPress แทนที่แบบฟอร์มที่มีอยู่ด้วยแบบฟอร์มนี้แทน เราสามารถวางบล็อคโค้ดทั้งหมดลงในไฟล์ปลั๊กอินหลังคลาสวิดเจ็ต ซึ่งอาจรวม functions.php ของธีมแทน แต่การรวมไว้ในปลั๊กอิน หมายความว่าการเปลี่ยนแปลงในแบบฟอร์มจะเกิดขึ้นต่อเมื่อเปิดใช้งานปลั๊กอินเท่านั้น
ตอนนี้เราได้เปลี่ยนชื่ออินพุตเป็น 'a' แล้ว เราต้องเปลี่ยนพารามิเตอร์การค้นหาที่แท้จริงด้วย พารามิเตอร์จะปรากฏใน URL เป็น: /?a=test แทนที่จะเป็น /?s=test ดังนั้นจึงลบส่วนของสตริงข้อความค้นหาที่บอก WordPress ว่าควรเปลี่ยนเส้นทางไปยังเทมเพลตผลการค้นหา
เพื่อให้คุณสามารถค้นหาโดยใช้พารามิเตอร์ใหม่ อัปเดตโค้ดที่เขียนไว้ก่อนหน้านี้สำหรับการโทรระยะไกลเพื่อใช้พารามิเตอร์ 'a' แทน 's'
ตอนนี้ควรมีลักษณะดังนี้:
if ( isset ( $_GET['a'] ) && !empty( $_GET['a'] ) ) {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]='.$_GET['a'] );
} else {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb/' );
}
ขอให้สังเกตว่าแม้ว่าพารามิเตอร์การค้นหาใน $_GET จะเปลี่ยนไป แต่สิ่งนี้จะไม่เปลี่ยนตัวกรองในการสืบค้นจริง เนื่องจาก WP Query มาตรฐานสำหรับการค้นหายังคงเป็น 's'
เมื่อเราทดสอบวิดเจ็ต เราควรจะสามารถค้นหาบทความฐานข้อมูลองค์ความรู้บนเว็บไซต์ภายนอกของคุณ และส่งคืนผลลัพธ์โดยไม่ถูกเปลี่ยนเส้นทางไปยังหน้าผลการค้นหา

รหัสเต็มสำหรับวิดเจ็ตมีลักษณะดังนี้:
/**
* Plugin Name: KB - REST API Widget
* Author: Kirsty Burgoine
*/
class REST_API_Widget extends WP_Widget {
/**
* Sets up the widgets name etc
*/
public function __construct() {
$widget_ops = array(
'classname' => 'rest-api-widget',
'description' => 'A REST API widget that pulls posts from a different website');
parent::__construct( 'rest_api_widget', 'REST API Widget', $widget_ops );
}
/**
* Outputs the content of the widget
*
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
// outputs the content of the widget
if ( isset ( $_GET['a'] ) && !empty( $_GET['a'] ) ) {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]='.$_GET['a'] );
} else {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb/' );
}
if( is_wp_error( $response ) ) {
return;
}
$posts = json_decode( wp_remote_retrieve_body( $response ) );
if( empty( $posts ) ) {
return;
}
echo $args['before_widget'];
if( !empty( $instance['title'] ) ) {
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $args['after_title'];
}
// Main Widget Content Here
get_search_form();
if( !empty( $posts ) ) {
echo '<ul>';
foreach( $posts as $post ) {
echo '<li><a href="' . $post->link. '">' . $post->title->rendered . '</a></li>';
}
echo '</ul>';
}
echo $args['after_widget'];
}
/**
* Outputs the options form on admin
*
* @param array $instance The widget options
*/
public function form( $instance ) {
// outputs the options form on admin
$title = ( !empty( $instance['title'] ) ) ? $instance['title'] : '';
?>
<label for="<?php echo $this->get_field_name( 'title' ); ?>">Title: </label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>"
name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
<?php
}
}
function api_search_form( $form ) {
$form = '<form role="search" method="get" class="search-form" action="' . home_url( '/' ) . '">
<label>
<span class="screen-reader-text">' . _x( 'Search for:', 'label' ) . '</span>
<input type="search" class="search-field" placeholder="' . esc_attr_x( 'Search …', 'placeholder' ) .'" value="' . get_search_query() . '" name="a" title="' . esc_attr_x( 'Search for:', 'label' ) .'" />
</label>
<button type="submit" class="search-submit"><span class="screen-reader-text">Search</span></button>
</form>';
return $form;
}
add_filter( 'get_search_form', 'api_search_form', 100 );
add_action( 'widgets_init', function(){
register_widget( 'REST_API_Widget' );
});
นี่เป็นการใช้งานวิดเจ็ตการค้นหาแบบกำหนดเองที่ง่ายมากโดยใช้ REST API ดังที่แสดงไว้ก่อนหน้านี้ เราสามารถเพิ่มตัวกรองเพิ่มเติมในการค้นหาเพื่อจำกัดจำนวนผลการค้นหาหรือลำดับที่จะแสดง คุณสามารถเลือกที่จะแสดงข้อมูลเพิ่มเติมในวิดเจ็ต เช่น ข้อความค้นหาและจำนวนผลลัพธ์ หรือ หากคุณรู้จัก jQuery / Javascript คุณสามารถใช้สิ่งนี้เพิ่มเติมและเพิ่มเอฟเฟกต์ AJAX ที่ดี เพื่อให้ผลลัพธ์ถูกส่งกลับโดยไม่จำเป็นต้องรีเฟรชหน้า
อ่านเพิ่มเติม:
- วิดเจ็ต API (WordPress Codex)
- ข้อมูลเบื้องต้นเกี่ยวกับการสร้างวิดเจ็ต WordPress ตัวแรกของคุณ (Tutsplus)
- วิธีสร้างวิดเจ็ต WordPress แบบกำหนดเอง (WP Beginner)
- วิธีสร้างปลั๊กอินวิดเจ็ตสำหรับ WordPress (WP Explorer)
