Devolver JSON usando el Marco Joomla

11

He empezado a construir una aplicación web usando Joomla Framework . Consiste en una página web simple que se mostrará en un iFrame junto con una API que se utilizará para actualizar el contenido con AJAX.

Seguí los Primeros pasos con Composer y Joomla! artículo y tener la aplicación Framework en funcionamiento. Personalicé la salida HTML predeterminada para que funcione en mi iFrame y comencé en la API. Utilicé News como plantilla y creé un controlador, modelo, tabla y vista para mi API, que funciona muy bien. Luego creé una plantilla Twig muy simple que devuelve una representación JSON de mis datos de esta manera:

{{ items|json_encode|raw }}

Hasta ahora todo bien, pero me devuelve este encabezado que causará problemas al usar AJAX con jQuery:

Content-Type:text/html; charset=utf-8

Pensé que sería un simple caso de agregar esto, pero no importa dónde lo coloque, no cambia el encabezado que se devuelve:

$this->app->setHeader('Content-Type', 'application/json', true);

Sé que setHeader funciona como si cambiara el nombre, veo que se devuelve el nuevo encabezado, así que supongo que se sobrescribirá más adelante en la ejecución.

Entonces mi pregunta es, ¿voy a hacer esto de la manera correcta? Mi vista extiende DefaultHtmlView que se siente mal, ¿debería crear un DefaultJsonView? ¿Cómo puedo configurar el tipo de contenido correcto o hay un mejor enfoque para devolver JSON?

Se agradece cualquier consejo que se pueda dar sobre la mejor manera de usar Joomla Framework para construir una API.

Joe P
fuente

Respuestas:

6

Finalmente encontré lo que parece ser la forma "correcta" de hacer esto. Incluso si utilicé sendHeaders, se agregó el Tipo de contenido adicional y se devolvió como se agregó más tarde.

Seguí el código y AbstractWebApplication.php establece los encabezados con esta línea:

// Send the content-type header.
$this->setHeader('Content-Type', $this->mimeType . '; charset=' . $this->charSet);

Así que pude definir mi propio mimeType usando esto en mi código:

$this->app->mimeType = 'application/json';

¡Ahora se devuelve el encabezado correcto y jQuery entiende la salida como JSON!

Joe P
fuente
3

Tomó un poco de investigación pero veo el problema

https://github.com/joomla-framework/application/blob/master/src/AbstractWebApplication.php

Si observa la función setHeader, en realidad aún no establece el encabezado, solo lo "prepara"

Entonces, lo que necesitas hacer es simple

$this->app->setHeader('Content-Type', 'application/json', true)->sendHeaders();

La función adicional sendHeaders()se puede encadenar para permitirle configurar los encabezados, no solo "prepararlos".

Con el uso más probable exit;para evitar cualquier otra ejecución y salida del JSON, la función sendHeaders probablemente no se esté ejecutando.

Jordan Ramstad
fuente
Gracias por tu sugerencia. Desafortunadamente, incluso por qué usé sendHeaders, el tipo de contenido todavía se sobrescribió. Intenté usar exit pero luego no obtuve salida ya que la plantilla no se había procesado. Encontré una solución que publiqué como respuesta.
Joe P
Bueno, agregaré otra solución, para que la mía funcione tan bien para quien la necesite. Si lo usa exit, debería evitar que se ejecute algo más y simplemente generarlo tal como está actualmente. Sin embargo, su respuesta parece mucho mejor.
Jordan Ramstad