Contenido "AJAX-API"
-
- Beiträge: 39
- Registriert: Fr 17. Dez 2004, 14:53
- Wohnort: NRW
- Kontaktdaten:
Contenido "AJAX-API"
HIER GIBT ES DIE AKTUELLE VERSION
Hallo zusammen,
derzeit setzte ich eine WebSite mit Contenido um, bei der ich allein auf Grund des Seitenaufbaus nicht um eine AJAX-Schnittstelle zu Contenido herumkomme. Im Netzt bin ich schon auf eine geeignete AJAX-liberay gestoßen (http://crossbrowserajax.com/). Als Basis-Funktionsparameter übergibt man einfach die Id des HTML-Elementes (z.B. DIV) dessen Inhalt ersetzt werden soll und die URL des Scriptes, welches den (neuen) Inhalt liefert. Um darauf aufbauend aber eine vernünftige Schnittstelle zu Contenido zu schaffen, müsste man meiner Meinung nach noch ein paar Dinge modifizieren und ergänzen. Letztendlich möchte ich über die AJAX-Schnittstelle spezifische Contenido-Container bzw. die zugewiesenden Module ausführen können und den generierten Code der Container/Module dann wie oben beschrieben zurückgeben. Die AJAX-Komponente arbeitet auch einwandtfrei, nur blicke ich bei der Codegenerierung der Module nicht ganz durch. Habe dafür die Datei "functions.con2.php" ins Auge gefasst, deren FUnktion "conGenerateCode" ja meines Erachtens die Codegenerierung der ganzen Seite (Layout, Template, Module) bewerkstelligt, aber darauf komm ich später zurück. Hier erstmal meine Grundgedanken für das Funktionsprinzip der "AJAX-API":
1. Blankes Layout mit einem Container erstellen
2. Modul "AJAX-API" (Details weiter unten)
3. Template "AJAX-API" erstellen, "blankes" Layout zuweisen und das "AJAX-API"-Modul dem Container zuordnen
4. "System"-Artikel erstellen und das entsprechende Layout zuweisen
5. CBA-Javascript-Libary in die "normalen" Layouts einnbinden
6. Javascript-Funktion erstellen, die CBA-Aufruf steuert (Details weiter unten)
Zu 2, "AJAX-API"-Modul":
Gehen wir mal davon aus, der erstellte Artikel mit dem AJAX-API-Template hat die idcat=2 und die idart=5, dann müsste die Javascriptfunktion der CBA-Komponente die URL "front_content.php?idcat=2&idart=5" aufrufen. Damit die AJAX-API auch weiß, von welchem Artikel sie Content zurückgeben soll, ergänzen wir folgende Variablen im URL-Aufruf "ajaxidcat" und "ajaxidart". Zusätzlich kann noch eine weitere optionale Variable "ajaxidcnt" übergeben werden, die den Container spezifiziert, dessen Modul ausgeführt werden soll. Wird dieser Parameter ausgelassen, würde/müsste sich die AJAX-API die Containerid des "Hauptinhaltes" (z.B. Container/Modul mit "CMS_HTML[x]") über eine zuvor erstellte Mandanteneinstellung holen. Das Modul müsste nun den Outputcode des Moduls aus der Datenbank holen und sowohl die entsprechende Container-Configuration, als auch evenutell im Modul vorhandene CMS-Content-Typen (CMS_HTML[x] usw.) laden und im Modulcode ersetzten. Anschließend müsste der erzeugte Code nur noch CBA konform ausgeben werden, was aber werniger problematisch ist.
Zu 6, "Javascript-Funktion":
function setContent ( id, idcat, idart ) {
var idcnt = (arguments[3]) ? arguments[3] : "false";
cbaUpdateElement ( id, "front_content.php?idcat=2&idart=5&ajaxidcat="+idcat+"&ajaxidart="+idart+"&ajaxidcnt="+idcnt )
}
PARAMETER "setContent":
id = ID des HTML-Elements dessen Inhalt ersetzt werden soll
idcat = IDCAT des Artikel dessen Inhalt dargestellt werden soll
idart = IDART des Artikel dessen Inhalt dargestellt werden soll
idcnt (optional) = ID des Containers dessen Modul ausgführt werden soll.
Desweiteren bietet die Funktion "cbaUpdateElement" weitere Parameter, mit denen sich das Cacheverhalten steuern lässt, "loading"-Texte eingebaut werden können, was an dieser Stelle aber für die Funktiontüchtigkeit der AJAX-API erstmal als nebensächlich erschien.
Um den Suchmaschinen die vollständige Indexierung der Seite zu ermöglichen habe ich auf der gesamten Seite eine Funktion zur URL-Erstellung verwendet. Diese erkennt zum einen ob die Seite im Contenido-Backend, das Frontend über einen Browser oder ob das Frontend von einem Suchmaschinenbot aufgerufen wurde und erzeugt entsprechend URLs mit oder ohne AJAX.
Im Prinzip habe ich meine Idee soweit auch schon realisiert, nur komm ich mich der Codegenerierung nicht weiter. Wäre also eine große Hilfe, könnte mir jemand Code zur Verfügung stellen, mit dem ich oben beschriebenes bewerkstelligen kann (Anhand der idcat, idart und idcnt, den Code des entsprechend zugewiesen Moduls ausführen und zurückgeben). Die dann feriggestellte "AJAX-API" stelle ich im Anschluss natürlich auch gerne allen zur Verfügung.
Wäre super jemand könnte mir rasch helfen oder zumindest einen brauchbaren Hinweis geben
und verbleibe mit besten Grüßen,
Schwarzesocke
HIER GIBT ES DIE AKTUELLE VERSION
Hallo zusammen,
derzeit setzte ich eine WebSite mit Contenido um, bei der ich allein auf Grund des Seitenaufbaus nicht um eine AJAX-Schnittstelle zu Contenido herumkomme. Im Netzt bin ich schon auf eine geeignete AJAX-liberay gestoßen (http://crossbrowserajax.com/). Als Basis-Funktionsparameter übergibt man einfach die Id des HTML-Elementes (z.B. DIV) dessen Inhalt ersetzt werden soll und die URL des Scriptes, welches den (neuen) Inhalt liefert. Um darauf aufbauend aber eine vernünftige Schnittstelle zu Contenido zu schaffen, müsste man meiner Meinung nach noch ein paar Dinge modifizieren und ergänzen. Letztendlich möchte ich über die AJAX-Schnittstelle spezifische Contenido-Container bzw. die zugewiesenden Module ausführen können und den generierten Code der Container/Module dann wie oben beschrieben zurückgeben. Die AJAX-Komponente arbeitet auch einwandtfrei, nur blicke ich bei der Codegenerierung der Module nicht ganz durch. Habe dafür die Datei "functions.con2.php" ins Auge gefasst, deren FUnktion "conGenerateCode" ja meines Erachtens die Codegenerierung der ganzen Seite (Layout, Template, Module) bewerkstelligt, aber darauf komm ich später zurück. Hier erstmal meine Grundgedanken für das Funktionsprinzip der "AJAX-API":
1. Blankes Layout mit einem Container erstellen
2. Modul "AJAX-API" (Details weiter unten)
3. Template "AJAX-API" erstellen, "blankes" Layout zuweisen und das "AJAX-API"-Modul dem Container zuordnen
4. "System"-Artikel erstellen und das entsprechende Layout zuweisen
5. CBA-Javascript-Libary in die "normalen" Layouts einnbinden
6. Javascript-Funktion erstellen, die CBA-Aufruf steuert (Details weiter unten)
Zu 2, "AJAX-API"-Modul":
Gehen wir mal davon aus, der erstellte Artikel mit dem AJAX-API-Template hat die idcat=2 und die idart=5, dann müsste die Javascriptfunktion der CBA-Komponente die URL "front_content.php?idcat=2&idart=5" aufrufen. Damit die AJAX-API auch weiß, von welchem Artikel sie Content zurückgeben soll, ergänzen wir folgende Variablen im URL-Aufruf "ajaxidcat" und "ajaxidart". Zusätzlich kann noch eine weitere optionale Variable "ajaxidcnt" übergeben werden, die den Container spezifiziert, dessen Modul ausgeführt werden soll. Wird dieser Parameter ausgelassen, würde/müsste sich die AJAX-API die Containerid des "Hauptinhaltes" (z.B. Container/Modul mit "CMS_HTML[x]") über eine zuvor erstellte Mandanteneinstellung holen. Das Modul müsste nun den Outputcode des Moduls aus der Datenbank holen und sowohl die entsprechende Container-Configuration, als auch evenutell im Modul vorhandene CMS-Content-Typen (CMS_HTML[x] usw.) laden und im Modulcode ersetzten. Anschließend müsste der erzeugte Code nur noch CBA konform ausgeben werden, was aber werniger problematisch ist.
Zu 6, "Javascript-Funktion":
function setContent ( id, idcat, idart ) {
var idcnt = (arguments[3]) ? arguments[3] : "false";
cbaUpdateElement ( id, "front_content.php?idcat=2&idart=5&ajaxidcat="+idcat+"&ajaxidart="+idart+"&ajaxidcnt="+idcnt )
}
PARAMETER "setContent":
id = ID des HTML-Elements dessen Inhalt ersetzt werden soll
idcat = IDCAT des Artikel dessen Inhalt dargestellt werden soll
idart = IDART des Artikel dessen Inhalt dargestellt werden soll
idcnt (optional) = ID des Containers dessen Modul ausgführt werden soll.
Desweiteren bietet die Funktion "cbaUpdateElement" weitere Parameter, mit denen sich das Cacheverhalten steuern lässt, "loading"-Texte eingebaut werden können, was an dieser Stelle aber für die Funktiontüchtigkeit der AJAX-API erstmal als nebensächlich erschien.
Um den Suchmaschinen die vollständige Indexierung der Seite zu ermöglichen habe ich auf der gesamten Seite eine Funktion zur URL-Erstellung verwendet. Diese erkennt zum einen ob die Seite im Contenido-Backend, das Frontend über einen Browser oder ob das Frontend von einem Suchmaschinenbot aufgerufen wurde und erzeugt entsprechend URLs mit oder ohne AJAX.
Im Prinzip habe ich meine Idee soweit auch schon realisiert, nur komm ich mich der Codegenerierung nicht weiter. Wäre also eine große Hilfe, könnte mir jemand Code zur Verfügung stellen, mit dem ich oben beschriebenes bewerkstelligen kann (Anhand der idcat, idart und idcnt, den Code des entsprechend zugewiesen Moduls ausführen und zurückgeben). Die dann feriggestellte "AJAX-API" stelle ich im Anschluss natürlich auch gerne allen zur Verfügung.
Wäre super jemand könnte mir rasch helfen oder zumindest einen brauchbaren Hinweis geben
und verbleibe mit besten Grüßen,
Schwarzesocke
HIER GIBT ES DIE AKTUELLE VERSION
Zuletzt geändert von Schwarzesocke am Di 7. Apr 2009, 13:57, insgesamt 5-mal geändert.
die vermutlich einfachste lösung dürfte sein:
(1) die container im layout mit zeichen xml-knoten einzuschliessen, die im response immer noch erscheinen. zb. <ajaxmodul id="7"></ajaxmodul>
(2) die ganze seite rendern lassen
(3) mit regex den interessanten bereich isolieren
(4) diesen dann zurück geben.
dabei würde die front_content.php die ajax-xml-knoten standardmässig entfernen. bei übergabe von z.b. &coi=7 (für Content Of Interest) würde es die xml-knoten belassen, die regex anwenden und nur den interessanten bereich ausgeben.
tönt das nach einem ansatz?
(1) die container im layout mit zeichen xml-knoten einzuschliessen, die im response immer noch erscheinen. zb. <ajaxmodul id="7"></ajaxmodul>
(2) die ganze seite rendern lassen
(3) mit regex den interessanten bereich isolieren
(4) diesen dann zurück geben.
dabei würde die front_content.php die ajax-xml-knoten standardmässig entfernen. bei übergabe von z.b. &coi=7 (für Content Of Interest) würde es die xml-knoten belassen, die regex anwenden und nur den interessanten bereich ausgeben.
tönt das nach einem ansatz?
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)
-
- Beiträge: 39
- Registriert: Fr 17. Dez 2004, 14:53
- Wohnort: NRW
- Kontaktdaten:
das ist in jedem fall ressourcenintensiver. da hast du absolut recht. jeder andere ansatz erfordert allerdings - so ist mindestens meine einschätzung - anpassungen am core.
ein weiterer ansatz ist möglicherweise folgender:
eine weitere php-datei erstellen, die den kontext von contenido aufbaut. anschliessend müsste aufgrund der idart sowie des coi (container of interest) das entsprechende modul recherchiert und ausgeführt werden. hier haben wir einfach das problem, dass die konfiguration noch nicht integriert wäre. die müsste man auch noch aus der db abfragen und die erforderlichen ersetzungen vornehmen.
dieser ansatz spart erheblich ressourcen und wird wesentlich performanter sein. aber gibt auch viel mehr zu tun. wie gesagt, dass ist lediglich eine schnelle einschätzung der situation. vielleicht würden sich noch andere möglichkeiten ergeben, wenn man die sachlage etwas vertiefter analysieren würde.
ein weiterer ansatz ist möglicherweise folgender:
eine weitere php-datei erstellen, die den kontext von contenido aufbaut. anschliessend müsste aufgrund der idart sowie des coi (container of interest) das entsprechende modul recherchiert und ausgeführt werden. hier haben wir einfach das problem, dass die konfiguration noch nicht integriert wäre. die müsste man auch noch aus der db abfragen und die erforderlichen ersetzungen vornehmen.
dieser ansatz spart erheblich ressourcen und wird wesentlich performanter sein. aber gibt auch viel mehr zu tun. wie gesagt, dass ist lediglich eine schnelle einschätzung der situation. vielleicht würden sich noch andere möglichkeiten ergeben, wenn man die sachlage etwas vertiefter analysieren würde.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)
ich habe mir soeben noch die con_code genauer angeschaut. da ergibt sich vielleicht auch ein ansatz.
wenn du dir den code der con_code ansiehst (die kriegt man über die idcatart), dann stellst du fest, dass jeder container mit folgendem php-code beginnt.
damit müsste sich der massgebliche modulcode auf basis der container-id auch isolieren und einzeln ausführen lassen.
dabei müsste es sich durch einen kleinen patch machen lassen. irgendwo im core wird der con_code ausgelesen und evaluiert. unmittelbar davor müsste man eingreifen und nur einen teil davon nehmen (mit regex isolieren) und nur diesen evaluieren lassen, statt den ganzen code.
wenn du die entsprechende stelle im code findest, müsste es sich relativ einfach lösen lassen. das wäre der wohl performanteste ansatz.
lass mich wissen, wenn ich dir ggf. weiterhelfen kann.
gruss,
andreas
ps: das ganze tönt übrigens sehr interessant.
wenn du dir den code der con_code ansiehst (die kriegt man über die idcatart), dann stellst du fest, dass jeder container mit folgendem php-code beginnt.
Code: Alles auswählen
<?php $cCurrentContainer = 80; ?><?php
dabei müsste es sich durch einen kleinen patch machen lassen. irgendwo im core wird der con_code ausgelesen und evaluiert. unmittelbar davor müsste man eingreifen und nur einen teil davon nehmen (mit regex isolieren) und nur diesen evaluieren lassen, statt den ganzen code.
wenn du die entsprechende stelle im code findest, müsste es sich relativ einfach lösen lassen. das wäre der wohl performanteste ansatz.
lass mich wissen, wenn ich dir ggf. weiterhelfen kann.
gruss,
andreas
ps: das ganze tönt übrigens sehr interessant.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)
-
- Beiträge: 39
- Registriert: Fr 17. Dez 2004, 14:53
- Wohnort: NRW
- Kontaktdaten:
Genau datt hatte ich vor, allerdings bin ich nicht auf die Option mit dem auslesen der "con_code"-Tabelle gekommen. Der entscheidene Teil im Core dürfte "includes/functions.con2.php" sein. Die Funktion "conGenerateCode" erzeugt doch den Inhalt für "con_code". Bei dem SQL-Syntax für die Abfrage der Containerconf. müsste man einfach eine Beschränkung auf den spezifischen Container einbauen, /* Create code for all containers */ (Zeile 244) auf einen reduzieren und die Layout- und Metatagberücksichtugung kegeln und den Code evaluieren - richtig? Werde diesen Ansatz mal verfolgen.
P.S.: ...und ja, interessant ist es für vor allem auch, da ich besagtes Projekt bis zum 1.9. fertiggestellt haben muss. Daher komm ich auf Dein Angebot bezüglich der Hilfe natürlich ausgesprochen gern zurück
Die Seite steht soweit auch schon, nur plage ich mich derzeit mit einer ganz fiesen AJAX-Lösung ab: Alle entsprechenden Module zusätzlich gemeinsam in ein ein weiters kopiere und nur für den Output im Frontend umbasteln 
P.S.: ...und ja, interessant ist es für vor allem auch, da ich besagtes Projekt bis zum 1.9. fertiggestellt haben muss. Daher komm ich auf Dein Angebot bezüglich der Hilfe natürlich ausgesprochen gern zurück


wie gesagt würde ich der einfachheit halber im layout alle container mit einer zeichenfolge einschliessen, die sich dann in der con_code wiederfindet und in der ausgabe nicht stört. das könnten z.b. html-kommentare sein. z.b.
und
die code-generierung könnte man so belasen, wie sie zurzeit ist. eine regex ist extrem schnell und stört die performance nicht.
man müsste also lediglich vor dem aufruf des eval() prüfen, ob $_GET['coi'] gesetzt ist und - wenn das der fall ist - den interessierenden teil des zu evaluierenden bereiches herausfinden (mit regex). und dann natürlich nur diesen teil ausführen lassen.
damit sollte sich das ganze mit drei, vier zeilen php lösen lassen. ich mache mich mal auf die suche nach der besagten stelle. oder hast du die bereits gefunden?
kannst du mal probeweise die kommentare im layout einfügen und den so entstehenden code in der con_code hier publizieren. dann erstelle ich einen regex für die isolation.
Code: Alles auswählen
<!-- container1 -->
Code: Alles auswählen
<!-- /container1 -->
man müsste also lediglich vor dem aufruf des eval() prüfen, ob $_GET['coi'] gesetzt ist und - wenn das der fall ist - den interessierenden teil des zu evaluierenden bereiches herausfinden (mit regex). und dann natürlich nur diesen teil ausführen lassen.
damit sollte sich das ganze mit drei, vier zeilen php lösen lassen. ich mache mich mal auf die suche nach der besagten stelle. oder hast du die bereits gefunden?
kannst du mal probeweise die kommentare im layout einfügen und den so entstehenden code in der con_code hier publizieren. dann erstelle ich einen regex für die isolation.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)
ich glaube, ich habe die richtige stelle gefunden. in der front_content.php auf zeile 857 (eine leerzeile) ist der code fertiggestellt und liegt in der variable $code.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)
-
- Beiträge: 39
- Registriert: Fr 17. Dez 2004, 14:53
- Wohnort: NRW
- Kontaktdaten:
wenn du die container wie folgt einkleidest (im layout):
(wobei die 1 durch die container-id zu ersetzen ist), dann kannst du mit folgendem regex die einzelnen code-fragmente ermitteln...
in $matches stehen dann die einzelnen fragmente:
$matches[0][1] liefert die container-id des ersten containers
$matches[0][2] liefert das code-fragment des ersten containers
du musst bloss durch $matches iterieren und beim richtigen container den code nehmen und dann $code durch den entsprechenden code ersetzen.
beim eval sollte dann nur noch das eine modul ausgeführt werden.
Code: Alles auswählen
<!-- container 1 -->
<container...
<!-- /container 1 -->
Code: Alles auswählen
$regex = '/<!--\\s*container\\s*([0-9])*\\s*-->(.*)<!--\\s*\/container\\s*\\1\\s*-->/s';
preg_match_all($regex, $code, $matches);
$matches[0][1] liefert die container-id des ersten containers
$matches[0][2] liefert das code-fragment des ersten containers
du musst bloss durch $matches iterieren und beim richtigen container den code nehmen und dann $code durch den entsprechenden code ersetzen.
beim eval sollte dann nur noch das eine modul ausgeführt werden.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)
-
- Beiträge: 39
- Registriert: Fr 17. Dez 2004, 14:53
- Wohnort: NRW
- Kontaktdaten:
Hallo zusammen,
habe die letzten Tage wie versprochen, noch etwas an der AJAX-API gearbeitet und wollte nun die erste Version veröffentlichen. Vorab aber noch ein paar Infos zum Projekt allgemein. Mit diesem "Mod" habe ich beabsichtigt, eine vernünftige AJAX-Schnittstelle für das Contenido-Frontend zu entwickeln. Zu aller erst wollte ich über die Schnittstelle den Code spezifischer Module neu generieren und ausgeben lassen. Für die Umsetzung gab mir "kummer" den Ratschlag, die relevanten Bereiche in den Contenido-Layouts mit z.B. HTML-Kommentaren zu versehen um dann bei der Codeausgabe im Frontend, mit regulären Ausdrücken den Code auf den entsprechenden Abschnitt zu reduzieren und dann entsprechend Formatiert an das Ajaxobjekt zurückzugeben. Alternativ hätte sich noch die Möglichkeit ergeben, mit den "<?php $cCurrentContainer = 1; ?>-Codefragmenten der Container zu arbeiten, nur eröffneten sich mit einer dritten Variante noch bessere Möglichkeiten - equivalent zur Container-Deklaration in den Layouts. Dies ermöglicht im Gegensatz zur zweiten Variante, mehrere Module bzw. Container in einen AjaxConainer zu packen (z.B. vorteilhaft wenn man den Hauptinhalt der Seite vie AJAX aktuallisieren will und sich dieser aus mehreren Modulen zusammensetzt) und die ID des HTML-Elements vorzubelegen, in dem der neue Inhalt angezeigt werden soll. Kurz: Bei der URL, die vom AJAX-Script zum Laden des Inhalts aufgerufen wird, sind nun lediglich eine bzw. zwei wohlbekannte Variablen erforderlich zu übergeben: idcat oder idcat und idart. Es ist aber auch alternativ möglich, einen oder mehrere spezielle(n) zuvor im Layout definierten AjaxContainer zu aktuallisiern. Die vorgegebene Funktion zum aktuallisieren von Inhalt der CBA-Libary, musste ich natürlich etwas anpassen, da Teile für diese Anwendung überflüssig wurden und somit keine Verwendung mehr fanden. Eine Funktion ist jedoch auch hinzugekommen, der Inhalt der Elemente wird jetzt nur noch aktuallisiert, wenn sich dieser auch tatsächlich verändert hat (wichtig wenn man z.B. mit scrollbaren DIV-Tags arbeitet).
Bei mir läuft die AJAX-API soweit gut, sowohl im Firefox (2.0.0.6), als auch im Opera (9.02) und IE (7). Daher werde ich sie Euch nun nicht mehr vorenthalten. Vor der Integration aber bitte umbedingt ein Backup der betroffenden Datei(en) machen - danke!
Getestet mit:
Contenido 4.6.15
PHP 4.4.3
LINUX-Server mit Apache 2.0
SETUP:
01. CBA-LIBARY (JAVASCRIPT)
- CBA-Libary downloaden: http://crossbrowserajax.com/ (Non-compressed)
- Entpacken und die Datei "cba.js" ins Verzeichnis "cms/js" kopieren oder
über "Styles -> Script" ein "Neues Script erstellen" (cba.js) und den Inhalt
reinkopieren und speichern.
- Gesamten Code der Funktion "cbaUpdateElement" (cba.js) durch folgenden ersetzten und speichern:
- Script in das oder die Layouts einbinden (<script type="text/javascript" language="javascript" src="js/cba.js"></script>)
02. CONTENIDO-CORE ANPASSEN (PHP)
Datei: cms/front_content.php
Aktionen:
- Backup anlegen!
- Codestelle suchen:
- Ersetzen durch:
03. AJAX-CONTAINER IM LAYOUT DEFINIEREN (HTML)
Die Ajax-Container ähnelm dem neuem Container-Syntax von Contenido. Um im Layout einen Bereich zu definieren, der über die AJAX-Schnittstelle neu generiert und ausgegeben werden können soll, umschließen wir diesen einfach mit:
Wobwei die "id" genau wie bei den standart Contenido-Containern unique sein muss, "target" muss die Id des HTML-Elements enthalten, in dem der umschlossene Bereich dargestellt werden soll:
Beispiel:
Erläuterung:
Beim Aktuallisiern der Seite bzw. beim Aufruf eines neue Artikels über die Ajax-Schnittstelle, würde nun der Output alle drei Module neu generiert und sofern sich dieser verändert hat, in "main_content" ausgegeben werden. So lassen sich beliebig viele Bereiche definieren und über die AJAX aktuallisieren. Überschneiden sollten sich diese aber nicht.
04. VERLINKUNG / AJAX-CONTAINER ANSPRECHEN (HTML, Javascript & PHP)
Um die zovor definierten Ajax-Container zu aktualliesern kann man nun wie folgt vorgehen:
Option A:
Option B:
Option C:
Erläuterung:
Der Artikel dessen Content geladen werden soll wird wie gewohnt über "idcat" und/oder "idart" definiert. Die weitere Variable "idcnt" wird entweder mit "auto" übergeben, so werden alle im Layout vorhandenen Ajaxcontainer ausgegeben oder ein oder mehrere mit Kommata getrennte IDs der AjaxContainer explizit angegeben. Alle anderen AjaxContainer werden dann bei der Aktuallisierung ignoriert. Für die "auto"-Funktion habe ich schon angedacht, die AjaxContainer im Layout mit weiteren Parametern wie "automode" zu versehen. Darüber ließe sich dann z.B. das Aktuallisierungverhalten kontrollieren, ob ein Container immer neugeladen wird, nur wenn sich der Inhalt verändert hat oder ob er z.B. ignoriert werden soll, wenn idcnt=auto ist und nur über den exklusiven Aufruf (Opt. B & C) aktuallisiert werden kann. Für mich hatte sich da jetzt noch kein konkreter Bedarf ergeben, allerdings wäre dies z.B. für den Einsatz verschiedener Layouts sinnvoll um z.B. den kompletten Body-Bereich zu aktuallisieren... aber darauf komm ich noch mal in ein paar Tagen zurück.
Um mir die Linkgenerierung etwas zu vereinfachen, habe ich mir noch eine kleine PHP-Funktion geschrieben und global verfügbar gemacht die zum Einen alle damit generierten Links im Backendeditor "backendkompatibel" mach und wie ich mir erhoffe, nebenbei noch Suchmaschinen ermöglicht, die Seiten vernünftig zu indexieren.
Anwendungsbeispiele:
Ausgabebeispiel und Erläuterung für den zweiten Link:
Der Link wird wie gewohnt mit dem href-Attribut und er entsprechenden URL zum Artikel generiert. Zusätzlich wird jedoch noch über onclick="return false" verhindert, dass der Browser beim Anklicken den mit "href" angegebenen Link normal aufruft, Suchmaschinen den Link aber verfolgen können (http://www.delorie.com/web/lynxview.html nach, dürfte meine Theorie auch in der Praxis zustreffen). Über den EventHandle "onmouseup" wird dann die URL der AjaxSchnittstelle übergeben. Diese kann auch noch mitweiteren Variablen übergeben werden, um z.B. Formulareingaben etc. zu verarbeiten.
Da ich für die zusätzliche Suchmaschinen optimieung die ReWriteEngine nutze, sehen die letzten Zeilen der Funktion zur Linkerstellung bei mir noch etwas anders aus. Die Ausgabe der Links ist also auch in einer ReWriteEngine-Form möglich (Vergelich: "front_content.php?idcat=".$idcat : "front_content.php?idcat=".$idcat."&idart=".$idart" und "index_".$idcat.".html" : "index_".$idcat."_".$idart.".html").
Hoffe Ihr kommt mit der Beschreibung klar, bin heute leider erstmal noch unterwegs Geld verdienen... bis später dann und viel Spaß und Erfolg mit der Anpassung. Über positive Implementations-Berichte freue ich mich sehr, aber auch negativen werde ich mich natürlich widmen
Beste Grüße,
Schwarzesocke
habe die letzten Tage wie versprochen, noch etwas an der AJAX-API gearbeitet und wollte nun die erste Version veröffentlichen. Vorab aber noch ein paar Infos zum Projekt allgemein. Mit diesem "Mod" habe ich beabsichtigt, eine vernünftige AJAX-Schnittstelle für das Contenido-Frontend zu entwickeln. Zu aller erst wollte ich über die Schnittstelle den Code spezifischer Module neu generieren und ausgeben lassen. Für die Umsetzung gab mir "kummer" den Ratschlag, die relevanten Bereiche in den Contenido-Layouts mit z.B. HTML-Kommentaren zu versehen um dann bei der Codeausgabe im Frontend, mit regulären Ausdrücken den Code auf den entsprechenden Abschnitt zu reduzieren und dann entsprechend Formatiert an das Ajaxobjekt zurückzugeben. Alternativ hätte sich noch die Möglichkeit ergeben, mit den "<?php $cCurrentContainer = 1; ?>-Codefragmenten der Container zu arbeiten, nur eröffneten sich mit einer dritten Variante noch bessere Möglichkeiten - equivalent zur Container-Deklaration in den Layouts. Dies ermöglicht im Gegensatz zur zweiten Variante, mehrere Module bzw. Container in einen AjaxConainer zu packen (z.B. vorteilhaft wenn man den Hauptinhalt der Seite vie AJAX aktuallisieren will und sich dieser aus mehreren Modulen zusammensetzt) und die ID des HTML-Elements vorzubelegen, in dem der neue Inhalt angezeigt werden soll. Kurz: Bei der URL, die vom AJAX-Script zum Laden des Inhalts aufgerufen wird, sind nun lediglich eine bzw. zwei wohlbekannte Variablen erforderlich zu übergeben: idcat oder idcat und idart. Es ist aber auch alternativ möglich, einen oder mehrere spezielle(n) zuvor im Layout definierten AjaxContainer zu aktuallisiern. Die vorgegebene Funktion zum aktuallisieren von Inhalt der CBA-Libary, musste ich natürlich etwas anpassen, da Teile für diese Anwendung überflüssig wurden und somit keine Verwendung mehr fanden. Eine Funktion ist jedoch auch hinzugekommen, der Inhalt der Elemente wird jetzt nur noch aktuallisiert, wenn sich dieser auch tatsächlich verändert hat (wichtig wenn man z.B. mit scrollbaren DIV-Tags arbeitet).
Bei mir läuft die AJAX-API soweit gut, sowohl im Firefox (2.0.0.6), als auch im Opera (9.02) und IE (7). Daher werde ich sie Euch nun nicht mehr vorenthalten. Vor der Integration aber bitte umbedingt ein Backup der betroffenden Datei(en) machen - danke!
Getestet mit:
Contenido 4.6.15
PHP 4.4.3
LINUX-Server mit Apache 2.0
SETUP:
01. CBA-LIBARY (JAVASCRIPT)
- CBA-Libary downloaden: http://crossbrowserajax.com/ (Non-compressed)
- Entpacken und die Datei "cba.js" ins Verzeichnis "cms/js" kopieren oder
über "Styles -> Script" ein "Neues Script erstellen" (cba.js) und den Inhalt
reinkopieren und speichern.
- Gesamten Code der Funktion "cbaUpdateElement" (cba.js) durch folgenden ersetzten und speichern:
Code: Alles auswählen
function cbaUpdateContent ( _url )
{
// set _debug
var _debug = false;
// set _caching
var _caching = (arguments.length > 1) ? arguments[1] : true;
// set _return_false
var _return_false = (arguments.length > 2) ? arguments[2] : true;
if (_debug) alert ("URL: " + _url) ;
// create CBA object (unless exists)
if (!_cba) _cba = new cbaRequest();
// query
_cba.query( _url, function() {
for (key in _cba.answer) {
txt = document.getElementById( key ).innerHTML;
while (txt.search(String.fromCharCode(9)) != -1) {
txt = txt.replace(String.fromCharCode(9), '');
}
while (txt.search(String.fromCharCode(10)) != -1) {
txt = txt.replace(String.fromCharCode(10), '');
}
while (txt.search(String.fromCharCode(13)) != -1) {
txt = txt.replace(String.fromCharCode(13), '');
}
if (txt != _cba.answer[key]) {
if (_debug) alert ("UPDATE '" + key + "' SET CONTENT '" + _cba.answer[key] + "'") ;
document.getElementById( key ).innerHTML = _cba.answer[key];
}
}
}
, _caching );
if (_return_false) return false;
}
02. CONTENIDO-CORE ANPASSEN (PHP)
Datei: cms/front_content.php
Aktionen:
- Backup anlegen!
- Codestelle suchen:
Code: Alles auswählen
/*
* That's it! The code of an article will be evaluated.
* The code of an article is basically a PHP script which is cached in the database.
* Layout and Modules are merged depending on the Container definitions of the Template.
*/
eval ("?>\n".$code."\n<?php\n");
Code: Alles auswählen
/*
* That's it! The code of an article will be evaluated.
* The code of an article is basically a PHP script which is cached in the database.
* Layout and Modules are merged depending on the Container definitions of the Template.
*/
/*
* CBA-Ajax-API
*/
if ($idcnt) {
preg_match_all("=<ajaxcontainer(.*)>(.*)<\/ajaxcontainer>=siU", $code, $code);
$aContent = array();
for ($i=0; $i<count($code[1]); $i++) {
preg_match_all("=(id|target)\=\"(.*)\"=siU", $code[1][$i], $sParam);
$nKey = $sParam[2][0];
$sElement = $sParam[2][1];
$aContent[$nKey]["element"] = $sElement;
ob_start();
eval ("?>\n".$code[2][$i]."\n<?php\n");
$aContent[$nKey]["code"] = ob_get_contents();
ob_end_clean();
}
$sSearch = '='.chr(9).'|'.chr(10).'|'.chr(13).'|'.chr(32).'{2,}=';
$code = "";
if ($idcnt=="auto") {
reset($aContent);
while($aCurrent = current($aContent)) {
$code .= "'".$aCurrent["element"]."':'".addslashes(preg_replace($sSearch, "",
$aCurrent["code"]))."',";
next($aContent);
}
} else {
$aIdcnt = explode(",",$idcnt);
foreach ($aIdcnt as $idcnt) {
if (array_key_exists($idcnt,$aContent)) {
$code .= "'".$aContent[$idcnt]["element"]."':'".addslashes(preg_replace($sSearch, "",
$aContent[$idcnt]["code"]))."',";
}
}
}
$code = substr($code,0,strlen($code)-1);
echo "_cba.ready ( $_cba_request_id, { ".$code." } );";
} else {
$code = preg_replace("=<(/?)ajaxcontainer(.*)>=", "", $code);
eval ("?>\n".$code."\n<?php\n");
}
Die Ajax-Container ähnelm dem neuem Container-Syntax von Contenido. Um im Layout einen Bereich zu definieren, der über die AJAX-Schnittstelle neu generiert und ausgegeben werden können soll, umschließen wir diesen einfach mit:
Code: Alles auswählen
<ajaxcontainer id="1" target="htmlelementid"></ajaxcontainer>
Beispiel:
Code: Alles auswählen
<div id="main_content">
<ajaxcontainer id="1" target="main_content">
<container id="1" name="HeadUndText" types="MainContent" default="HeadUndText" mode="fixed">Head und Text</container>
<container id="2" name="Bilder" types="AddContent" default="MainContent" mode="fixed">Bilder</container>
<container id="3" name="Artikelliste" types="AddContent" mode="fixed">Artikelliste</container>
</ajaxcontainer>
</div>
Beim Aktuallisiern der Seite bzw. beim Aufruf eines neue Artikels über die Ajax-Schnittstelle, würde nun der Output alle drei Module neu generiert und sofern sich dieser verändert hat, in "main_content" ausgegeben werden. So lassen sich beliebig viele Bereiche definieren und über die AJAX aktuallisieren. Überschneiden sollten sich diese aber nicht.
04. VERLINKUNG / AJAX-CONTAINER ANSPRECHEN (HTML, Javascript & PHP)
Um die zovor definierten Ajax-Container zu aktualliesern kann man nun wie folgt vorgehen:
Option A:
Code: Alles auswählen
<a href="javascript:cbaUpdateContent('front_content.php?idcat=1&idart=1&idcnt=auto')">Link</a>
Code: Alles auswählen
<a href="javascript:cbaUpdateContent('front_content.php?idcat=1&idart=1&idcnt=2')">Link</a>
Code: Alles auswählen
<a href="javascript:cbaUpdateContent('front_content.php?idcat=1&idart=1&idcnt=1,3')">Link</a>
Der Artikel dessen Content geladen werden soll wird wie gewohnt über "idcat" und/oder "idart" definiert. Die weitere Variable "idcnt" wird entweder mit "auto" übergeben, so werden alle im Layout vorhandenen Ajaxcontainer ausgegeben oder ein oder mehrere mit Kommata getrennte IDs der AjaxContainer explizit angegeben. Alle anderen AjaxContainer werden dann bei der Aktuallisierung ignoriert. Für die "auto"-Funktion habe ich schon angedacht, die AjaxContainer im Layout mit weiteren Parametern wie "automode" zu versehen. Darüber ließe sich dann z.B. das Aktuallisierungverhalten kontrollieren, ob ein Container immer neugeladen wird, nur wenn sich der Inhalt verändert hat oder ob er z.B. ignoriert werden soll, wenn idcnt=auto ist und nur über den exklusiven Aufruf (Opt. B & C) aktuallisiert werden kann. Für mich hatte sich da jetzt noch kein konkreter Bedarf ergeben, allerdings wäre dies z.B. für den Einsatz verschiedener Layouts sinnvoll um z.B. den kompletten Body-Bereich zu aktuallisieren... aber darauf komm ich noch mal in ein paar Tagen zurück.
Um mir die Linkgenerierung etwas zu vereinfachen, habe ich mir noch eine kleine PHP-Funktion geschrieben und global verfügbar gemacht die zum Einen alle damit generierten Links im Backendeditor "backendkompatibel" mach und wie ich mir erhoffe, nebenbei noch Suchmaschinen ermöglicht, die Seiten vernünftig zu indexieren.
Code: Alles auswählen
function AjaxLink ($idcat, $idart=false, $idcnt="auto", $bCaching="true", $bScriptOnly=false) {
global $contenido, $sess, $client, $lang;
if ($contenido) {
if ($idart==false) {
$aArticleListOptions = array("idcat" => $mydb->f("idcat"), "lang" => $lang, "client"=> $client, "start" => true,
"order" => "published", "direction" => "desc");
$oArticleList = new ArticleCollection($aArticleListOptions);
$oArticle = $oArticleList->startArticle();
return
$sess->url("index.php?changeview=edit&action=con_editart&idartlang=".$oArticle->getField("idartlang")."&type=&typenr=&idart=".$oArticle->getFi
eld("idart")."&idcat=".$idcat."&idcatart=&lang=".$lang);
} else {
$oArticle = new Article ($idart, $client, $lang);
return
$sess->url("index.php?changeview=edit&action=con_editart&idartlang=".$oArticle->_getIdArtLang($idart,$lang)."&type=&typenr=&idart=".$idart."&i
dcat=".$idcat."&idcatart=&lang=".$lang);
}
} else {
if ($bScriptOnly) {
return
"javascript:cbaUpdateContent('front_content.php?idcat=".$idcat."&idart=".$idart."&idcnt=".$idcnt."',".$bCaching.",false)";
} else {
return ( ($idart==false) ? "front_content.php?idcat=".$idcat : "front_content.php?idcat=".$idcat."&idart=".$idart ) .
"\" onclick=\"return false;\"
onmouseup=\"cbaUpdateContent('front_content.php?idcat=".$idcat."&idart=".$idart."&idcnt=".$idcnt."',".$bCaching.")";
}
}
}
Code: Alles auswählen
echo '<a href="'.AjaxLink(1).'">Link</a>';
// Link zur Kategorie (idcat=1), automatische AjaxContainer-Aktuallisierung
echo '<a href="'.AjaxLink(1,7).'">Link</a>';
// Link zum Artikel (idart=7) in Kategorie (idcat=1), automatische AjaxContainer-Aktuallisierung
echo '<a href="'.AjaxLink(1,4,"1").'">Link</a>';
// Link zum Artikel (idart=4) in Kategorie (idcat=1), nur der AjaxContainer mit der ID=1 wird aktuallisiert
echo '<a href="'.AjaxLink(1,2,"1,3").'">Link</a>';
// Link zum Artikel (idart=2) in Kategorie (idcat=1), nur die AjaxContainer mit der ID=1 und ID=3 werden aktuallisiert
echo '<a href="'.AjaxLink(1,6,"auto","false").'">Link</a>';
// Link zum Artikel (idart=6) in Kategorie (idcat=1), automatische AjaxContainer-Aktuallisierung, kein caching
echo '<a href="'.AjaxLink(1,6,"auto","true",true).'">Link</a>';
// Link zum Artikel (idart=6) in Kategorie (idcat=1), automatische AjaxContainer-Aktuallisierung, caching aktiv, Linkausgabe für die Verwendung in SWF-Dateien (getURL())
Code: Alles auswählen
<a href="front_content.php?idcat=1&idart=7" onclick="return false;" onmouseup="cbaUpdateContent('front_content.php?idcat=1&idart=7&idcnt=auto',false)">Link</a>
Da ich für die zusätzliche Suchmaschinen optimieung die ReWriteEngine nutze, sehen die letzten Zeilen der Funktion zur Linkerstellung bei mir noch etwas anders aus. Die Ausgabe der Links ist also auch in einer ReWriteEngine-Form möglich (Vergelich: "front_content.php?idcat=".$idcat : "front_content.php?idcat=".$idcat."&idart=".$idart" und "index_".$idcat.".html" : "index_".$idcat."_".$idart.".html").
Hoffe Ihr kommt mit der Beschreibung klar, bin heute leider erstmal noch unterwegs Geld verdienen... bis später dann und viel Spaß und Erfolg mit der Anpassung. Über positive Implementations-Berichte freue ich mich sehr, aber auch negativen werde ich mich natürlich widmen

Beste Grüße,
Schwarzesocke
Zuletzt geändert von Schwarzesocke am Di 7. Apr 2009, 13:57, insgesamt 1-mal geändert.
-
- Beiträge: 39
- Registriert: Fr 17. Dez 2004, 14:53
- Wohnort: NRW
- Kontaktdaten:
das ist leider richtig. allerdings: was gibt es für eine alternative?i-fekt hat geschrieben:Ich warne hier aber mal vor, bei einem Update wird u.a. die "front_content.php" überschrieben und die Änderungen müssen nochmal gemacht werden.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)