Soeben hatte ich das Problem, dass ich die Ausgabe in einer selbst entwickelten Komponente bei Joomla deaktivieren wollte, da ich als Ausgabeformat JSON haben wollte oder gegebenenfalls auch XML oder vielleicht sogar nur Text, plain ASCII. Ich habe schon lange nichts mehr mit Joomla gemacht, musste mich also erstmal wieder an das CMS gewöhnen und hab dabei erfreut festgestellt, dass Joomla ja nach MVC-Architektur aufgebaut ist! Da ich in den letzten größeren Projekten hauptsächlich mit Zend gearbeitet hatte, kam mir das nur entgegen. Aber zum eigentlichen Problem:
Nach Recherche fand ich in der Joomla-Doku über Generating JSON output folgende Zeilen, die helfen sollen:
< ?php //Daten, die später als JSON zurück- bzw. ausgegeben werden sollen. $data = array('some data'); // Lade das Document-Objekt. $document =& JFactory::getDocument(); // Setze MIME Typ für JSON Ausgabe. $document->setMimeEncoding('application/json'); // Dem Header "sagen", dass es sich um eine Datei handelt, die heruntergeladen werden soll. Dateiendung *.json JResponse::setHeader('Content-Disposition','attachment;filename="'.$view->getName().'.json"'); // Ausgabe der Daten JSON-encoded durch die native PHP-Funktion json_encode. echo json_encode($data); ?> |
Da ich die Daten nicht als Datei benötigt habe, sondern die Ausgabe im Browser sehen wollte, hab ich die Zeile, wo der Header für eine Datei gesetzt wird, auskommentiert. Was ich bei vielen Dokus vermisse, ist der Ort, wo dieser Code eingebaut werden soll. Neulinge wissen meist nicht, wohin der Code gehört. Weiterhin kommt dazu, dass es stets mehrere Lösungen gibt, saubere und unsaubere ;). Für mich klang alles nach View, da es ja um die Ausgabe im Browser ging, daher hab ich den Code in die view.html.php der View der Komponente gepackt. Die Datei liegt unter
com_KOMPONENTENNAME/views/KOMPONENTENNAME/view.html.php |
Sie repräsentiert die View der Komponente und lädt das Default-Template unter
com_KOMPONENTENNAME/views/KOMPONENTENNAME/tmpl/default.php |
aber das nur am Rande erwähnt. Die Ausgabe jedoch entsprach nicht meinem Wunsch: Es kam der Quelltext vollständig zurück mit html, head, title, meta, body und sonstigen HTML-Tags. Nach weiterer Suche traf ich auf einen Beitrag von 2009 zum Verbergen des Administrator- oder Frontend – Layout – Templates:
JRequest::setVar('tmpl', 'component'); |
Laut Angabe soll diese Zeile im Controller eingebaut werden. Sie bewirkt, dass das Layout nur den Inhalt der View anzeigt, ohne von einem Template umrahmt bzw. gewrappt zu werden. Ich habe die Zeile direkt hinter die MIME-Anweisung in die View gepackt. Neuladen hat gezeigt, dass jetzt die Menüstruktur der gesamten Seite nicht mehr da war, sondern nur noch der Inhalt der View! … und leider noch die html, head, title, meta- und body-Tags. Zu XML- oder JSON-Output hatte ich nun nichts brauchbares mehr gefunden außer viele Fragen, wie das denn nun geht, also hab ich mein Suchquery geändert und nach Verwendung mit AJAX gesucht, da man dabei meist auch nur einen bestimmten Datensatz abfragen will ohne das Layout oder anderen Quelltext. Ebenso kann die Antwort dort ja auch JSON sein und mit AJAX weiterverarbeitet werden. Und siehe da, ich wurde fündig bei stackoverflow (wo auch sonst) in einer Antwort mit 0 „likes“:
//after $this->display($tpl); global $mainframe; $mainframe->close(); |
Dies war die Lösung. Nun nochmal im Gesamtzusammenhang der Code, der mir JSON als Ausgabe in einer View in der Joomla-Komponente ermöglicht hat:
< ?php //-- No direct access defined('_JEXEC') || die('=;)'); jimport('joomla.application.component.view'); class KOMPONENTENNAMEViewKOMPONENTENNAME extends JView { public function display($tpl = null) { // Get the document object. $document =& JFactory::getDocument(); // Set the MIME type for JSON output. $document->setMimeEncoding('application/json'); //Deaktiviert das Template und nutzt nur das Template //der Komponente JRequest::setVar('tmpl', 'component'); /* Datenverarbeitung aller Daten, beispielsweise ein * Datensatz aus der Datenbank, welcher als Array * zurückgegeben wird. Beispielcode: * $model = &$this->getModel(); * $data = $model->getData(); * echo json_encode( $data ); */ parent::display($tpl); //Deaktivierung der gesamten Layout-Komponente, //die für html, head, meta und body-Tags zuständig ist global $mainframe; $mainframe->close(); }//function }//class ?> |
Der auskommentierte Teil in der Mitte steht für den Part, in welchem die Daten geladen werden, welche später JSON-encoded ausgegeben werden sollen.
Ich hoffe, der Code hilft noch vielen weiteren, die wie ich ewig danach gesucht haben!
Ich bin kein Joomla-Experte und freue mich daher sehr über Verbesserungsvorschläge und Anmerkungen! Die Lösung funktioniert zwar, aber ist sie auch sauber?