Tuesday, May 19, 2015

Ajax calls in Wordpress - Part II

Check out the first part of this article here

Now, check the more neat and cleaner and recommended method for implementing Ajax with Wordpress. So let's check out our new process ... 

1. Same old template-ajax-page.php will be our page template, where we would be writing the jQuery call. The jQuery POST method will have a small change here. Let's check it out. 

<script>
function call_me()
{
  jQuery.post(
  // Check the Target URL admin-ajax.php
  "<?php echo get_site_url();?>/wp-admin/admin-ajax.php", 
  {
    'action':  'fetch_posts',
    'data'  :  'posts_per_page=5' +
               '&post_status=publish' 
  }, 
  function(response)
  {
     // Put the response in a particular place
     jQuery('#post_lists').html(response);
  });

}
</script>

Here, the change is done only to the AJAX target URL which is "wp-admin/admin-ajax.php". Wordpress includes this file for handling AJAX request. 

2. Next, we need to open our theme's function.php and add new hooks in there. It is shown below. 

<?php
// Our custom function's definition
function my_custom_fetch_posts()
{

}


// The below statement is for situations 

// when User is logged in
add_action( 'wp_ajax_fetch_posts', 'my_custom_fetch_posts');

// The below statement is for situations 

// when User is not logged in
add_action( 'wp_ajax_nopriv_fetch_posts', 'my_custom_fetch_posts'); 
?>

The above lines are very important. Let me explain them.

In our jQuery POST method above, as our 'action' is 'fetch_posts', our target action hooks will be "wp_ajax_fetch_posts" (when user is logged in) and "wp_ajax_nopriv_fetch_posts" (when user is not logged in). The names of these two hooks can be different from each other. This hooks are created in admin-ajax.php ( our AJAX target file ) and our custom function 'my_custom_fetch_posts' is just added to the above hooks. So, in admin-ajax.php, when the action hook 'wp_ajax_fetch_posts' or 'wp_ajax_nopriv_fetch_posts' is triggered through do_action() calls, our custom function my_custom_fetch_posts() is called and executed eventually.

So, the basic is, as soon as our jQuery POST is triggered, and if 'add_foobar' is passed as 'action', target AJAX handler admin-ajax.php file fires  authenticated AJAX action hook "wp_ajax_add_foobar" ( 'wp_ajax_' . $_REQUEST['action'] ) and if we add/attach our custom function "my_function" to that hook, my_function() will  eventually be executed and the output will be returned back to the browser as a result of the AJAX call.

3. So, before above two add_action statements, we would be supplying the definition of our custom function as shown below. 

<?php
// Our custom function
function prefix_ajax_fetch_posts()
{
  
  // CHECK the action parameter
  if( isset($_REQUEST['action']) && $_REQUEST['action'] == 'fetch_posts' )
  {
   
  // Extract the data part
  parse_str( $_REQUEST['data'] );
  
  // So now we have variables like $posts_per_page
  // $post_status and $category__in
  // NOw we BUILD the arguments for WP_QUERY
  $arg = array();

    // SET number of posts          
    if(isset($posts_per_page))  
    {
 $arg['posts_per_page'] = $posts_per_page;
    }

    // SET POST status
    if(isset($post_status)) 
    {   
 $arg['post_status'] = $post_status;
    }
  
    // SET Category IDs
    if(isset($category__in))  
    {
 $arg['category__in'] = explode(",",$category__in);
    }

    // The QUERY 
    $the_query = new WP_Query( $arg );
 
    // Now do what you want to do
    // The Loop
    $output = "";
  
    while ( $the_query->have_posts() )   
    { 
 
 $the_query->the_post();

 // GET ID, Title etc   
 $title = get_the_title();
 $id = get_the_id();
  
 // BUILD the Output
 $output .= '<div class="post_details ">' . 
 get_the_post_thumbnail( $a, 'thumbnail' ) .
  '<div class="post_title"> <a href="'. get_permalink().
 '">'.$title.'</a>  </div>';
  }
 
    // output 
    echo $output;
  }
  // IF ends here
  
  die();
}

// Attach our function to the Hook

add_action( 'wp_ajax_fetch_posts', 'prefix_ajax_fetch_posts');
add_action( 'wp_ajax_nopriv_fetch_posts', prefix_ajax_fetch_posts');
?>

The statements within the above function "prefix_ajax_fetch_posts()" are same as we saw in the article discussing uglier AJAX technique. Here, they are just wrapped within a function definition. It just builds parameters to generate a WP_Query and prints the result of the query and sends back to browser.



In the above screenshot, some posts' titles are returned by server as per our logic and printed in a DIV.

Hope this helps.

Thursday, May 14, 2015

Ajax calls in Wordpress - Part I

In this article, I am going to share how we can implement ajax within Wordpress.

We can choose between two methods, one is uglier and the second one the recommended method.

Let's start with the uglier method. 

Method 1 :: 
   
   a. Here, we are going to create a new page where we would be demonstrating the ajax call.
   b. We would be creating a new template for this also.
   c. We would be requiring jQuery ajax post methods for submitting our requests.
   
   1. So, let's create a new template within the theme folder. In my case, the active theme is 'twentyfourteen'. So, within twentyfourteen/page-templates folder, we create a new template file called "template-ajax-page.php". It's content is shown below :: 
    
   This new template can be created by copy-pasting old template files (even copying page.php is also ok) and modifying the comment section as shown below.
   
 <?php
   /**
    * Template Name: AJAX PAGE
    */
 ?>
   
   So, our template file is ready. Now, on this page, we would be adding our custom jQuery post() function which would send requests to the server asynchronously and show the response on screen. 
   
   If we have created the template by copying page.php or any other template file of our choice, we would not touch any other part of the template code, but we would add a button with title "Click to call AJAX" and a custom JS function "call_me" which would be executed when click the button.
   
<script>
// Our custom JS function which submits the 
// request asynchronously
function call_me()
{
  jQuery.post(
    "<?php echo get_site_url() . "/test-ajax.php"; ?>", 
  {
'action': 'add_foobar',
'data':   'name=admin&age=34&roll_no=23'
  }, 
  function(response)
  {
     console.log('The server responded: <br>' + response);
  }
  );
} // Function ends
</script>

<!--   Our Button   -->

<input type="button" value="Click to call ajax" onclick="call_me()">


Check the jQuery.post() function structure. The first parameter is the target PHP file (test-ajax.php) which would handle the AJAX request. Second parameter of this jQuery.post() function consists of an object with member like 'action', 'data' etc. These members' names can be anything. Third parameter is the callback handler which handles the return response. Here, we have printed the response in browser console.

We can put the button HTML anywhere within the page. The test-ajax.php (Ajax Handler at the server side) can be placed within any directory within Wordpress installation, but it's path must be specified properly while calling jQuery.post() function.

So, the gist is, when the above button is clicked, "call_me" function is called which posts the 2nd parameter object (passed through jQuery.post() function). And when the server response is received, it is printed in the console.

2. So far so good, next, we would create a page and assign the above template to it. By doing this, we are making the our ajax functionality available at the front-end. So, we have created a page called "Ajax Page" and setting its template as shown below ... 



And, see, how it looks like at the front-end.




The content of the page can be shown in anyway we want. That's why I said to not to touch other part of the template file. This way, we are just adding our functionality to the existing working template (as this was copied from page.php or any other template file).

3. Now, let's create the PHP page which will handle the AJAX request. In our example, the file's name is test-ajax.php and we would create this file at the root folder of our Wordpress installation. And this would match with the path provided in the jQuery.post() function's first parameter. 

Let's check the content of test-ajax.php ...

 <?php
  // The below file is important to load Wordpress
  // Core functionalities
  require( dirname( __FILE__ ) . '/wp-blog-header.php' );
    
  // Clear the Buffer
  // This is Important, otherwise default
  // WORDPRESS-generated htmls will be available to us
  ob_end_clean();

  // PRINT the REQUEST
  print_r($_REQUEST);
?>

We have included the "wp-blog-header.php" file at the top to get the Wordpress functionality, so $wpdb object, WP_Query() functions will be automatically available to us.

With this much of arrangement, let's see what happens when we click on the "Click to call ajax" button above. Check the output below :: 

The server responded: 
Array
(
   [action] => add_foobar
   [data] => name=admin&age=34&roll_no=23
)

This output was captured at the console of the browser. So, it is clear that the data part ( 2nd Parameter of jQuery.post() function ) was successfully posted to Server. The post data "name=admin&age=34&roll_no=23" can be easily parsed and output can be generated accordingly.

Now, let's write a new jQuery which requests the server for the details of all the posts created and published within Wordpress. 

jQuery.post(
  "<?php  echo get_site_url() . "/test-ajax.php"; ?>", 
  {
'action':  'fetch_posts',
'data'  :  'posts_per_page=5' +
            '&post_status=publish' +
            '&category__in=1,2,3,4'
}, 
function(response)
        {
   // Put the response in a particular place
   jQuery('#post_lists').html(response);
 });

Here, we have added "category__in" parameter i.e our query would check if the post belongs to category ID 1,2,3 or 4Check, how we can parse the AJAX request at the server side below.

<?php
if( isset($_REQUEST['action']) && $_REQUEST['action'] == 'fetch_posts' )
{
   // Extract the data part
   parse_str( $_REQUEST['data'] );
   
   // So now we have variables like $posts_per_page
   // $post_status and $category__in
        
   // NOw we BUILD the arguments for WP_QUERY
   $arg = array();
        
   // SET number of posts        
   if(isset($posts_per_page))  
      $arg['posts_per_page'] = $posts_per_page;
 
   // SET POST status
   if(isset($post_status))  
      $arg['post_status'] = $post_status;

   // SET Category IDs
   if(isset($category__in))  
   {
      $arg['category__in'] = explode(",",$category__in);
   }

   // The QUERY
   $the_query = new WP_Query( $arg );

   // Now do what you want to do
   // The Loop
   $output = "";

   while ( $the_query->have_posts() )   
   {

      $the_query->the_post();
            
      // GET ID, Title etc
      $title = get_the_title();
      $id = get_the_id();

      // BUILD the Output
      $output .= '<div class="post_details ">' . 
         get_the_post_thumbnail( $a, 'thumbnail' ) .
         '<div class="post_title">                  <a href="'.get_permalink().
                 '">'.$title.'</a> </div>';
    }

   // output 
   echo $output;
}
?>

The above code is quite simple. 

Check how we have set the data ( 2nd parameter in jQuery.post() function ) part in our browser AJAX request. 

{
  'action': 'fetch_titles',
  'data':   'posts_per_page=5' + 
            '&post_status=publish' + 
            '&category__in=1,2,3,4'
}

Then, we are checking at the server-side for right POST variable.  

if( isset($_REQUEST['action']) && $_REQUEST['action'] == 'fetch_posts' ) 

and then we just extract parameters from the received data 'posts_per_page=5&post_status=publish&category__in=1,2,3,4' and build an array $args with which we finally create the WP_QUERY object.

Next, we just loop through all the results returned by WP_QUERY, generate a suitable HTML and output it.

On the browser side, the jQuery has a callback function defined :: 

function(response)
{
   // Put the response in a particular place
   jQuery('#post_lists').html(response);
}

which places/puts the response (server generated HTML) in a target DIV (with ID post_lists).

So, this is the simple AJAX implementation within Wordpress. Check the better method in my next article.