Làm thế nào để tôi xử lý tốt nhất các hành động trang plugin tùy chỉnh?


21

Tôi liên tục gặp phải những phiền toái tương tự, vì vậy tôi nghĩ tôi sẽ xem liệu có ý tưởng hay kinh nghiệm nào ngoài đó không ...

Tôi đã tạo một plugin sử dụng trang quản trị riêng của nó. Nó phải. Bây giờ tôi đã sắp xếp các công cụ WP_List_Table (), tôi phải nói rằng nó rất tuyệt ... nhưng ....

Các trang plugin tùy chỉnh luôn tải như admin.php?page=...trừ khi tôi muốn tải chúng trực tiếp từ thư mục plugin mà tôi không tải. Bây giờ nếu tôi thực hiện một 'hành động' từ trang đó, tôi cần xử lý bằng cách nào đó và sau đó chuyển hướng trở lại trang mà không có tham số hành động. Không có vấn đề nếu tôi làm một GET hoặc POST, thực sự.

Trên tất cả các trang nội bộ, WP thực hiện điều này trên cùng một trang, nó kiểm tra xem có hành động nào không, nếu vậy xử lý nó và sau đó chuyển hướng đến chính nó mà không cần hành động. Điều này là có thể, bởi vì trên các trang admin-headernày chưa được tải.

Tuy nhiên, nếu bạn thử thực hiện nó trên trang của riêng bạn, một nửa giao diện quản trị viên đã được gửi tới trình duyệt, do đó không thể chuyển hướng được nữa. Rõ ràng, giải pháp là POST / GET trực tiếp sang một trang khác, tải khung WP trên đó, xử lý và sau đó chuyển hướng trở lại trang gốc ... nhưng ... điều đó hơi khó chịu, bởi vì ... bản gốc của tôi trang được tải thông qua một cuộc gọi lại, vì vậy nó chạy trong một phương thức của lớp tôi. Thật là đẹp.

Nếu tôi tải một trang riêng, tôi phải bao gồm một cách thủ công wp-load.phpvà nằm ngoài lớp học, điều này gây phiền nhiễu, và trong trường hợp cụ thể của tôi, đặc biệt là tôi, vì tôi chỉ ẩn danh lớp plugin của mình để không ai có thể truy cập nó từ bên ngoài.

Vậy sau câu chuyện dài này ... có ai nghĩ ra một giải pháp tốt để tải một trang khác thông qua một cuộc gọi lại mà không có toàn bộ giao diện quản trị đã được thiết lập xung quanh nó không?

(Tôi biết một cách giải quyết ... tôi có thể nối một hàm vào load-....đó để kiểm tra tham số hành động và thực hiện xử lý và chuyển hướng. Nhưng tôi tự hỏi liệu có cách nào tốt hơn không.)

Cảm ơn.


Tại sao điều này được gắn thẻ [plugin-wp-pagenavi]? [plugin-development]chắc chắn được chào đón ở đây.
Jan Fabry

@Jan Fabry: Không chắc chắn điều gì plugin-wp-pagenavidành cho ... tôi đã cho rằng nó dành cho những thứ liên quan đến sự tương quan giữa các plugin và menu quản trị. Vì câu hỏi của tôi liên quan đến điều đó, tôi đã chọn thẻ đó.
wyrfel

WP-PageNavi là một plugin có điều hướng phân trang nâng cao hơn cho giao diện người dùng. Bạn có thể sử dụng [admin-menu]ở đây, nhưng tôi không nghĩ nó thực sự liên quan đến điều đó. Tôi đã thay đổi các thẻ thành những gì tôi nghĩ phù hợp với nó, tất nhiên bạn có thể chỉnh sửa lại.
Jan Fabry

@Jan Fabry: Cảm ơn bạn đã gắn thẻ lại ... chưa quen với toàn bộ nhóm thẻ, nhưng (khá rõ ràng).
wyrfel

Câu trả lời:


28

Theo nguyên tắc thông thường, bạn nên sử dụng yêu cầu POST cho hầu hết các hành động, để đảm bảo chúng không được thực hiện một cách tình cờ . Nhưng nó cũng là một thực hành tốt để chuyển hướng đến một trang bình thường sau một yêu cầu POST, để ngăn chặn việc thực hiện trùng lặp khi người dùng làm mới trang.

Vì vậy, dòng chảy là như thế này:

  1. Trang plugin của bạn với một hình thức POST, gửi đến
  2. Một trang xử lý yêu cầu, chuyển hướng đến
  3. Trang plugin của bạn, hiển thị kết quả của hành động

Trang giữa không phải là trang plugin của bạn. Điều này có nghĩa rằng bạn có thể sử dụng "handler POST chung chung" được bao gồm ba năm trước đây, các 'admin_action_' . $_REQUEST['action']móc trongadmin.php .

Một người dùng ví dụ là plugin Akismet . Nếu bạn muốn sử dụng nó một cách đáng tin cậy, bạn phải gửi admin.phptrực tiếp , không phải đến một trang khác xảy ra admin.php.

Đây là một ví dụ rất cơ bản về cách sử dụng nó:

add_action( 'admin_action_wpse10500', 'wpse10500_admin_action' );
function wpse10500_admin_action()
{
    // Do your stuff here

    wp_redirect( $_SERVER['HTTP_REFERER'] );
    exit();
}

add_action( 'admin_menu', 'wpse10500_admin_menu' );
function wpse10500_admin_menu()
{
    add_management_page( 'WPSE 10500 Test page', 'WPSE 10500 Test page', 'administrator', 'wpse10500', 'wpse10500_do_page' );
}

function wpse10500_do_page()
{
?>
<form method="POST" action="<?php echo admin_url( 'admin.php' ); ?>">
    <input type="hidden" name="action" value="wpse10500" />
    <input type="submit" value="Do it!" />
</form>
<?php
}

Hei, tôi sẽ xem lại mã, rõ ràng là tôi không thấy điều đó, nhưng chỉ để xác nhận ... vì vậy điều bạn đang nói là nếu tôi gọi admin.php trực tiếp mà không có tham số trang, nó sẽ bỏ qua tất cả trang đang tải và chỉ thực hiện một số khởi tạo và chạy hook? Điều đó thật tuyệt vời ... ish (tôi vẫn không hiểu tại sao họ không đặt hook trước khi tải trang).
wyrfel

@wyrfel: Vâng, gọi admin.phptrực tiếp là "mánh khóe" mà nguồn Akismet đã dạy tôi. Bạn đã đúng khi bạn đang hiển thị một biểu mẫu và muốn hiển thị lại trong trường hợp có lỗi: thì thật dễ dàng nếu đích là trang plugin của bạn nhưng móc ở đâu đó khi bắt đầu (để bạn có thể chuyển hướng nếu thành công hoặc hiển thị hình thức lại với thông báo lỗi nếu không). Có thể đề nghị nó trong một vé Trac?
Jan Fabry

Tôi sẽ nộp một vé. Như một giải pháp thay thế, tôi đã tìm thấy 'load-<pagehook>'hook hoạt động ... nó được gọi trước khi trang được tải ... nhưng admin_action_...khái niệm này có vẻ đẹp hơn và cụ thể hơn rất nhiều. Ngoài ra, trên một lưu ý, các thông báo lỗi vẫn có vấn đề nếu bạn thực hiện POST và không muốn đăng lại khi tải lại, nhưng đó là một chủ đề khác.
wyrfel

@wyrfel: Tại sao thông báo lỗi vẫn có vấn đề? Nếu có thông báo lỗi, hãy ở lại trang và hiển thị lại biểu mẫu cùng với các thông báo (tất nhiên việc làm mới sẽ không có ý nghĩa nhiều ở đây - nhưng nó cũng sẽ không gây hại gì, vì các lỗi vẫn sẽ ở đó và sẽ không có hành động nào được thực thi). Nếu không có lỗi, hãy thực hiện hành động và chuyển hướng đến trang tổng quan "an toàn". Điều này sẽ hoạt động - nếu admin_action_hook sẽ được di chuyển trước trình tải trang plugin.
Jan Fabry

Ok ... tôi đã suy nghĩ quá phức tạp.
wyrfel

3

Tôi đã tiếp cận điều này hơi khác bằng cách thêm noheader = true vào url hành động trên trang nơi người dùng gửi thực hiện hành động

Trình xử lý của tôi sau đó thực hiện hành động (nghĩa là thường là thêm, cập nhật hoặc xóa) sau đó kết thúc với wp_redirect () cho hành động trang tiếp theo (ví dụ: thêm trang -> chỉnh sửa trang, xóa trang -> trang danh sách, chỉnh sửa trang -> chỉnh sửa trang ). Tôi cũng chuyển một thông báo trên URL để tôi có thể hiển thị trạng thái như cập nhật thành công hoặc thất bại.

Cách tiếp cận này giữ tất cả các hành động: liệt kê, thêm, chỉnh sửa, xóa, xóa hàng loạt, v.v ... trong cùng một lớp và với cùng một quản trị viên sên nên khá dễ dàng để duy trì và hiểu.


Người đàn ông, bạn là thiên tài! Tôi đã vật lộn trong hai ngày liền và dường như tất cả những gì tôi cần là phần "noheader = true". Cảm ơn!
r00m

0

Một cách tiếp cận khác chỉ là thêm một trường đầu vào ẩn vào biểu mẫu:

<input type="hidden" name="page" value="your-page-slug" />

Bằng cách này, WordPress dường như xử lý chuyển hướng tự độ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.