Home Ghiền Trick Hướng Dẫn Chi Tiết A-Z: Tự Tay Tạo Plugin WordPress

Hướng Dẫn Chi Tiết A-Z: Tự Tay Tạo Plugin WordPress

Dai Hoang
0 comment 134 views

Trong bài viết cung cấp hướng dẫn chi tiết về cách tạo plugin WordPress, từ chuẩn bị kiến thức, công cụ đến các bước thực hiện và phương pháp hay nhất để đảm bảo plugin hoạt động hiệu quả, an toàn và dễ bảo trì.

1. Plugin WordPress là gì và tại sao nên tạo?

Hướng Dẫn Chi Tiết A-Z: Tự Tay Tạo Plugin WordPress

Plugin WordPress là tập hợp các đoạn mã (chủ yếu bằng PHP) bổ sung, sửa đổi hoặc mở rộng chức năng của website mà không cần chạm vào mã nguồn chính của WordPress.

Lợi ích của việc tự tạo plugin:

  • Tùy biến không giới hạn: Thêm bất kỳ tính năng nào theo ý muốn.
  • Dễ dàng cập nhật: Các tùy chỉnh không bị mất khi cập nhật WordPress hoặc theme.
  • Kiểm soát hoàn toàn: Toàn quyền kiểm soát mã nguồn, hiệu suất và bảo mật.
  • Tính linh hoạt và tái sử dụng: Có thể kích hoạt/vô hiệu hóa và sử dụng trên nhiều website.
  • Giải quyết vấn đề riêng biệt: Đáp ứng nhu cầu đặc thù không có sẵn trên thị trường.

2. Chuẩn bị trước khi bắt đầu phát triển Plugin

Hướng Dẫn Chi Tiết A-Z: Tự Tay Tạo Plugin WordPress

Kiến thức cơ bản về lập trình:

  • PHP: Ngôn ngữ lập trình chính của WordPress.
  • HTML và CSS: Hữu ích cho giao diện người dùng.
  • Action Hooks và Filter Hooks: Cơ chế cốt lõi để tương tác với WordPress.
  • JavaScript và MySQL: Cần thiết cho các plugin phức tạp hơn.

Môi trường phát triển cục bộ (Local Development Environment):

  • Cài đặt WordPress trên máy tính để thử nghiệm và sửa lỗi an toàn.
  • Công cụ phổ biến: XAMPP, WAMP, MAMP, Local by Flywheel.

Trình soạn thảo mã (Code Editor):

  • Giúp viết code dễ dàng và hiệu quả.
  • Lựa chọn phổ biến: VS Code, Sublime Text, Atom, PhpStorm.

3. Hướng dẫn chi tiết các bước tạo Plugin WordPress đầu tiên

Step 1: Cấu Trúc Thư Mục Plugin Chuẩn (Standard Plugin Directory Structure)

Mỗi plugin cần một thư mục riêng biệt trong `wp-content/plugins`. Một cấu trúc rõ ràng sẽ giúp quản lý dễ dàng hơn.

Example Structure:

wp-content/
└── plugins/
    └── ten-plugin-cua-ban/
        ├── ten-plugin-cua-ban.php (Main plugin file)
        ├── includes/
        │   └── custom-post-type.php
        │   └── shortcodes.php
        ├── assets/
        │   ├── css/
        │   │   └── style.css
        │   ├── js/
        │   │   └── script.js
        │   └── images/
        │       └── default-image.png  <-- Static plugin images
        └── readme.txt (For WordPress.org)
  • `assets/images/`: Nơi lý tưởng để lưu trữ các hình ảnh tĩnh của plugin như biểu tượng hoặc hình ảnh mặc định cho shortcodes.

Step 2: Tạo Tệp Plugin Chính và Tiêu Đề Plugin (Create Main Plugin File and Header)

Tệp PHP chính là trái tim của plugin, được WordPress nhận diện thông qua một tiêu đề chuẩn.

`ten-plugin-cua-ban.php` Content Example:

<?php
/**
 * Plugin Name: Tên Plugin Của Bạn
 * Plugin URI:  https://example.com/
 * Description: A sample plugin for demonstrating CPT and Shortcode creation.
 * Version:     1.0.0
 * Author:      Tên Tác Giả Của Bạn
 * Author URI:  https://example.com/tac-gia
 * License:     GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain: ten-plugin-cua-ban
 * Domain Path: /languages
 */

// Prevent direct access for security
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// Define plugin base path for easier use
define( 'TEN_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );

// Include separate function files for code organization
require_once TEN_PLUGIN_DIR . 'includes/custom-post-type.php';
require_once TEN_PLUGIN_DIR . 'includes/shortcodes.php';
// require_once TEN_PLUGIN_DIR . 'includes/widgets.php'; // If you have widgets
?>
  • Activation: Sau khi lưu, kích hoạt plugin từ trang “Plugins” -> “Installed Plugins” trong admin WordPress.

Step 3: Tương Tác Với WordPress: Hooks (Actions & Filters)

Hooks cho phép các plugin tương tác với WordPress mà không cần chỉnh sửa các tệp lõi.

  • Actions: Thực thi các tác vụ tại các điểm cụ thể (ví dụ: `save_post`, `admin_init`, `init`). Các hàm callback không cần trả về giá trị.
  • Filters: Thay đổi dữ liệu trước khi nó được hiển thị hoặc lưu (ví dụ: `the_content`, `document_title_parts`). Các hàm callback phải trả về giá trị đã sửa đổi.
  • Usage: Sử dụng `add_action()` và `add_filter()` để móc các hàm tùy chỉnh của bạn.
<?php
// Example Action
function my_custom_init_action() { error_log('My plugin initialized!'); }
add_action( 'init', 'my_custom_init_action' );

// Example Filter
function my_custom_title_filter( $title ) { return 'Awesome: ' . $title; }
add_filter( 'wp_title', 'my_custom_title_filter' ); // Note: 'wp_title' is legacy. Use 'document_title_parts' for modern themes.
?>

Step 4: Tạo Custom Post Type (CPT)

CPT cho phép tạo các loại nội dung mới ngoài “Bài viết” và “Trang” mặc định.

  • File: `includes/custom-post-type.php`
  • Content Example: Định nghĩa một CPT “Dự án” (Project) với các nhãn, hỗ trợ (tiêu đề, trình soạn thảo, hình ảnh đại diện, tóm tắt, bình luận), phân loại và khả năng hiển thị công khai.
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }

function create_my_custom_post_type() {
    $labels = array( /* ... labels for 'Dự án' ... */ );
    $args = array(
        'label'                 => __( 'Dự án', 'ten-plugin-cua-ban' ),
        'description'           => __( 'Các dự án của tôi', 'ten-plugin-cua-ban' ),
        'labels'                => $labels,
        'supports'              => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments' ),
        'taxonomies'            => array( 'category', 'post_tag' ),
        'hierarchical'          => false,
        'public'                => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'menu_position'         => 5,
        'menu_icon'             => 'dashicons-portfolio',
        'show_in_admin_bar'     => true,
        'show_in_nav_menus'     => true,
        'can_export'            => true,
        'has_archive'           => true,
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'capability_type'       => 'post',
        'show_in_rest'          => true, // For Gutenberg/REST API support
    );
    register_post_type( 'du_an_cua_toi', $args );
}
add_action( 'init', 'create_my_custom_post_type' );
?>
  • Result: Một mục menu “Dự án” mới sẽ xuất hiện trong thanh bên quản trị WordPress.

Step 5: Tạo Shortcode

Shortcodes cho phép người dùng chèn nội dung động hoặc chức năng phức tạp vào bài đăng, trang hoặc widget bằng các thẻ ngắn gọn.

  • File: `includes/shortcodes.php`
  • Content Example: Định nghĩa các shortcode `[my_info]` và `[my_content]`.
    • `my_custom_shortcode` (`[my_info]`): Chấp nhận các thuộc tính `title`, `image`, và `content`. Sử dụng `shortcode_atts()` cho giá trị mặc định và `plugins_url()` để tham chiếu `assets/images/default-image.png`.
    • `my_content_shortcode` (`[my_content]`): Một shortcode bao bọc nội dung, cho phép các shortcode lồng nhau thông qua `do_shortcode()`.
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }

// Simple shortcode with attributes
function my_custom_shortcode( $atts ) {
    $atts = shortcode_atts(
        array(
            'title' => 'Default Title',
            'image' => TEN_PLUGIN_DIR . 'assets/images/default-image.png',
            'content' => 'Default content.',
        ),
        $atts,
        'my_info'
    );

    $output = '<div class="my-info-box">';
    $output .= '<h2>' . esc_html( $atts['title'] ) . '</h2>';
    $output .= '<img src="' . esc_url( plugins_url( 'assets/images/default-image.png', dirname(__FILE__, 2) ) ) . '" alt="' . esc_attr( $atts['title'] ) . '">';
    $output .= '<p>' . esc_html( $atts['content'] ) . '</p>';
    $output .= '</div>';
    return $output;
}
add_shortcode( 'my_info', 'my_custom_shortcode' );

// Enclosing shortcode
function my_content_shortcode( $atts, $content = null ) {
    $atts = shortcode_atts( array( 'class' => 'highlight-box' ), $atts, 'my_content' );
    return '<div class="' . esc_attr( $atts['class'] ) . '">' . do_shortcode( $content ) . '</div>';
}
add_shortcode( 'my_content', 'my_content_shortcode' );
?>

Usage:

  • `[my_info title=”My Awesome Project” content=”A brief and engaging description…”]`
  • `[my_content class=”green-box”]This content is highlighted inside a special box.[/my_content]`

Step 6: Tạo Widget Tùy Chỉnh (Create Custom Widget)

Widgets là các khối nội dung mà người dùng có thể kéo và thả vào các khu vực widget được định nghĩa bởi theme (thanh bên, chân trang).

  • Implementation: Tạo một lớp PHP mở rộng `WP_Widget` và triển khai các phương thức: `__construct`, `widget` (hiển thị giao diện người dùng), `form` (biểu mẫu cài đặt quản trị), và `update` (lưu cài đặt).
  • File: Có thể thêm vào `ten-plugin-cua-ban.php` hoặc một tệp riêng biệt như `includes/widgets.php`.
  • Example Widget Structure: `My_Custom_Text_Widget` cho phép người dùng nhập tiêu đề, văn bản và URL hình ảnh.
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }

class My_Custom_Text_Widget extends WP_Widget {
    function __construct() {
        parent::__construct(
            'my_custom_text_widget', // Base ID
            __( 'Widget Văn bản Tùy chỉnh Của Tôi', 'ten-plugin-cua-ban' ), // Widget name
            array( 'description' => __( 'A simple text widget that can display an image.', 'ten-plugin-cua-ban' ) ) // Description
        );
    }

    // Frontend display
    public function widget( $args, $instance ) {
        echo $args['before_widget'];
        if ( ! empty( $instance['title'] ) ) { echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title']; }
        if ( ! empty( $instance['text'] ) ) { echo '<p>' . wp_kses_post( $instance['text'] ) . '</p>'; }
        if ( ! empty( $instance['image_url'] ) ) { echo '<img src="' . esc_url( $instance['image_url'] ) . '" alt="' . esc_attr( $instance['title'] ) . '" style="max-width:100%; height:auto;">'; }
        echo $args['after_widget'];
    }

    // Admin form
    public function form( $instance ) {
        $title = ! empty( $instance['title'] ) ? $instance['title'] : __( 'New title', 'ten-plugin-cua-ban' );
        $text = ! empty( $instance['text'] ) ? $instance['text'] : '';
        $image_url = ! empty( $instance['image_url'] ) ? $instance['image_url'] : '';
        ?>
        <p><label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php _e( 'Title:' ); ?></label>
        <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>"></p>
        <p><label for="<?php echo esc_attr( $this->get_field_id( 'text' ) ); ?>"><?php _e( 'Text:' ); ?></label>
        <textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'text' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'text' ) ); ?>" rows="5"><?php echo esc_textarea( $text ); ?></textarea></p>
        <p><label for="<?php echo esc_attr( $this->get_field_id( 'image_url' ) ); ?>"><?php _e( 'Image URL:' ); ?></label>
        <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'image_url' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'image_url' ) ); ?>" type="text" value="<?php echo esc_attr( $image_url ); ?>"></p>
        <?php
    }

    // Save settings
    public function update( $new_instance, $old_instance ) {
        $instance = array();
        $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( $new_instance['title'] ) : '';
        $instance['text'] = ( ! empty( $new_instance['text'] ) ) ? wp_kses_post( $new_instance['text'] ) : '';
        $instance['image_url'] = ( ! empty( $new_instance['image_url'] ) ) ? esc_url_raw( $new_instance['image_url'] ) : '';
        return $instance;
    }
}

// Register the widget
function register_my_custom_text_widget() { register_widget( 'My_Custom_Text_Widget' ); }
add_action( 'widgets_init', 'register_my_custom_text_widget' );
?>

Usage:

Thêm widget từ “Appearance” -> “Widgets” trong admin, cấu hình tiêu đề, văn bản và URL hình ảnh.

Step 7: Quản lý Tài Nguyên (CSS, JavaScript, Images)

Quản lý và đưa tài nguyên (CSS, JS, hình ảnh) vào hàng đợi là rất quan trọng để có một plugin chuyên nghiệp và tương tác. Những tài nguyên này thường được đặt trong thư mục `assets/`.

  • Enqueueing: Sử dụng `wp_enqueue_style()` và `wp_enqueue_script()` để tải an toàn và đúng thứ tự.
  • Code Example (add to `ten-plugin-cua-ban.php`):
<?php
// ... (previous main file code)

function my_plugin_enqueue_assets() {
    // Enqueue CSS for frontend
    wp_enqueue_style( 'my-plugin-style', plugins_url( 'assets/css/style.css', __FILE__ ), array(), '1.0.0', 'all' );
    // Enqueue JavaScript for frontend
    wp_enqueue_script( 'my-plugin-script', plugins_url( 'assets/js/script.js', __FILE__ ), array( 'jquery' ), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue_assets' ); // For frontend
// add_action( 'admin_enqueue_scripts', 'my_plugin_enqueue_assets' ); // For admin if needed
?>
  • `assets/css/style.css` Example: Chứa các kiểu dáng cho CPTs, shortcodes và widgets để đảm bảo hiển thị tốt.
/* style.css */
.my-info-box { border: 1px solid #ccc; padding: 15px; margin-bottom: 20px; background-color: #f9f9f9; border-radius: 5px; box-shadow: 2px 2px 5px rgba(0,0,0,0.1); }
.my-info-box h2 { color: #333; font-size: 20px; margin-top: 0; border-bottom: 1px solid #eee; padding-bottom: 10px; }
.my-info-box img { max-width: 100%; height: auto; margin-bottom: 10px; display: block; }
.my-info-box p { font-size: 14px; line-height: 1.6; color: #555; }
.highlight-box { background-color: #e6ffe6; border-left: 5px solid #4CAF50; padding: 10px 15px; margin-bottom: 15px; color: #333; }

Step 8: Thêm Hình Ảnh Vào Plugin (Adding Images to the Plugin)

Hình ảnh tĩnh (biểu tượng, hình ảnh mặc định) nên được đặt trong `assets/images/`.

Getting Image URLs:

  • In PHP: Sử dụng `plugins_url()`.
    <img src="' . esc_url( plugins_url( 'assets/images/default-image.png', dirname(__FILE__, 2) ) ) . '" alt="Image Description">

    `dirname(__FILE__, 2)` được sử dụng khi gọi từ một tệp trong thư mục con (ví dụ: `includes/`). Sử dụng `__FILE__` nếu gọi từ tệp plugin chính.

  • In CSS: Sử dụng đường dẫn tương đối.
    .my-custom-element { background-image: url('../images/background-pattern.png'); }

Step 9: Gỡ Lỗi và Kiểm Thử (Debugging and Testing)

  • Enable `WP_DEBUG`: Đặt `define( ‘WP_DEBUG’, true );` trong `wp-config.php` để hiển thị lỗi và cảnh báo PHP. `WP_DEBUG_LOG` có thể ghi lỗi vào một tệp.
  • `error_log()`: Sử dụng `error_log(‘My message: ‘ . $variable);` để ghi thông tin vào nhật ký lỗi của máy chủ hoặc WordPress.
  • Browser Console: Sử dụng công cụ dành cho nhà phát triển của trình duyệt (F12) để kiểm tra lỗi JavaScript và yêu cầu mạng.
  • Debugging Plugins: Các plugin như Debug Bar cung cấp thông tin chi tiết về các truy vấn cơ sở dữ liệu, hooks và tài nguyên đã tải.

Step 10: Đóng Gói Plugin (Packaging the Plugin)

Sau khi phát triển và kiểm tra, đóng gói plugin để phân phối.

  • Process: Nén toàn bộ thư mục gốc của plugin (ví dụ: `ten-plugin-cua-ban/`) vào một tệp `.zip`.
  • Installation: Tệp `.zip` này có thể được tải lên thông qua admin WordPress (“Plugins” -> “Add New” -> “Upload Plugin”) hoặc phân phối thủ công.

Conclusion

Tạo một plugin WordPress đòi hỏi sự hiểu biết về PHP, HTML, CSS và các hook của WordPress. Hướng dẫn này đã trình bày các bước thiết yếu để tạo CPTs, Shortcodes và quản lý tài nguyên. Luôn kiểm tra kỹ lưỡng trong môi trường phát triển trước khi triển khai lên một trang web trực tiếp.

 

Cùng chuyên mục

Theo dõi
Thông báo của
guest
0 Góp ý
Phản hồi nội tuyến
Xem tất cả bình luận