I'm trying to do an AJAX request in an WordPress plugin. The request is initiated on the front page embedded in an article using a custom shortcode.
I tried to combine infos from the documentation and this tutorial .
However something is going wrong when testing that method... the AJAX query hook isn't called.
This is how my page.php
script is called for short code delivery:
add_shortcode('testshortcode', 'TestShortCodeFunction');
function TestShortCodeFunction($attributes)
{
ob_start();
include(__DIR__.'/page.php');
return ob_get_clean();
}
This is my compacted test script page.php
:
<?php
add_action('wp_ajax_test', 'Test');
add_action('wp_ajax_nopriv_test', 'Test');
// do_action('wp_ajax_nopriv_test'); this calls Test()
function Test()
{
echo 'Hallo';
die();
}
?>
<script type='text/javascript'>
jQuery(document).ready(function() {
console.log("JS query started");
// The following does not call test()
jQuery.ajax({
type: "POST",
url: "http://127.0.0.1/wordpress/wp-admin/admin-ajax.php?action=test",
success: function(data) {
console.log("Query returned: "+data);
}
});
});
</script>
Output on the console is:
JS query started
Query returned: 0
The Test()
function is never call according to the PHP debugger.
The admin-ajax.php
is executed according to the network monitor ( URL http://127.0.0.1/wordpress/wp-admin/admin-ajax.php?action=test
) but returns 0
.
Inside admin-ajax.php
do_action('wp_ajax_test')
is called according to the PHP debugger.
I'd be really surprised if you managed to make those Ajax action hooks work inside an Output Buffer .
AFAIK, we should only use PHP ob_*
functions as last resort.
Here's a standard implementation. A JavaScript file will be enqueued inside the shortcode callback function, and inside it we fire a document.ready
Ajax call. The admin-ajax.php
URL is passed to a JS object using wp_localize_script
. Check the code comments for more info and the Codex for details on each WP function:
<?php
/**
* Plugin Name: (SO) Simple Ajax Shortcode
* Description: Fire an Ajax action when rendering a shortcode
* Author: brasofilo
* Plugin URL: https://stackoverflow.com/a/22585520/1287812
*/
add_shortcode( 'testshortcode', 'shortcode_so_22579460' );
add_action( 'wp_enqueue_scripts', 'enqueue_so_22579460' );
add_action( 'wp_ajax_Test_SO', 'Test_SO' );
add_action( 'wp_ajax_nopriv_Test_SO', 'Test_SO' );
/**
* Enqueue our script inside the shortcode
*/
function shortcode_so_22579460($attributes)
{
wp_enqueue_script( 'my-script' );
return '<h1>Check the broswer console.</h1>';
}
/**
* Register and localize our script
*/
function enqueue_so_22579460()
{
wp_register_script(
'my-script',
plugin_dir_url( __FILE__ ) . 'ajax.js',
array( 'jquery' ) // enqueue jQuery as dependency
);
// We can pass any number of PHP data to the JS 'wp_ajax' object
// Here, only the basics, Ajax URL and a security check
wp_localize_script(
'my-script',
'wp_ajax',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'ajaxnonce' => wp_create_nonce( 'ajax_post_validation' )
)
);
}
/**
* Ajax callback
*/
function Test_SO()
{
// Security check
check_ajax_referer( 'ajax_post_validation', 'security' );
// Demonstrative boolean value to return
$random = ( rand() % 2 != 0 );
if( $random )
wp_send_json_error( array( 'error' => 'Random is ODD' ) );
else
wp_send_json_success( 'Random is EVEN' );
}
And the JavaScript file ( ajax.js
) stored in the same folder as the plugin file:
jQuery(document).ready( function($)
{
var data = {
action: 'Test_SO',
security: wp_ajax.ajaxnonce
};
$.post(
wp_ajax.ajaxurl,
data,
function( response )
{
// Errors
if( !response.success )
{
// No data came back, maybe a security error
if( !response.data )
console.log( 'AJAX ERROR: no response' );
// Error from PHP
else
console.log( 'Response Error: ' + response.data.error );
}
// Success
else
console.log( 'Response Success: ' + response.data );
}
);
});
Here's a similar answer of mine using OOP and jQuery commands to trigger the action. And an article of interest .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.