5.4 WordPress and JavaScript
WordPress projects require consideration for JavaScript integration to avoid performance and maintainability issues. Scripts are to be enqueued using WordPress’s script syntax and dynamic content should leverage the WordPress REST API instead of the older admin-ajax approach.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php
// WordPress JavaScript enqueuing with REST API support
function enqueue_theme_scripts() {
wp_enqueue_script(
'theme-main',
get_theme_file_uri('/assets/js/main.js'),
[],
wp_get_theme()->get('Version'),
true
);
// Localize script for REST API
wp_localize_script('theme-main', 'wpApiSettings', [
'apiUrl' => home_url('/wp-json/wp/v2/'),
'nonce' => wp_create_nonce('wp_rest'),
'strings' => [
'loading' => __('Loading...', 'theme-textdomain'),
'error' => __('An error occurred.', 'theme-textdomain')
]
]);
}
add_action('wp_enqueue_scripts', 'enqueue_theme_scripts');
// Custom REST API endpoint for theme-specific functionality
function register_custom_endpoints() {
register_rest_route('theme/v1', '/contact', [
'methods' => 'POST',
'callback' => 'handle_contact_form_api',
'permission_callback' => '__return_true',
'args' => [
'name' => [
'required' => true,
'sanitize_callback' => 'sanitize_text_field',
],
'email' => [
'required' => true,
'sanitize_callback' => 'sanitize_email',
'validate_callback' => 'is_email',
],
'message' => [
'required' => true,
'sanitize_callback' => 'sanitize_textarea_field',
],
],
]);
}
add_action('rest_api_init', 'register_custom_endpoints');
function handle_contact_form_api($request) {
// Verify nonce
if (!wp_verify_nonce($request->get_header('X-WP-Nonce'), 'wp_rest')) {
return new WP_Error('invalid_nonce', 'Security verification failed', ['status' => 403]);
}
$name = $request->get_param('name');
$email = $request->get_param('email');
$message = $request->get_param('message');
// Process the form submission
$result = process_contact_form($name, $email, $message);
if ($result) {
return new WP_REST_Response([
'success' => true,
'message' => 'Thank you for your message!'
], 200);
}
return new WP_Error('submission_failed', 'Failed to process your request', ['status' => 500]);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Modern WordPress REST API integration
class WordPressAPI {
constructor() {
this.apiUrl = wpApiSettings.apiUrl;
this.nonce = wpApiSettings.nonce;
}
async request(endpoint, options = {}) {
const url = endpoint.startsWith('http') ? endpoint : `${this.apiUrl}${endpoint}`;
const config = {
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': this.nonce,
...options.headers
},
...options
};
const response = await fetch(url, config);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'API request failed');
}
return response.json();
}
async get(endpoint) {
return this.request(endpoint);
}
async post(endpoint, data) {
return this.request(endpoint, {
method: 'POST',
body: JSON.stringify(data)
});
}
}
// Usage examples
const wpApi = new WordPressAPI();
// Load posts with the built-in REST API
wpApi.get('posts?per_page=6&_embed')
.then(posts => {
posts.forEach(post => {
displayPost(post);
});
})
.catch(error => {
console.error('Failed to load posts:', error);
});
// Submit contact form using custom endpoint
async function handleContactForm(form) {
const formData = new FormData(form);
const data = {
name: formData.get('name'),
email: formData.get('email'),
message: formData.get('message')
};
try {
const response = await wpApi.post('theme/v1/contact', data);
showSuccessMessage(response.message);
form.reset();
} catch (error) {
showErrorMessage(error.message);
}
}
5.4.1 When to Use admin-ajax.php
The admin-ajax.php approach should now be reserved for admin-specific functionality where the REST API isn’t appropriate:
1
2
3
4
<?php
// Still appropriate for admin-only functionality
add_action('wp_ajax_admin_dashboard_action', 'handle_admin_dashboard');
add_action('wp_ajax_bulk_process_posts', 'handle_bulk_processing');