Ở đâu, khi nào, và làm thế nào để xóa đúng quy tắc viết lại trong phạm vi của một plugin?


10

Tôi có một chút vấn đề kỳ lạ với các quy tắc viết lại không đúng.

Tôi đã thử sử dụng flush_rewrite_rules();flush_rewrite_rules(true);.

Tôi cũng đã thử toàn cầu hóa $wp_rewritebằng cách sử dụng $wp_rewrite->flush_rules();$wp_rewrite->flush_rules(true);

Không ai trong số đó dường như đang tuôn ra các quy tắc viết lại chính xác. Những cuộc gọi đó thực sự tuôn ra các quy tắc viết lại khi được gọi. Làm thế nào để tôi biết điều này? Sử dụng giải pháp để gỡ lỗi quy tắc viết lại tuôn ra .

Hiện tại, tôi đã viết lại các quy tắc tuôn ra khi kích hoạt plugin và hủy kích hoạt plugin. Không có vấn đề ở đó.

Tôi có một trang cài đặt quản trị plugin để người dùng định cấu hình plugin. Một số cài đặt điều chỉnh cấu trúc permalink, do đó, các quy tắc viết lại được yêu cầu phải được xóa trên trang cài đặt quản trị plugin "Lưu cài đặt". (Sử dụng tiêu chuẩn update_option();) để lưu cài đặt.

Tôi muốn lưu ý rằng tùy thuộc vào cài đặt được chỉ định, các loại bài đăng tùy chỉnh được tạo để phù hợp với cài đặt do người dùng chỉ định. Vì vậy, các quy tắc viết lại phải được xóa ngay lập tức sau khi các cài đặt được lưu. Đây là nơi mọi thứ không hoạt động thích hợp.

Giải pháp liên kết ở trên để gỡ lỗi các quy tắc viết lại được cung cấp bởi @toschođang hiển thị rằng nó đang tuôn ra hàng tấn quy tắc viết lại. Tuy nhiên, khi truy cập vào mục đơn lẻ loại bài đăng tùy chỉnh hoặc thậm chí lưu trữ loại bài đăng tùy chỉnh cho vấn đề đó, mỗi lần trả về là lỗi 404.

Loại bài tùy chỉnh được đăng ký chính xác và thích hợp. Tôi biết chắc chắn đó không phải là vấn đề.

Ngay lập tức làm theo với các cài đặt trang quản trị plugin lưu. Các loại bài tùy chỉnh được tạo, cấu trúc permalink được điều chỉnh và tất cả các quy tắc viết lại được cố gắng để được xóa.

Các loại bài tùy chỉnh sau đó được tải luôn và được tải initnhư bình thường.

Vì một số lý do, các quy tắc viết lại không được xóa đúng cách, vì như tôi đã nói trước đây, truy cập các phần đơn lẻ hoặc lưu trữ của loại bài đăng tùy chỉnh trả về lỗi 404.

Bây giờ phần kỳ lạ, nếu tất cả những gì tôi làm chỉ đơn giản là truy cập trang cài đặt permalinks của chính quyền, sau đó quay lại giao diện người dùng để xem các phần đơn lẻ hoặc lưu trữ của loại bài đăng tùy chỉnh, chúng sẽ hoạt động một cách kỳ diệu như mong đợi.

Trang cài đặt permalinks quản trị đó làm gì mà tôi không làm điều đó cho phép các quy tắc viết lại tuôn ra một cách thích hợp và của tôi thì không?

Ý tôi là, như một giải pháp tạm thời, tôi đang chuyển hướng người dùng đến trang cài đặt permalinks quản trị sau khi lưu trang cài đặt quản trị plugin, nhưng đây không phải là một giải pháp lý tưởng. Tôi muốn các quy tắc viết lại chỉ cần tuôn ra đúng trong mã của plugin của tôi.

Có một điểm nào đó trong WordPress khi việc xóa các quy tắc viết lại chỉ không xóa TẤT CẢ các quy tắc nữa?

admin_menu - Trang cài đặt Plugin được thêm vào quản trị WordPress.

add_options_page() - Trang cài đặt Plugin được thêm vào trong menu Cài đặt.

Trang cài đặt được hiển thị trong cuộc gọi lại cho add_options_page(). Đây cũng là nơi $_POSTđược xử lý để cập nhật cài đặt plugin và xóa quy tắc viết lại.

Vì đây đã là một câu hỏi dài, tôi sẽ sẵn sàng cung cấp các khối mã (nếu nó giúp) trong một liên kết ngoại vi để hỗ trợ tạo ra một câu trả lời hợp lệ.


1
Có vẻ như có thể bạn đã hiểu thứ tự sai, thật khó để nói mà không thấy một số mã. trang quản trị permalinks chỉ cần gọi flush_rewrite_rules, chỉ cần xóa rewrite_rulestùy chọn và tạo lại nó, bạn có thể mở tệp wp-admin/options-permalinks.phpvà xem điều này xảy ra ở đâu. vì thao tác này chỉ xóa toàn bộ tùy chọn, nên không thể xóa một phần quy tắc.
Milo

@Milo Tôi nghĩ bạn đúng. Tôi có một lớp được tải trên initđó đăng ký các loại bài. Tôi hình dung, các cài đặt trang đang được lưu và trang sẽ tải lại ... sau đó bắn lại inithook để đăng ký các loại bài đăng cần thiết. Vì vậy, tôi đã tìm ra các loại bài đăng đã được tải và tất cả những gì tôi cần làm là cập nhật tùy chọn, sau đó xóa các quy tắc viết lại từ trang cài đặt plugin của tôi. Tôi sẽ đăng câu trả lời về cách tôi tìm ra giải pháp.
Michael Ecklund

Chỉ cần một cảnh báo flush_rewrite_rules () trong plugin của tôi đã trở thành một phần của vấn đề đối với tôi. Tôi đã xóa hook php và cuối cùng chỉ cập nhật permalinks theo cách thủ công và lỗi CPT 404 của tôi biến mất.
myol

Câu trả lời:


4

Nơi tốt nhất để xóa các quy tắc viết lại là trên kích hoạt / hủy kích hoạt plugin.

function myplugin_activate() {
    // register taxonomies/post types here
    flush_rewrite_rules();
}

register_activation_hook( __FILE__, 'myplugin_activate' );

function myplugin_deactivate() {
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'myplugin_deactivate' );

Xem bài viết về codex

Xin lỗi trước, tôi đã không giải đáp mọi thắc mắc của bạn, vì vậy đây là một chút phản hồi của người cắt cookie.


1
Cảm ơn lời đề nghị của bạn, nhưng tôi biết điều này. Vấn đề không phải là về việc kích hoạt plugin / hủy kích hoạt plugin. Nó phải được thực hiện với người dùng thay đổi cài đặt thành plugin đã hoạt động, điều chỉnh các quy tắc viết lại, do đó yêu cầu phải xóa.
Michael Ecklund

1
Tôi nghĩ đó có thể là trường hợp, nhưng tôi đã khá mệt mỏi khi đọc câu hỏi của bạn. Giải pháp của ialocin có vẻ đầy hứa hẹn, hy vọng bạn đã giải quyết được.
xe đạp vào

4

Khó có thể nói những gì sai, mà không thấy mã của bạn. Nhưng sau khi lưu một số cài đặt, thực tế là nối vào admin_initnhư hiển thị bên dưới để xóa các quy tắc viết lại của bạn.

Mã số:

add_action('admin_init', 'wpse_123401_plugin_settings_flush_rewrite');
function wpse_123401_plugin_settings_flush_rewrite() {
    if ( get_option('plugin_settings_have_changed') == true ) {
        flush_rewrite_rules();
        update_option('plugin_settings_have_changed', false);
    }
}


Bạn phải đặt tùy chọn một số vị trí tại trang cài đặt của bạn hoặc chính xác là một số vị trí trong quá trình lưu cài đặt. Làm điều đó mà không có tùy chọn là xấu, bởi vì bạn không muốn tuôn ra các quy tắc mỗi lần.


Lưu ý: chưa được kiểm tra


2
Hoặc bạn có thể sử dụng thoáng qua có thể? Nhưng chắc chắn +1 vì không xóa các quy tắc trên mỗi admin_init.
xe đạp vào

Tất nhiên bạn đúng về thoáng qua, tôi đoán tôi đã chọn *_option()vì trang cài đặt. @helgatheviking
Nicolai

Điều này rất hữu ích. Tôi đã có một tình huống tương tự như Michael. Tôi đã kết thúc việc kết hợp đề xuất của helga về việc sử dụng tạm thời và tôi đặt nó trong chức năng xác thực cho các cài đặt. Cuối cùng tôi cần phải đặt tạm thời thành false sau khi xả hoặc nếu không nó chỉ tiếp tục xóa trên mỗi lần tải trang quản trị cho đến khi hết thời gian tạm thời. Vì vậy, chức năng sử dụng một tùy chọn hoặc thoáng qua là như nhau. Tôi đoán thoáng qua có thể là tốt chỉ để giữ bảng tùy chọn sạch hơn một chút. Nhưng một điểm nhỏ.
MatthewLee

Sự khác biệt là rất nhỏ, đặc biệt là nếu các quá độ là vĩnh viễn, không hết hạn, nhưng tất nhiên các quá độ có các khả năng khác, lợi ích rất tốt để có. @MatthewLee
Nicolai

3

Tôi đã có một tệp lớp loại bài đăng chịu trách nhiệm đọc các cài đặt tùy chọn của plugin và tạo các loại bài đăng tùy chỉnh cần thiết dựa trên các cài đặt do người dùng chỉ định.

Tập tin loại bài đăng này đã được tải trên hook init.

Tôi đã tìm ra tất cả những gì tôi cần làm sau đó là cập nhật cài đặt plugin, sau đó xóa các quy tắc viết lại. Vì lớp loại bài đã được tải dựa trên các cài đặt plugin. Nhưng với các trang quản trị, chúng được tải SAU initmóc.

Các loại bài đăng chưa bao giờ thực sự được đăng ký, vì các cài đặt chưa thực sự được đặt. Lớp đăng ký loại bài kết thúc sớm kết thúc mà không có loại bài đăng ký.

Giải pháp là:

  1. Cập nhật cài đặt plugin.
  2. Tải tệp lớp loại bài CHỈ một lần ở đây để quy tắc viết lại mới được tạo.
  3. Xóa các quy tắc viết lại.

(Trước đây ... bước 2 bị thiếu - Như đã đề cập ở trên ...)

Từ giờ trở đi, các loại bài đăng sẽ được tải trên inithook và sẽ có các cài đặt được chỉ định, cho phép các loại bài đăng được tạo và ghép với các quy tắc viết lại thích hợp.

Vì lý do gì, tôi đã phải thêm một cuộc gọi JavaScript để chuyển hướng đến trang hiện tại, sau khi thực hiện ba bước trên.

Tôi cũng đã phải thêm một cuộc gọi flush_rewrite_rules();vào trang cài đặt quản trị của plugin.

Vì vậy, để đảm bảo mọi thứ được tuôn ra ...

Bước 1) Điều hướng đến trang cài đặt quản trị của plugin. - Xả ban đầu.

Bước 2) Cập nhật cài đặt plugin. - Lần xả thứ hai.

Bước 3) Trang chuyển hướng đến trang cài đặt của plugin. Gây ra ... lần xả thứ ba và lần cuối (giống như lần xả ban đầu - Hoàn thành tự động khi trang cài đặt của plugin được truy cập)

Tôi không nói rằng đây là một giải pháp thực tế, nhưng nó hiệu quả với tôi. Vấn đề rất lạ và rất có thể liên quan đến cơ sở hạ tầng mã hóa của tôi.


1

@ tazo-todua điều này cũng có hiệu quả với tôi khi sử dụng multisite.

add_action( 'wpmu_new_blog', 'set_my_permalink_structure', 11, 2 );

function set_my_permalink_structure( $blog_id ) {

    switch_to_blog( $blog_id );

    global $wp_rewrite;
    $wp_rewrite->set_permalink_structure( '/%postname%/' );
    $wp_rewrite->flush_rules();
    $wp_rewrite->init();

    restore_current_blog();
}

0

GIẢI PHÁP CỦA TÔI tìm thấy:

global $wp_rewrite; $wp_rewrite->flush_rules(); $wp_rewrite->init();

0

Tôi đã có chính xác cùng một vấn đề. Trong plugin của tôi, tôi có các loại bài đăng được tạo động. Do đó, chúng không thể được đăng ký thông qua register_post_type()một phương thức tĩnh trong activation_hookvà do đó chưa hoạt động khi flush_rewrite_rules()được chạy trong hook này (thường là cách được khuyến nghị để xóa quy tắc viết lại).

Giải pháp sạch nhất tôi có thể đưa ra cuối cùng là xóa các quy tắc viết lại sau khi đăng ký các loại bài đăng, nhưng tất nhiên chỉ khi việc xả như vậy là thực sự cần thiết (vì hoạt động chậm). Trong trường hợp của tôi, tôi thực sự có một số loại bài tùy chỉnh kế thừa từ một lớp cơ sở duy nhất và do đó, mong muốn thực hiện mã thực hiện việc xóa đó.

Việc xả nước có cần thiết hay không có thể được quyết định bằng cách xem kết quả của get_option( 'rewrite_rules' ):

class MyPostTypeClass {

public final function register_as_custom_post_type() {
    ...   //do all the setup of your post type here     
    $args = array(
                  ... //populate the other arguments as you see fit
                  'rewrite' => array('slug' => 'slug-of-your-post-type')
                 );
    register_post_type('post-type-name-of-your-post-type', $args );

    $rewrite_rules_must_be_fluhed = true;
    foreach( get_option( 'rewrite_rules' ) as $key => $rule)
        if(strpos($key, $args['rewrite']['slug'] ) === 0)
        {
            $rewrite_rules_must_be_fluhed = false;
            break;
        }
    if($rewrite_rules_must_be_fluhed)
        flush_rewrite_rules(true);
}
}

Hạn chế:

  • Liên quan đến một số mức độ mà các quy tắc viết lại chính xác mà WP tạo ra trong thời gian register_post_type().
  • Kiểm tra xem việc xả nước có cần thiết trong mỗi lần tải trang hay không cũng tạo ra một số chi phí.

Ưu điểm:

  • Đóng gói đầy đủ trong lớp đại diện cho loại bài.
  • Chỉ xóa các quy tắc viết lại nếu thực sự cần thiết.

Chỉ sử dụng điều này nếu bạn không thể đăng ký loại bài đăng của mình trong một hàm tĩnh có thể gọi trong cả hai initactivation_hook!

Sự phụ thuộc vào cách các quy tắc viết lại được tạo ra trong khi register_post_type()trông giống như có thể được giảm thiểu bằng cách thay thế thử nghiệm if(strpos($key, $args['rewrite']['slug'] ) === 0)bằng một cái gì đó phức tạp hơn, tức là một biểu thức thông thường.

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.