This is probably a palm slap question, but I'm confused.

I created what I thought was a simple WP template page. A form to update a form to a db via ajax callback. At the bottom I placed the add_action() statements for the callback function to fire when the form submits via WP-AJAX.

I quickly realised that the callback function (the functions in the add_action() statements) were not firing. The response code from the 'done' function in my jQuery was 0... which means WP-AJAX couldn't hook into the callback function.

add_action('wp_ajax_updateuserprofileAction',        'updateuserprofileAction');
add_action('wp_ajax_nopriv_updateuserprofileAction', 'updateuserprofileAction');

function updateuserprofileAction($args) {
$nonce = $_POST['send'];

if ( !wp_verify_nonce($_POST['send'],'jch-ajax-update-userprofile') ) {
  echo $nonce;
  die ( $nonce ); }

// Read the form values
$success = false;
$senderFirstName = isset( $_POST['senderFirstName'] ) ? preg_replace( "/[^\.\-\' a-zA-Z0-9]/", "", $_POST['senderFirstName'] ) : "";
$senderLastName = isset( $_POST['senderLastName'] ) ? preg_replace( "/[^\.\-\' a-zA-Z0-9]/", "", $_POST['senderLastName'] ) : "";   
$senderEmail = isset( $_POST['senderEmail'] ) ? preg_replace( "/[^\.\-\_\@a-zA-Z0-9]/", "", $_POST['senderEmail'] ) : "";

// If all values exist, send the email
if ( $senderFirstName && $senderLastName && $senderEmail) {

    global $current_user;

    update_user_meta( $current_user->ID, 'phone', $_POST['senderPhone']);

    if($success == 1)
else {
    die( 'ERROR');

Out of frustration, I moved the callback function and the add_action statements to a plug-in which also uses WP-AJAX and immediately... it works.

So my question is: why? Why can't you put add_action() statements into a template page? Or to put it another way: what are the 'rules' for where you can place add_action()?

Ideally, I'd like to keep the add_action() and the callback functions in the same file as the template page. Is there a way to do this?

1 Answer 1


When you send an AJAX request, wp-admin/admin-ajax.php is called, not your template file. This separate request has no knowledge of all existing code in all existing templates, because they aren’t even included.

What is included: the theme’s functions.php and plugin files. This is why your callback works in a plugin.

As a rule of thumb: templates should never contain business code. No function or class declarations, no registration of callbacks. They are templates, they should just add markup to data, nothing else.

  • Thanks. It sure would be -convenient- to be able to have functionally related code all in one place. I was hoping there was a way to declare the callback function 'globally' so that it would somehow still 'visible' to admin-ajax.php.
    – jchwebdev
    May 8, 2015 at 23:57
  • @jchwebdev The functions.php or a plugin is that global place. A template isn’t.
    – fuxia
    May 8, 2015 at 23:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.