How to show Drupal nodes using jQuery for AJAX and JSON

The other day some one asked about my familiarity with JSON and its use as a format for delivering information across the wire. I also saw that many ask about how to show Drupal nodes using AJAX. So here’s a demo module that does both. I did not break up the code but chose instead to make careful comments. This way you only have to copy and paste to get going. Enjoy!

<?php

/**
 * @author Carl McDade
 * @copyright Copyright (c) 2010, Carl McDade
 * @since 2010-02-26
 * @version 1.0
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link http://www.drupal.se Drupal Sweden
 */

/*
 * The access callbacks have been removed to allow use as a service API where they
 * requester will need an API key to access the JSON. To use this module you only
 * have to activate it so care should be taken.
 *
 */
function dajax_menu()
{
    $items[ 'dajax' ] = array(
        'page callback' => 'dajax_page',
        'access callback' => TRUE,
        'type' => MENU_CALLBACK

    );

    $items[ 'dajax/node/%/json' ] = array(
        'page callback' => 'dajax_json',
        'page arguments' => array(2),
        'access callback' => TRUE,
        'type' => MENU_CALLBACK

    );

    return $items;
}

/**
 *
 * @author Carl McDade
 * @since 2010-02-26
 * Start page and viewer for the AJAX service
 *
 *
 */

function dajax_page()
{

    /*
     * Add some links to content. You would normally get these dynamically
     * from the database but for the purposes of this demo
     */
    $content .= l('get node content','dajax/node/1/json',array('attributes' => array('class' => 'someContent')));

    $content .= ' | ';

    $content .= l('get node content','dajax/node/2/json',array('attributes' => array('class' => 'someContent')));

    $content .= ' | ';

    $content .= l('get node content','dajax/node/3/json',array('attributes' => array('class' => 'someContent')));

    $content .= '<div id="node-content">The nodes content will appear here.</div>';

    $content = theme('dajax_page', $content);

    print theme('page', $content);

}

/*
 * This is where it the complete nodes are made available. This function loads a
 * node then returns its content as a JSON object.
 *
 * NOTICE! There may be some properties that you don't want exposed.
 * You can unset them from the object here or change them in the theme_dajax_json
 * function.
 *
 * Homework: You can do some advanced mods of this module by checking for API keys
 * before allowing access. This is the reason I removed the standard access control
 *
 * Consumers can use the shorthand version jQuery.getJSON();
 *
 */

function dajax_json()
{
    $content = node_load(array('nid' => arg(2)));

    $content = theme('dajax_json', $content);

    return drupal_json(array('content' => $content));
    exit;
}

/**
 * Drupal needs to know what you will be using as a presentation for the content
 * you can use a template file or a function.
 *
 */

function dajax_theme()
{
   return array(
      'dajax_json' => array('arguments' => array('content' => NULL)),
      'dajax_page' => array('arguments' => array('content' => NULL))
   );
}

function theme_dajax_page($content)
{
    /**
     *  This is the handler for the AJAX response it is placed here so that it
     * can be overriden since it contains some HTML formatting. Drupal add js
     * automatically adds in $(document).ready(function(){
     *
     */

      drupal_add_js("

      Drupal.behaviors.dajax = function (context) {

      $('a.someContent:not(.someContent-viewed)', context).click(function () {

      var showNode = function(data) {
        $('#node-content').html(
            '<h3>' + data.content.title + '</h3>' +
            data.content.body + '<br />' +
            data.content.created
          );
      }

      $.ajax({
        type: 'POST',
        url: this.href,
        success: showNode,
        dataType: 'json',
        data: 'js=1'
       });

       return false;

       }).addClass('someContent-viewed');
       }", 'inline');

    return $content;

}

/*
 * Using a theme here to fix some of the things that need to be formatted.
 * This theme allows the use of PHP to handle the strings within the JSON object
 * avoiding the use of JQuery plugins to try and fix them after the fact.
 *
 */

function theme_dajax_json($content)
{

    // format the date before sending it to the JSON object
    $content->created = format_date($content->created);

    // format the date before sending it to the JSON object
    $content->changed = format_date($content->changed);

    return $content;
}

?>

The info file:

; $Id$ name = Dajax project = "Drupal ajax Demo" description = "A outline module demonstrating how to use Ajax using Jquery in Drupal." package = "Other" version = "6.x" core = 6.x