Problembeschreibung

Wer in seinem Joomla 1.5-Projekt (ähnlich kann in Joomla 1.7 - 2.5 verfahren werden) per Ajax Daten z.B. in Module nachladen will, der will diese Responce-Daten natürlich um der Ajax-Philosophie möglichst zu entsprechen, nur reine Daten empfangen die für den Zielkontainer bestimmt sind. Es soll keine komplette Joomla-Seite und auch nicht nur der Content-Bereich geladen werden, erst recht nicht, wenn der Ajax-Zielkontainer ja eben eine Modul ist - hier nützen mir die Daten im Contentbereich nicht viel. Außerdem wie gesagt hätte ich dann im Contentbereich die komplette Komponentendaten neu geladen, was keinen Geschwindigkeitsvorteil mitbringt.

 

Zur Veranschaulichung, was wir erreichen wollen hier mal drei Beispiele:

  1. Stellen Sie sich vor, sie haben in einem Modul ein Menü. Beim Aufklappen eines Menüs, sollen das Menü erneuert werden, ohne die Seite komplett neu zu laden. Wir laden nur den Modulinhalt. Noch besser sogar, wir laden in den LI-Bereich des Menüeintrages eine neue UL-Liste und eben nur diese per Ajax nach. Ähnlich könnte man mit Pulldown-Selektionslisten als Auswahlmenü verfahren. Hier wird mit Auswahl eines Optionseintrages aus der



    Root-Pulldown-Ebene das nächste Pulldownlistenfeld mit den Einträgen der nächsten Ebenen nachgeladen usw.
  2. Der Nutzer hat in einem Modul die Möglichkeit dieses zu Toggeln, also weg- und ein-zublenden um z.B. mehr Platz zugunsten anderer Seiteninhalte zu schaffen. Diese Einstellung soll sich die Site merken. d.h. beim Aufruf der nächsten Seiten soll das gleiche Modul ebenfalls mit gleichem Status getoggelt sein. Um das zu erreichen müssen wir, wenn der User auf den Toggle-Schalter klickt nicht nur das Modul toggeln, sondern gleichzeitig eine kleine Info an den Server schicken, damit dieser den gewünschten Status in die Session schreibt. Beim nächsten Seitenaufruf kann dann aus der Session dieser Wert als Quasi-Default-Wert verwendet werden.
  3. Auch eine Instant-Suche aus einem Modul heraus könnte so realisiert werden.

Die genannten Beispiele benötigen die gleiche Verfahrensweise.

 

Prinzipiell Umsetzung

Für die Umsetzung machen wir uns die HTML-Template-Funktion von Joomla-Templates zu Nutze. Diese besteht aus folgenden Features.

  1. Wir können unserem URL einen GET-Parameter tmpl verwenden und dafür z.B. den Wert component übergeben. Damit weisen wir das Joomla-Framework an, in unserem Standardtemplate nicht z.B. die index.php als HTML-Template zu verwenden sondern ein component.php. Als Muster liegt genau diese meist im Joomla-Templateverzeichnis und i.d.R. auch in den nachinstallierten eigenen Templates. Hierfür wird dann das Joomla-Template-Overriding genutzt. Neben component gibt es häufig im Template weitere solcher HTML-Standardvorlagen, z.B. für die Seiten die Fehlerfall angezeigt werden soll (error => error.php), für die Seite-ist-offline-Anzeige (offline => offline.php) und ggf. weitere.
  2. Ein zweiteres i.d.R. vom Template unterstütztes Feature ist, dass wir sogar eigene HTML-Templates bereitstellen können. Für unser Beispiel legen wir ein Template ajaxrequest an und erstellen uns eine ajaxrequest.php.

Die Neuerstellung einer solchen HTML-Template-Datei machen wir einfach durch Kopieren einer der vorhandenen Beispielvorlagen, am besten die component.php, die ja quasi üblicherweise ungenutzt als sample dafür vorgesehen ist.

Dann müssen wir unseren Vorlage Ajax-spezifisch anpassen. Die Vorlage component.php enthält schon einen kompletten wenn auch reduzierten beispielhaften Dokumentenaufbau mit den üblichen HTML-Tags head, body sowie dem Doctype und natürlich unseren Template-Containern. All dies wird in diesem Umfang für unseren Ajax-Request nicht benötigt. Wir können also gehörig ausmisten, denn abhänigig von Ihrem erwarteten Ajax-Responce-Type (dataType) liefern dieser nur HTML-Fragemente oder JSON-Strings aus.

 

Die Spezifik beim JYAML-Template

Wie schon in anderen Beiträgen erwähnt, arbeite ich bei meinen Projekten sehr gerne mit dem YMAL-Template für Joomla von Hiebl-Media. Unter den Joomla-Version 1.5 und dem JYAML-Template 3 war es noch üblich, dass die Controller-Datei für die HTML-Templates im Ordner \templates\hm_yaml\ liegen und eigentlichen Template-Scripte dann im Template-Design-Ordner \templates\hm_yaml\index\meinDESIGN\. Die Verzeichnisstruktur hing damit zusammen, dass das JYAML-Template mehrere Design-Verwalten konnte. Im Jetztigen Joomla gibt es statt dessen die Skins. Folglich sind im J!1.7...2.5 nun die Verzeichnis-Strukturen auch im JYAML streng nach dem Template-Override-Prinzip aufgebaut.

Nicht davon verwirren lassen, dass es auch schon in der Controller-component.php eine fast identische HTML-Ausgabe gibt. Dies ist nur eine Fallback-Version, für den Fall das das eigentliche Templates-Script nicht gefunden werden kann.

Ob man denn nur im Controller-Script die Ausgaben erzeugt oder im Template-Script, darüber läßt sich streiten. Eigentlich erzeugen wir keine speziell formatierten Daten, wenn wir z.B. json-Daten ausliefern, sondern nur einen serialisierten String. Wenn jedoch das XML-Standformat verwendet wird, könnte es schon anders aussehen. Solange es nur einfach unformatierte Daten sind, tendiere ich dazu diese gleich vom Controller-Script ausliefern zu lassen. In diesem Fall könnte man sich die gesamt Template-Datei sparen und auch deren Einbinden ins Steuer-Script.

Übrigens: Der charmante Vorteil dieser Vorgehensweise ist der, dass wir dazu keine Joomla-Core- oder Template-Core-Scripte manipulieren müssen!

 

Mal ein Beipiel und ein Test

Wie oben erwähnt legen wir Dupblikate der beiden component.php-Scripte an und benennen diese jeweils als ajaxrequest.php. Dann öffnen wir die Controller-ajaxrequest.php und ändern die dortige Pfadeinbindung für den require_once()-Importierung

alt:

 

$component_file = JYAML_PATH_ABS.DS.'html'.DS.'index'.DS.$jyaml->config->design.DS.'component.php';

 

neu:

 

$component_file = JYAML_PATH_ABS.DS.'html'.DS.'index'.DS.$jyaml->config->design.DS.'ajaxrequest.php';

 

Mehr Änderungen an diesem Script sind nicht notwendig. Jetzt ändern wir zu Testzwecken schnell noch unser Template-ajaxrequest.php-Script z.B. auf diesen reduzierten Gesamtinhalt:

 

defined( '_JEXEC' ) or die( 'Restricted access' ); ?>
<?php echo __FILE__; ?>

 

So, abschließend nur noch den kleinen Test. Wir rufen folgenden URL im Browser auf:

www.ihredomain.de/?tmpl=ajaxrequest

Als Ergebnis erhalten wir die Pfadanzeige für unser Ajax-"Template"-Script z.B. in der Form

/.../.../.../templates/hm_yaml/html/index/meinDESIGN/ajaxrequest.php

 

Bsp: ToggleStatus in Session speichern

Hier mal als kleine Dreingabe ein ajaxrequest-Script, welche die Aufgabe erfüllen soll Benutzerinteraktionen und Layouteinstellungen in der Session zu speicher. Ich beschrieb ein denkbares Szenario in den Beispielen oben, bei dem ein Modul getoggelt werden soll. Dieses Beispielscript macht allerdings etwas Ajax-untypisches, es liefert keine Daten zurück die angezeigt werden, sondern lediglich zum evtl. debuggen. Es soll auch nur ein kleines Beispiel sein:

# Wir holen den GET-Parameter
$RequColToggleStatus = JRequest::getString( 'coltogglestatus', 0 );
# klein Kontrollausgabe
echo "\nRequest.ColToggleStatus: " . $RequColToggleStatus;
#Session-Objekt holen
$session =& JFactory::getSession();
Wenn der Inhalt hide oder show, dann diesen Wert in Session schreiben, und wieder kl. Kontrollausgabe
if ( $RequColToggleStatus == 'hide' || $RequColToggleStatus == 'show' ) {
	$SessColToggleStatus = $session->set('ColToggleStatus', $RequColToggleStatus);
	echo "\nSession.ColToggleStatus neu: " . $session->get('ColToggleStatus');
}