Các phương pháp hay nhất về phản hồi cuộc gọi AJAX trong Plugin WordPress
Lời nói đầu (bạn có thể bỏ qua, nếu muốn): Một khách hàng đến gặp tôi với yêu cầu xây dựng một ứng dụng và kết hợp nó với một cài đặt WordPress hiện có. Lúc đầu, tôi đã do dự, nhưng tôi thấy rằng việc sử dụng “WordPress làm phụ trợ” có khá nhiều lợi thế: Nó có các vai trò người dùng và trang web phù hợp và bạn có thể sử dụng các plugin hiện có để đơn giản hóa sự phát triển của chính mình.
Contents
Nhiệm vụ
Như tôi đã đề cập trong lời nói đầu, sử dụng WordPress làm chương trình phụ trợ đi kèm với một số lợi ích, tôi quyết định lập trình ứng dụng mới dưới dạng một plugin. Nhưng tôi không muốn sử dụng sự kết hợp (đôi khi kỳ lạ) của PHP và HTML cũng như không gửi tất cả dữ liệu cần thiết thông qua các biểu mẫu đến phần phụ trợ.
Tôi muốn gắn bó với các công cụ mà tôi quen thuộc hơn:
- Tôi chọn Vue.js làm giao diện người dùng của mình cho ứng dụng.
- Và phần phụ trợ sẽ là một plugin WordPress.
Khi phát triển với khung giao diện người dùng như Vue.js, bạn phải sử dụng lệnh gọi AJAX để giao tiếp với phần phụ trợ của mình. Và đó là khi tôi phát hiện ra rằng tài liệu hiện có về AJAX với WordPress cảm thấy khá cũ ( https://codex.wordpress.org/AJAX_in_Plugins ) và không có ví dụ mã hoàn chỉnh và không có phương pháp hay nhất về cách làm việc với các lệnh gọi AJAX khi bằng WordPress.
Nội dung
Trong bài viết này, tôi sẽ không chỉ đề cập đến “AJAX với WordPress”, mà còn một số chủ đề liên quan:
- Khái niệm cơ bản về WordPress AJAX
- Trả lời các cuộc gọi AJAX từ plugin WordPress của bạn
- Ủy quyền
- Các phương pháp hay nhất về giao diện người dùng
- Gửi giao diện người dùng của bạn cùng với plugin của bạn
- Nonces
Khái niệm cơ bản về WordPress AJAX
Vui lòng bật gỡ lỗi ( https://wordpress.org/support/article/debugging-in-wordpress/ ) bằng cách sử dụng cả hai WP_DEBUG
và WP_DEBUG_LOG
, nó sẽ giúp cuộc sống của bạn dễ dàng hơn 🙂
Bài viết wordpress này giải thích những điều cơ bản về phản hồi cuộc gọi ajax.
Đây là Gist cũng mô tả mọi thứ bạn nên biết:
<?php | |
/* | |
General information: Your frontend has to direct the ajax calls to the /wp-admin/admin-ajax.php endpoint. | |
And it has to specify an “action” so that WordPress knows which function to call. | |
When you register an call like this: | |
add_action(‘wp_ajax_loggedin_calls’, ‘loggedin_call_function’); | |
then “loggedin_calls” is the action the frontend has to specify | |
*/ | |
if (is_admin()) { | |
// loggedin_call_function is called when an logged-in user makes an AJAX call with the action “loggedin_calls” | |
// if the user is not logged in, WordPress returns “0” | |
add_action(‘wp_ajax_loggedin_calls’, ‘loggedin_call_function’); | |
// “wp_ajax_nopriv_*” is explicitly for not logged in users | |
// not_loggedid_call_function is called when an logged-in user makes an AJAX call with the action “not_loggedin_calls” | |
// if the user is logged in, WordPress returns “0” | |
add_action(‘wp_ajax_nopriv_not_loggedin_calls’, ‘not_loggedid_call_function’); | |
} | |
function loggedin_call_function() { | |
// do your thing | |
} | |
function not_loggedid_call_function() { | |
// do your thing | |
} | |
?> |
Một điều cần lưu ý: Bạn luôn phải kiểm tra quyền trong các cuộc gọi AJAX của mình
Trả lời các cuộc gọi AJAX
Trong các chức năng của bạn, bạn nên sử dụng wp_send_json_success
hoặc wp_send_json_error
các chức năng để gửi dữ liệu trở lại khách hàng ( đây là một bài đăng stackexchange thông tin về điều đó )
Trên cài đặt mặc định, máy khách phải gửi tất cả dữ liệu x-www-form-url
, nếu không, bạn không thể truy cập nó bằng $_POST['something']
. Tôi không thích điều đó và đã tìm ra cách để gửi phân tích cú pháp dữ liệu khi sử dụng application / json Content-Type :
$data = json_decode(file_get_contents('php://input'));
Bây giờ $data
biến của bạn chứa tất cả dữ liệu yêu cầu. Bây giờ bạn có thể sử dụng cấu trúc đối tượng để truy cập dữ liệu dễ dàng hơn ( nhưng nó phụ thuộc vào phiên bản PHP của bạn ). Bỏ qua phần Các phương pháp hay nhất về giao diện người dùng khi bạn muốn biết cách gửi dữ liệu từ giao diện người dùng đến trình xử lý AJAX
Ủy quyền
Như đã giải thích trong phần đầu tiên, bạn phải tự mình ủy quyền cho các chức năng / định tuyến AJAX của mình. Nó thực sự phụ thuộc vào ứng dụng và trường hợp sử dụng của plugin của bạn. Bạn có thể thử sử dụng hàm current_user_can được tích hợp sẵn trong WordPress hoặc xây dựng hệ thống quyền / vai trò của riêng bạn mà tôi phải làm. Cuối cùng, tôi đã kết thúc với mã sau:
$data = json_decode(file_get_contents('php://input'));
$id = $data->locationId;
// I check whether the current user is allowed to access the given location
// If not the function returns wp_send_json_error(null, 401)
checkUserAccessToLocation($id);
Các phương pháp hay nhất về giao diện người dùng
Bạn nên có một thành phần duy nhất trong dự án giao diện người dùng của mình để xử lý các lệnh gọi đến phần phụ trợ: Việc duy trì và giảm xác suất lỗi sẽ dễ dàng hơn. Tôi đang sử dụng Vue.js và có một đơn giản class
để xử lý giao tiếp với phụ trợ (tôi đang sử dụng axios )
export class BackendCommunicationService {
private static async buildCall(data: {[k: string]: any}) {
const params = new URLSearchParams()
params.append('action',data['action'])
delete data['action']
const res = await Vue.axios.post('/wp-admin/admin-ajax.php', data, {params})
return res.data
}
// ..... other functions
}
Sử dụng buildCall
hàm trong rất dễ dàng class
:. this.buildCall({action: 'insert_name', name: 'Foobar'})
Điều này sẽ gọi wp_ajax_insert_name
hành động ajax đã xác định của bạn (hy vọng trước đó).
Vận chuyển plugin của bạn
Tôi muốn gửi plugin với mã ứng dụng đầy đủ. Vì vậy, tôi build
dự án giao diện người dùng và sao chép dist
thư mục đã tạo vào một assets
thư mục của plugin. Đây là kịch bản bash của tôi:
cd frontend && npm run build
cp -r dist/* ../plugin/assets/
Để có tên tệp có thể đoán được, tôi phải thêm filenameHashing: false
vào của tôi vue.config.js
.
Bây giờ tôi có mã giao diện người dùng của mình trong thư mục nội dung. Làm cách nào để đưa plugin với toàn bộ ứng dụng vào wordpress? Cách dễ nhất mà tôi tìm thấy là sử dụng mã ngắn . Đây là mã PHP của tôi để gửi ứng dụng của tôi thông qua một shortcode:
<?php
add_shortcode('get_ll_include_tags','get_ll_include_tags_func');
function get_ll_include_tags_func() {
// Load JS files
wp_register_script( 'vue-app.js', plugin_dir_url( __FILE__ ) . 'assets/js/app.js');
wp_enqueue_script( 'vue-app.js' );
wp_register_script( 'vue-vendors.js', plugin_dir_url( __FILE__ ) . 'assets/js/chunk-vendors.js');
wp_enqueue_script( 'vue-vendors.js' );
// Load CSS files of application
wp_register_style( 'vue-app.css', plugin_dir_url( __FILE__ ) . 'assets/css/app.css');
wp_enqueue_style( 'vue-app.css' );
wp_register_style( 'vue-vendors.css', plugin_dir_url( __FILE__ ) . 'assets/css/chunk-vendors.css');
wp_enqueue_style( 'vue-vendors.css' );
ob_start();
?>
<div id="app">
<div class="app__loading-spinner"></div>Application is loading...
</div>
<?php
return ob_get_clean();
}
?>
Bây giờ tôi có thể sử dụng [get_ll_include_tags]
trong bất kỳ trang wordpress nào và ứng dụng của tôi sẽ được tải.
Nonces
Thành thật mà nói, đây là một chủ đề tôi vẫn còn đang lưỡng lự. Không có mã số là có lý do chính đáng, nhưng vì tất cả các cuộc gọi AJAX đều là POST
yêu cầu và tôi đang kiểm tra ủy quyền cho mọi cuộc gọi, tôi không chắc liệu có cần các lệnh gọi không? Nhưng xin hãy sửa cho tôi, nếu tôi sai! Nếu cần các nonces, tôi đã có một vài ý tưởng về cách triển khai chúng.
Kết thúc
Tôi hy vọng điều này sẽ giúp một số người, tôi ước tôi có một bài viết như vậy khi bắt đầu phát triển plugin PHP WordPress.
Tuyên bố từ chối trách nhiệm: Tôi là người mới phát triển plugin WordPress và PHP, vì vậy hãy bình luận nếu bạn tìm thấy lỗi hoặc có nhận xét về điều gì đó