¿Cómo puedo devolver JSON real usando Drupal?

13

Me gustaría implementar una función AJAX simple localmente que me permita completar automáticamente los títulos de los nodos ya existentes a medida que el usuario escribe. Para ese fin, necesito la capacidad de tener una API que pueda buscar en los títulos de los nodos. El problema es que cuando produzco JSON sin formato, viene rodeado de etiquetas. Entonces, no importa lo que haga, sigo recibiendo ...

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

Intenté implementar una plantilla de página personalizada que ya solo genera contenido, que produjo los mismos resultados. Así es como estoy haciendo esto actualmente, en mi archivo de módulo ...

<?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);
}

¿Cómo puedo devolver JUST raw JSON?

rybosome
fuente
Quieres la drupal_json_outputfunción. Ver aquí o allá para ejemplos de trabajo.
keithm
¿Puede alguien mostrar un ejemplo para Drupal 7
Patrick W. McMahon

Respuestas:

17

Para Drupal 6, puede usar 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;
}

Para Drupal 7, cámbielo para usar 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();
}

Probablemente también sería más seguro analizar la consulta para desinfectar, verificar errores, etc., en lugar de simplemente intentar devolver el resultado.

mpdonadio
fuente
2
Solo una nota rápida: generalmente es preferible usar drupal_exit () en lugar de exit () después de imprimir JSON.
geerlingguy
2
@geerlingguy Buena captura; No me di cuenta de eso. Para aquellos que no conocen la diferencia, llamando drupal_exit () invocará hook_exit (), el desmontaje de la sesión, etc.
mpdonadio
3

Vi que no había respuesta para Drupal 8.

Para procesar JSON en Drupal 8, use el siguiente código:

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

Puedes leer más sobre esto aquí

thegrandhi
fuente