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?

  • You want the drupal_json_output function. See here or there for working examples. – keithm Nov 3 '11 at 19:02
  • Can some one show an example for Drupal 7 – Patrick W. McMahon Aug 10 '15 at 15:20
17

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
    Just a quick note: it's generally preferable to use drupal_exit() instead of exit() after printing JSON. – geerlingguy May 17 '13 at 19:36
  • 2
    @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 May 17 '13 at 19:42
3

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

1

Here is a real life example for Drupal 8

https://github.com/npinos/drupal8-greenhouse

Includes controller and routing

This code returns a node count in json format exposed as an endpoint

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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