Tạo một tiện ích thanh bên đơn giản

Tạo một tiện ích thanh bên đơn giản cho trang web WordPress của bạn. Tìm hiểu cách hiển thị danh sách các bài đăng trong hướng dẫn này cho những người không phải là lập trình viên. Chúng tôi sẽ giữ tất cả mã trong một tệp PHP để bạn có thể sử dụng nó trong một chủ đề con tùy chỉnh hoặc trong một plugin tùy chỉnh . Tiện ích sẽ hiển thị danh sách các bài đăng gần đây và chúng tôi sẽ có thể…

  • Chọn một loại bài đăng. Vì vậy, bạn có thể hiển thị các bài đăng, trang, sản phẩm hoặc một loại bài đăng tùy chỉnh.
  • Tùy chọn lọc các bài đăng theo phân loại / thuật ngữ.
Trong WordPress, chúng tôi tương tác với các widget trong 2 lĩnh vực. Chúng tôi đặt thuộc tính của chúng trong khu vực quản trị và hiển thị chúng trong giao diện người dùng. Bởi vì chúng tôi cần có thể thiết lập một số tùy chọn tiện ích trước khi chúng tôi có thể hiển thị nó, chúng tôi sẽ thực hiện các bit quản trị cuối trước.

Chúng ta sẽ thực hiện một số lập trình hướng đối tượng để tạo định nghĩa lớp PHP. Định nghĩa sẽ mở rộng lớp WP_Widget. Khi chúng tôi đã xác định lớp của mình, chúng tôi sẽ nói với WordPress về nó để chúng tôi có thể tạo các phiên bản widget trong trang web của mình.

thông tin Nếu bạn chỉ muốn mã cho tiện ích, hãy cuộn đến cuối - tất cả đều ở đó và bạn có thể sao chép / dán nó vào dự án của mình.

Hãy viết một số mã tiện ích

Trong thư mục chủ đề con tùy chỉnh của bạn, hãy tạo một thư mục con có tên “widget” (nếu bạn chưa có), sau đó tạo một tệp có tên custom-post-list-widget.php trong thư mục con widget mới. Tệp này sẽ chứa tất cả mã cho tiện ích con tùy chỉnh của chúng tôi. Hãy bắt đầu bằng cách thiết lập các chức năng chính, như thế này…
// Block direct access.
if (!defined('WPINC')) {
   exit('Do NOT access this file directly.');
}
/**
 * A widget to show a list of posts.
 */
class Custom_Post_List_Widget extends WP_Widget {
   private $widget_args = null;
   private $widget_instance = null;
   private $this_id = '';
   function __construct() {
      parent::__construct(
         'Custom_Post_List_Widget',
         __('Custom Post List', 'headwall'),
         array('description' => __('Shows a customisable list of posts.', 'headwall'))
      );
   }
   /**
    * Display the widget form options in the back-end.
    */
   public function form($instance) {
      $this->init_widget_instance(null, $instance);
   }
   /**
    * Process our widget's options.
    */
   private function init_widget_instance($args, $instance) {
      $this->widget_args = $args;
      $this->widget_instance = $instance;
      if (is_array($args)) {
         $this->this_id = $args['widget_id'];
      }
   }
   /**
    * Render the widget in the front-end.
    */
   public function widget($args, $instance) {
      $this->init_widget_instance($args, $instance);
      echo '

Widget goes here...

'; } } register_widget('Custom_Post_List_Widget');
… Sau đó thêm một cái gì đó như thế này vào tệp functions.php của chủ đề con tùy chỉnh của bạn để đưa mã mới vào màn hình đầu tiên.
// Load our custom post list widget.
require_once 'widgets/custom-post-list-widget.php';
Đây là phần cơ bản của bất kỳ tiện ích nào và vừa đủ để WordPress chú ý đến nó. Lưu tệp, chuyển đến khu vực Quản trị của trang web của bạn, sau đó đi tới Giao diện> Tiện ích. Bạn sẽ thấy Widget mới của mình trong danh sách các widget mà bạn có thể thêm vào trang web của mình.

Thêm tiện ích vào thanh bên của bạn và sau đó chuyển đến một trang trên trang web của bạn có hiển thị thanh bên. Nếu mọi thứ hoạt động bình thường, bạn sẽ thấy “Tiện ích con chạy ở đây…” hoạt động như một loại trình giữ chỗ.

Chúng tôi đang tiến bộ.

Hãy quay lại mã và điền vào một số chỗ trống để chúng ta có thể đặt một số thuộc tính cho tiện ích của mình. Đây là phiên bản mới của custom-post-list-widget.php

/**
 * A widget to show a list of posts.
 */
// Block direct access.
if (!defined('WPINC')) {
   exit('Do NOT access this file directly.');
}
/**
 * A widget to show a list of posts.
 */
class Custom_Post_List_Widget extends WP_Widget {
   private $widget_args = null;
   private $widget_instance = null;
   private $this_id = '';
   private $title = null;
   private $is_title_visible = true;
   private $post_type = null;
   private $taxonomy = null;
   private $term = null;
   private $number_of_posts = -1;
   function __construct() {
      parent::__construct(
         'Custom_Post_List_Widget',
         __('Custom Post List', 'headwall'),
         array('description' => __('Shows a customisable list of posts.', 'headwall'))
      );
   }
   /**
    * Display the widget form options in the back-end.
    */
   public function form($instance) {
      $this->init_widget_instance(null, $instance);
      // The title for our widget (text/string).
      echo '

'; printf('%s', $this->get_field_id('title'), __('Title:') ); printf('', $this->get_field_id('title'), $this->get_field_name('title'), esc_attr($this->title) ); echo '

'; // Hide/show the title (boolean/checkbox). echo '

'; printf('', $this->get_field_id('is_title_visible'), $this->get_field_name('is_title_visible'), $this->is_title_visible ? 'checked' : '' ); printf('%s', $this->get_field_id('is_title_visible'), __('Show the Widget Title?', 'headwall') ); echo '

'; // The post type we want to query (drop-down list). echo '

'; printf('%s', $this->get_field_id('post_type'), __('Post Type:') ); printf('', $this->get_field_id('post_type'), $this->get_field_name('post_type') ); if (is_array($post_types = get_post_types(null, 'objects'))) { foreach ($post_types as $post_type) { if ($post_type->public) { $props = ''; if ($post_type->name == $this->post_type) { $props .= 'selected'; } printf('%s', esc_attr($post_type->name), $props, esc_html($post_type->label) ); } } } echo ''; echo '

'; // The taxonomy we want to query (drop-down list). echo '

'; printf('%s', $this->get_field_id('taxonomy'), __('Taxonomy (Optional):') ); printf('', $this->get_field_id('taxonomy'), $this->get_field_name('taxonomy') ); if (is_array($taxonomies = get_taxonomies(null, 'objects'))) { printf('<%s>', empty($this->taxonomy) ? 'selected' : '', esc_html__('None') ); foreach ($taxonomies as $taxonomy) { if ($taxonomy->public) { $props = ''; if ($taxonomy->name == $this->taxonomy) { $props .= 'selected'; } printf('%s (%s)', esc_attr($taxonomy->name), $props, esc_html($taxonomy->label), esc_html($taxonomy->name) ); } } } echo ''; echo '

'; // The taxonomy term we want to filter against. echo '

'; printf('%s', $this->get_field_id('term'), __('Term (slug):') ); printf('', $this->get_field_id('term'), $this->get_field_name('term'), esc_attr($this->term) ); echo '

'; // Number of posts to show. echo '

'; printf('%s', $this->get_field_id('number_of_posts'), __('Number of posts:') ); printf('', $this->get_field_id('number_of_posts'), $this->get_field_name('number_of_posts'), $this->number_of_posts ); echo '

'; } /** * Process our widget's options. */ private function init_widget_instance($args, $instance) { $this->widget_args = $args; $this->widget_instance = $instance; if (is_array($args)) { $this->this_id = $args['widget_id']; } // Widget title text. if (!isset($this->widget_instance['title'])) { $this->title = __('Custom Post List', 'headwall'); } else { $this->title = $this->widget_instance['title']; } // Is the widget title visible? $this->is_title_visible = true; if (isset($this->widget_instance['is_title_visible'])) { $this->is_title_visible = boolval($this->widget_instance['is_title_visible']); } // The post type we want to query. $this->post_type = 'post'; if (isset($this->widget_instance['post_type'])) { $this->post_type = $this->widget_instance['post_type']; } // The taxonomy we want. Optional. $this->taxonomy = ''; if (isset($this->widget_instance['taxonomy'])) { $this->taxonomy = $this->widget_instance['taxonomy']; } // The taxonomy we want. Optional. $this->term = ''; if (isset($this->widget_instance['term'])) { $this->term = $this->widget_instance['term']; } // The number of posts to show. $this->number_of_posts = 5; if (isset($this->widget_instance['number_of_posts'])) { $this->number_of_posts = intval($this->widget_instance['number_of_posts']); } } /** * Render the widget in the front-end. */ public function widget($args, $instance) { $this->init_widget_instance($args, $instance); echo '

Widget goes here...

'; } } register_widget('Custom_Post_List_Widget');

Chỉ có một vài đoạn mã thú vị ở đây. Chúng ta có một hàm gọi là form () và một hàm gọi là init_widget_instance (). WordPress hy vọng chúng ta triển khai hàm form () để bố trí các tùy chọn trong Appearance> Widgets. Đoạn mã trong đó hiển thị cách bố trí hộp văn bản, hộp kiểm, danh sách thả xuống và trường số. HTML ở đây cần phải đơn giản vì không có nhiều không gian trên màn hình để làm việc. Chỉ cần đảm bảo rằng bạn cung cấp cho biểu mẫu HTML điều khiển các tên và ID chính xác bằng cách sử dụng các hàm get_field_id () và get_field_name ().

Hàm khác mà chúng tôi đã tạo là init_widget_instance (). Về mặt kỹ thuật, chúng ta không cần hàm này - chúng ta có thể chỉ đặt tất cả mã đó ở đầu hàm form (), nhưng… việc đặt mã trong một hàm nhỏ riêng biệt làm cho hàm form () thực sự dễ đọc, và… chúng ta sẽ gọi lại init_widget_instance () khi chúng ta viết mã giao diện người dùng.

Kiểm tra nó ra!

Kiểm tra xem bạn có thể lưu từng tùy chọn đúng cách hay không. Nếu bạn cố gắng lưu một tùy chọn nhưng nó không thực sự lưu, hãy kiểm tra xem các điều khiển biểu mẫu đã có tên / ID chính xác chưa và mọi điều khiển bạn đang vẽ trong hàm form () đều có một đoạn mã tương đương trong init_widget_instance () để trích xuất các giá trị từ $ instance.

Hiển thị tiện ích thanh bên mới của chúng tôi

Bây giờ chúng ta hãy làm một chút thú vị - thực sự hiển thị một số bài đăng trong thanh bên. Để làm điều này, chúng ta chỉ cần thêm một chức năng mới được gọi là widget (). Đây là phiên bản cập nhật của custom-post-list-widget.php , hoàn chỉnh với hàm widget () mới để hiển thị giao diện người dùng.
/**
 * A widget to show a list of posts.
 *
 * Include this file from your child theme' functions.php file:
 *
 * require_once 'widgets/custom-post-list-widget.php';
 */
// Block direct access.
if (!defined('WPINC')) {
   exit('Do NOT access this file directly.');
}
/**
 * A widget to show a list of posts.
 */
class Custom_Post_List_Widget extends WP_Widget {
   private $widget_args = null;
   private $widget_instance = null;
   private $this_id = '';
   private $title = null;
   private $is_title_visible = true;
   private $post_type = null;
   private $taxonomy = null;
   private $term = null;
   private $number_of_posts = -1;
   function __construct() {
      parent::__construct(
         'Custom_Post_List_Widget',
         __('Custom Post List', 'headwall'),
         array('description' => __('Shows a customisable list of posts.', 'headwall'))
      );
   }
   /**
    * Display the widget form options in the back-end.
    */
   public function form($instance) {
      $this->init_widget_instance(null, $instance);
      // The title for our widget (text/string).
      echo '

'; printf('%s', $this->get_field_id('title'), __('Title:') ); printf('', $this->get_field_id('title'), $this->get_field_name('title'), esc_attr($this->title) ); echo '

'; // Hide/show the title (boolean/checkbox). echo '

'; printf('', $this->get_field_id('is_title_visible'), $this->get_field_name('is_title_visible'), $this->is_title_visible ? 'checked' : '' ); printf('%s', $this->get_field_id('is_title_visible'), __('Show the Widget Title?', 'headwall') ); echo '

'; // The post type we want to query (drop-down list). echo '

'; printf('%s', $this->get_field_id('post_type'), __('Post Type:') ); printf('', $this->get_field_id('post_type'), $this->get_field_name('post_type') ); if (is_array($post_types = get_post_types(null, 'objects'))) { foreach ($post_types as $post_type) { if ($post_type->public) { $props = ''; if ($post_type->name == $this->post_type) { $props .= 'selected'; } printf('%s', esc_attr($post_type->name), $props, esc_html($post_type->label) ); } } } echo ''; echo '

'; // The taxonomy we want to query (drop-down list). echo '

'; printf('%s', $this->get_field_id('taxonomy'), __('Taxonomy (Optional):') ); printf('', $this->get_field_id('taxonomy'), $this->get_field_name('taxonomy') ); if (is_array($taxonomies = get_taxonomies(null, 'objects'))) { printf('<%s>', empty($this->taxonomy) ? 'selected' : '', esc_html__('None') ); foreach ($taxonomies as $taxonomy) { if ($taxonomy->public) { $props = ''; if ($taxonomy->name == $this->taxonomy) { $props .= 'selected'; } printf('%s (%s)', esc_attr($taxonomy->name), $props, esc_html($taxonomy->label), esc_html($taxonomy->name) ); } } } echo ''; echo '

'; // The taxonomy term we want to filter against. echo '

'; printf('%s', $this->get_field_id('term'), __('Term (slug):') ); printf('', $this->get_field_id('term'), $this->get_field_name('term'), esc_attr($this->term) ); echo '

'; // Number of posts to show. echo '

'; printf('%s', $this->get_field_id('number_of_posts'), __('Number of posts:') ); printf('', $this->get_field_id('number_of_posts'), $this->get_field_name('number_of_posts'), $this->number_of_posts ); echo '

'; } /** * Process our widget's options. */ private function init_widget_instance($args, $instance) { $this->widget_args = $args; $this->widget_instance = $instance; if (is_array($args)) { $this->this_id = $args['widget_id']; } // Widget title text. if (!isset($this->widget_instance['title'])) { $this->title = __('Custom Post List', 'headwall'); } else { $this->title = $this->widget_instance['title']; } // Is the widget title visible? $this->is_title_visible = true; if (isset($this->widget_instance['is_title_visible'])) { $this->is_title_visible = boolval($this->widget_instance['is_title_visible']); } // The post type we want to query. $this->post_type = 'post'; if (isset($this->widget_instance['post_type'])) { $this->post_type = $this->widget_instance['post_type']; } // The taxonomy we want. Optional. $this->taxonomy = ''; if (isset($this->widget_instance['taxonomy'])) { $this->taxonomy = $this->widget_instance['taxonomy']; } // The taxonomy we want. Optional. $this->term = ''; if (isset($this->widget_instance['term'])) { $this->term = $this->widget_instance['term']; } // The number of posts to show. $this->number_of_posts = 5; if (isset($this->widget_instance['number_of_posts'])) { $this->number_of_posts = intval($this->widget_instance['number_of_posts']); } } /** * Render the widget in the front-end. */ public function widget($args, $instance) { $this->init_widget_instance($args, $instance); // Open the HTML for our widget. echo $this->widget_args['before_widget']; if ($this->is_title_visible && !empty($this->title)) { echo $args['before_title']; esc_html_e($this->title); echo $args['after_title']; } if (($this->number_of_posts) > 0) { $query_args = array( 'posts_per_page' => $this->number_of_posts, 'post_type' => $this->post_type, 'page' => 1, 'orderby' => 'date', 'order' => 'DESC', ); // If we have a taxonomy and a term, we can filter for // these with a tax_query. if (!empty($this->taxonomy) && !empty($this->term)) { $query_args['tax_query'] = array( array( 'taxonomy' => $this->taxonomy, 'field' => 'slug', 'terms' => $this->term, ), ); } $query = new WP_Query($query_args); if ($query->have_posts()) { echo '
    '; while ($query->have_posts()) { $query->the_post(); echo '
  • '; echo '
    '; printf('%s', esc_url(get_the_permalink()), esc_html(get_the_title()) ); echo '
    '; echo '
  • '; } echo '
'; wp_reset_postdata(); } } // Close the HTML for our widget. echo $this->widget_args['after_widget']; } } register_widget('Custom_Post_List_Widget'); Đây là toàn bộ tệp PHP của widget, với ba chức năng chính:
  • init_widget_instance ()
    • Xử lý các thông số của widget của chúng tôi.
  • mẫu đơn()
    • Hiển thị biểu mẫu HTML trong back-end để chúng tôi có thể định cấu hình từng phiên bản widget của mình.
  • widget ()
    • Hiển thị HTML giao diện người dùng của tiện ích con của chúng tôi.
Logic trong widget () khá đơn giản và xoay quanh WP_Query và một vòng lặp WordPress. Chúng tôi sẽ trình bày những điều này trong một hướng dẫn khác, nhưng tất cả những gì chúng tôi làm ở đây là xuất mỗi bài đăng dưới dạng một mục danh sách trong một danh sách không có thứ tự. Bạn có thể dễ dàng mở rộng phần này của vòng lặp để hiển thị tóm tắt bài đăng của mình theo bất kỳ cách nào bạn muốn.

Tiện ích này hiện có thể được sử dụng nguyên trạng hoặc bạn có thể sử dụng nó làm cơ sở cho một thứ gì đó phức tạp hơn. Hack nó về - có đủ trong đó để giúp bạn bắt đầu. Chúc vui vẻ!