Lộ trình plugin tùy chỉnh trong Wordpress


12

Được rồi vì vậy câu hỏi của tôi khá đơn giản. Tôi cần thực hiện một số quy tắc định tuyến tùy chỉnh cho plugin của mình. Các tuyến đó sẽ chỉ có một đối số (vì vậy không có gì phức tạp) và sẽ trông như sau: http://www.example.org/myroute/myargument

Và lý tưởng, điều này sẽ gọi một lớp tùy chỉnh và hiển thị một mẫu tùy chỉnh (có thể truy cập trực tiếp vào lớp).

Cách tiếp cận tốt nhất cho việc này là gì? Chúc mừng

Câu trả lời:


15

Bạn cần làm ba điều quan trọng:

  1. Tạo quy tắc viết lại tùy chỉnh để biến các phần của URI thành các giá trị được truyền vào index.php.
  2. Thêm myroutemyargumentvào danh sách các biến truy vấn của WordPress, để WordPress không bỏ qua chúng khi chúng xuất hiện trong chuỗi truy vấn.
  3. Xóa các quy tắc viết lại.

Trước tiên, tôi sẽ khuyên bạn thay vì http://www.example.org/myroute/myargument, bạn giải quyết một số loại tiền tố hoặc hậu tố đặc biệt để biểu thị khi URI nên được coi là một trong những 'tuyến đường' đặc biệt này. Vì lợi ích của ví dụ này, tôi đã chọn tiền tố api, vì vậy nó sẽ như vậy http://www.example.org/api/myroute/myargument. Tôi chọnapi bởi vì khi tôi làm một cái gì đó RESTful, giống như những gì bạn dường như đang làm việc, nó là cho một API.

Mật mã

add_filter( 'rewrite_rules_array', 'my_insert_rewrite_rules' );
add_filter( 'query_vars', 'my_insert_query_vars' );
add_action( 'wp_loaded', 'my_flush_rules' );

// flush_rules() if our rules are not yet included
function my_flush_rules() {
    $rules = get_option( 'rewrite_rules' );

    if ( ! isset( $rules['api/(.*?)/(.+?)'] ) ) {
        global $wp_rewrite;
        $wp_rewrite->flush_rules();
    }
}

// Adding a new rule
function my_insert_rewrite_rules( $rules ) {
    $newrules = array();
    $newrules['api/(.*?)/(.+?)'] = 'index.php?myroute=$matches[1]&myargument=$matches[2]';
    return $newrules + $rules;
}

// Adding the id var so that WP recognizes it
function my_insert_query_vars( $vars ) {
    array_push( $vars, 'myroute', 'myargument' );
    return $vars;
}

Sự cố nhanh

Tất cả đều khá thẳng về phía trước. Mẫu regex được thêm vào danh sách tất cả các quy tắc viết lại trong WordPress và mẫu tùy chỉnh của bạn nằm ở đầu danh sách. Khi mẫu được khớp, WordPress sẽ ngừng xem qua danh sách các quy tắc viết lại và sử dụng các giá trị đã bắt của regex thay cho các tham chiếu ( $matches[1]$matches[2]) trong chuỗi truy vấn được truyền tới index.php.

Việc thêm các biến truy vấn myroutemyargumentvào danh sách trắng chỉ khiến WordPress chú ý đến chúng hơn là loại bỏ chúng.

Cách khác của 'không gian tên' tuyến đường tùy chỉnh của bạn

Nếu bạn muốn tránh sử dụng /api/làm tiền tố, bạn có thể sử dụng biến / trường chuỗi truy vấn thay thế. Để làm một cái gì đó như thế, bạn sẽ thay đổi regex thành một cái gì đó giống như (.*?)/(.+?)\\?api=1và sau đó thêm apinhư một tham số bổ sung cho array_push()cuộc gọi được thực hiện my_insert_query_vars().

Điều đó sẽ thay đổi tuyến tùy chỉnh để nó kích hoạt bất cứ lúc nào api=1là thành phần đầu tiên của chuỗi truy vấn, ví dụ: nó sẽ kích hoạt http://example.com/anytext/anytext?api=1.

Bỏ qua việc sử dụng thuật ngữ 'không gian tên' - chỉ sử dụng nó cho ngắn gọn.

Nếu bạn không 'không gian tên' với tiền tố hoặc hậu tố, bạn sẽ kết thúc với các mẫu URI va chạm. Điều này là do WordPress sẽ không có cách nào để phân biệt mẫu tùy chỉnh của bạn với một mẫu dự định là một bài đăng hoặc trang. Làm thế nào để WordPress biết rằng đó myroutekhông phải là phân loại, thuật ngữ hoặc trang mẹ?

Hi vọng điêu nay co ich.


1
Lưu ý tiện dụng: quy tắc được xác định my_insert_rewrite_rulestheo thứ tự định nghĩa! Bắt đầu với quy tắc dài nhất trước sau đó làm việc đơn giản nhất, nếu không / api / myroute sẽ ghi đè / api / myroute / myargument.
emc

1
@npc Đó là một điểm quan trọng cần lưu ý khi tạo quy tắc viết lại tùy chỉnh, chúng cũng có thể va chạm theo cách đó. Trong ví dụ trên, đó không phải là vấn đề vì / api / myroute đơn giản sẽ không phải là đường dẫn hợp lệ.
eddiemoya

Làm cách nào đó ai đó có thể tải một mẫu tùy chỉnh từ thư mục plugin của họ bất cứ khi nào trang example.org/api/myroute/myargument được yêu cầu?
Matt Keys

1
Đây là giải pháp thực tế và đầy đủ của wordpress: codex.wordpress.org/Rewrite_API/add_rewrite_rule
Imran Zahoor

5

Để mở rộng một chút về những gì eddiemoya đã làm ở trên:

Giống như poster ban đầu của câu hỏi này, tôi muốn tạo một bản viết lại tùy chỉnh và cũng cung cấp một mẫu tùy chỉnh cho trang viết lại đó. Mã từ edditmoya đã giúp tôi bắt đầu đi đúng hướng và tôi đã thêm một chức năng bổ sung để phục vụ mẫu tùy chỉnh của mình khi trang được truy cập.

Mẫu tùy chỉnh có thể được đặt ở bất cứ đâu, trong trường hợp của tôi, nó được lưu trong thư mục plugin.

Tôi cũng chỉ muốn kiểm tra xem các quy tắc viết lại có cần được xóa trong quá trình kích hoạt plugin hay không, vì vậy tôi đã đặt nó trên register_activation_hook

Xem bên dưới để biết ví dụ đầy đủ về những gì tôi đã làm:

CẬP NHẬT đơn giản hóa dựa trên lời khuyên từ milo

class Your_Class
{

    public function init()
    {
        add_filter( 'template_include', array( $this, 'include_template' ) );
        add_filter( 'init', array( $this, 'rewrite_rules' ) );
    }

    public function include_template( $template )
    {
        //try and get the query var we registered in our query_vars() function
        $account_page = get_query_var( 'account_page' );

        //if the query var has data, we must be on the right page, load our custom template
        if ( $account_page ) {
            return PATH_TO_PLUGIN_TEMPLATES_DIR . 'register.php';
        }

        return $template;
    }

    public function flush_rules()
    {
        $this->rewrite_rules();

        flush_rewrite_rules();
    }

    public function rewrite_rules()
    {
        add_rewrite_rule( 'account/(.+?)/?$', 'index.php?account_page=$matches[1]', 'top');
        add_rewrite_tag( '%account_page%', '([^&]+)' );
    }

}

add_action( 'plugins_loaded', array( new Your_Class, 'init' ) );

// One time activation functions
register_activation_hook( PATH_TO_PLUGIN_FILE, array( new Your_Class, 'flush_rules' ) );

1
bạn cũng có thể chỉ sử dụng add_rewrite_endpoint, sẽ tạo quy tắc cho bạn và thêm var truy vấn trong một lần. ngoài ra nếu bạn thêm các quy tắc viết lại của riêng bạn, tôi đề nghị add_rewrite_rulechức năng thay vì lọc rewrite_rules_array.
Milo

Cảm ơn Milo, tôi đã cập nhật mã để sử dụng add_rewrite_rule thay vì lọc mảng viết lại. Tôi đã xem add_rewrite_endpoint nhưng tôi nghĩ add_rewrite_tag có thể phù hợp hơn với nhu cầu của tôi. Có vẻ như add_rewrite_endpoint chủ yếu hữu ích nếu bạn muốn thêm đối số bổ sung vào các bản viết lại WP hiện có. Sửa lỗi cho tôi nếu tôi sai ở đây.
Matt Keys

1
Tôi thích cách tiếp cận hướng đối tượng. Quá nhiều nhà phát triển WP vẫn không biết cách sử dụng OOP. Cảm ơn bạn đã cố gắng khôi phục niềm tin của tôi vào các nhà phát triển PHP. ;)
Arvid
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.