13

I'd like to implement a simple AJAX function locally that allows me to autocomplete node titles of already existing nodes as the user types. To that end, I need the ability to have an API that I can search on node titles. The problem is that when I output raw JSON, it comes surrounded by tags. So, no matter what I do, I keep getting...

<html>
    <head>
    </head>
    <body>
        <pre style="word-wrap: break-word; white-space: pre-wrap;"> {json here}</pre>
    </body>
</html>

I've tried implementing a custom page template that only outputs content already, that produced the same results. Here is how I am currently doing this, in my module file...

<?php

/**
 * Implementation of hook_menu()
 */
function content_relation_menu() {
    $items = array();
    $items['api'] = array(
        'title' => 'Search',
        'page callback' => 'content_relation_get',
        'access callback' => TRUE,
        'type' => MENU_CALLBACK,
    );

    return $items;
}

function content_relation_get($term = '') {
    drupal_add_http_header('Content-Type', 'application/javascript; utf-8');
    $var = json_encode(
        db_query("SELECT nid,title FROM {node} WHERE title LIKE :title LIMIT 5", array(":title" => $term.'%'))->fetchAll()
    );
    echo $var;
    exit(0);
}

How can I return JUST raw JSON?

3
  • You want the drupal_json_output function. See here or there for working examples.
    – keithm
    Commented Nov 3, 2011 at 19:02
  • Can some one show an example for Drupal 7 Commented Aug 10, 2015 at 15:20
  • This is a real life example for Drupal 8: github.com/npinos/drupal8-greenhouse. It includes controller and routing, and returns a node count in JSON, exposed as an endpoint. Commented Mar 25, 2018 at 1:02

2 Answers 2

18

For Drupal 6, you can use drupal_json

function content_relation_get($term = '') {
    $result = db_query("SELECT nid,title FROM {node} WHERE title LIKE :title LIMIT 5", array(":title" => $term.'%'))->fetchAll()
    );
    drupal_json($result);
    exit;
}

For Drupal 7, change it to use drupal_json_output

function content_relation_get($term = '') {
    $result = db_query("SELECT nid,title FROM {node} WHERE title LIKE :title LIMIT 5", array(":title" => $term.'%'))->fetchAll()
    );
    drupal_json_output($result);
    drupal_exit();
}

It would also probably be safer to parse out the query to sanitize, error check, etc, instead of just trying to return the result.

2
  • 3
    Just a quick note: it's generally preferable to use drupal_exit() instead of exit() after printing JSON. Commented May 17, 2013 at 19:36
  • 3
    @geerlingguy Good catch; didn't notice that. For those who don't know the difference, calling drupal_exit() will invoke hook_exit(), teardown the session, etc.
    – mpdonadio
    Commented May 17, 2013 at 19:42
6

I saw that there was no answer provided for Drupal 8.

In order to process JSON in Drupal 8, use the following code:

  <?php
     use Symfony\Component\HttpFoundation\JsonResponse;
     // ...
     $options = _menu_get_options(menu_get_menus(), $available_menus, array('mlid' => 0));
     return new JsonResponse($options);
  ?>

You can read more about it here

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.