Contao Web-CMS
- Abkürzungen/Begriffe/Konventionen
- Extensions
- Nicht updatesichere Anpassungen
- Templates
- Benutzerrechte
- CSS Klassen
- Sammlung interessanter Links
Abkürzungen/Begriffe/Konventionen
BE = Backend
FE = Frontend
DB = Datenbank
MM = MetaModels
MM (ehemals Catalog) ist ein starkes Werkzeug um beliebige Datensätze in die DB von Conato zu integrieren und wieder aus zu geben. Im Contao-Forum findet man einen gesonderten Diskussionsbereich für Fragen/Hilfestellungen rund um MM.
- Contao Wiki: MetaModels Tutorial zum Einstieg
- Diskussionsbereich im Forum: MetaModels
ER = Extension Repository (Erweiterungskatalog)
Mit diesem BE-Modul (genauer BE-core-Modul - es ist in der Standardinstallation enthalten) lassen sich Erweiterungen bequem herunterladen, automatisch installieren und aktualisieren. In unserem Fall wird dieses aber durch den Composer (Paketverwaltung) ersetzt. Mit der Paketverwaltung ist es möglich auch nur einzelne Dateien von Erweiterungen zu aktualisieren. Das ist nötig um MM zu nutzen, da es bislang keine stabile Version von MM gibt die man im ER vorfinden würde und permanent Aktualisierungen in Teilbereichen von MM stattfinden. Inzwischen stellen aber die Entwickler ihre Erweiterungen ehe fast alle auch in der Paketverwaltung zur Verfügung, weswegen kein Nachteil entsteht diese zu nutzen - denke sogar die Paketverwaltung wird das ER irgendwann ablösen. Sie lässt sich schon jetzt optional direkt bei der Contao Installation mit installieren.
PV = Paketverwaltung
DCA = Data Container Arrays
Die DCA beinhaltet alle Felder (einer Eingabemaske) samt ihrer Feldwerte und Eigenschaften (Formatierung, SQL Datentyp usw.) sowie auch Tabellenwerte welche in Beziehung damit stehen. Die Arrays regeln damit die Datenausgabe, Manipulation vor/nach dem Speichern von Feld-/Tabellenwerten und das Speichern selbst. Neben den Feldwerten regeln die DCA auch Konfigurationen (z.B. Bearbeitungsrechte) und Beziehungen zwischen Tabellen.
Werden über die DCA z.B. Felder zu einer Eingabemaske durch ein Modul hinzugefügt (siehe dazu Allgemeiner Aufbau von Modulen→ Links am Ende) sind diese direkt sichtbar und ausfüllbar. Vorher wird aber ein DB-Update im installtool benötigt. Dort muss bestätigt werden dass die Spalten welche für die zusätzlichen Felder nötig sind angelegt werden dürfen.
Möchte man demnach Module einsetzen um die DCA zu manipulieren ist es wichtig zu wissen, dass zuerst das Backend Modul, dann das Frontend Modul und erst dann die Module aus [...]/system/modules in alphabetischer Reihenfolge geladen werden. Es lässt sich also auch eine Manipulation einer Manipulation vornehmen, solange das Modul alphabetisch nachstehend ist.
Für updatesichere globale Änderungen an den DCA steht auch die Datei system/config/dcaconfig.php zur Verfügung
Extensions
Wir haben bestehende Module modifiziert, aber auch eigene entwickelt. Generell findet man alle Module in [...]/system/modules. Wenn wir von Modulen sprechen sind folgend solche aus dem [...]/system/modules Ordner gemeint. D.h. wir meinen damit alle installierten Extensions wie auch von Contao mitgebrachte Module. Ein Modul wie Artikel oder Nachrichten wird als BE-Modul oder konkreter als Artikel/Nachrichten Modul bezeichnet.
Die Modifizierung eines Moduls ist wie ihr Original benannt, mit dem angehängten Suffix _cfaed (z.B. calendar_cfaed). Solche Module sind vom Aufbau her immer zweiteilig. Sie bestehen (1) aus dem original Modul (z.B. calendar) welches auch im Backend aufgerufen wird und (2) der Modifizierung (z.B. calendar_cfaed) welche nach dem Aufruf vom Original an diesem Veränderungen vornimmt (z.B. zusätzliche Eingabefelder hinzufügen). Aus diesem Grund muss das modifizierende Modul unbedingt alphabetisch nach dem Original kommen.
Eigene entwickelte Module werden häufig über Hooks eingebunden. Hooks sind im Prinzip von Contao bereitgestellte Events mit denen sich eigene Scripte auslösen lassen (z.B. wird das Modul removeRecipient durch einen gleichnamigen Hook ausgelöst, welcher aufgerufen wird wenn sich ein Abonnent aus einem Newsletterverteiler austrägt - mehr dazu unten). Häufig wird auch die ganze Systematik an Systemevents Scripte an zu hängen als Hook bezeichnet. So werden auch Callbacks, Cron Jobs usw. häufig als Hook bezeichnet und können in vielen Fällen sehr analog behandelt werden.
Allgemeiner Aufbau von Modulen
Module bestehen im Grundgerüst im Wesentlichem aus zwei Bausteinen.
Zum einen aus der config.php ([...]/system/modules/MeinModul/config/config.php): Hier werden einerseits die Klasse (MeineKlasse) und Funktion (MeineFuktion) benannt welche ein beliebiges Script enthalten, andererseits regelt man hier auch den Aufruf dieser. d.h. man legt praktisch das Event fest welches die Ausführung auslöst, bzw. legt fest wo (z.B. als Backend Erweiterung) das Modul eingebunden ist. Der zweite Teil ist eine PHP Datei mit dem Klassennamen MeineKlasse.php ([...]/system/modules/MeinModul/MeineKlasse.php) welche MeineFuktion enthält.
Im Großen und Ganzen ist der Syntax bei einfachen Modulen (wie unsere selbst entwichelten Module) gut überschaubar. Es ist empfehlenswert sich beim entwickeln/anpassen von Modulen Anregungen bei den bestehenden zu holen.
Ein Wichtiger Hinweis den man gern vergisst: Nach dem Upload eines neuen Moduls in [...]/system/modules nicht vergessen den Autoload-Creator für dieses im BE auszuführen. Normalerweise ist das nur bei selbst entwickelten Modulen nötig. Bei Modulen welche aus dem ER oder der PV installiert wurden entfällt dieser Schritt. Allerdings behebt auch hier in seltenen Situationen das erstellen neuer autoload-Dateien manchmal einen Fehler.
Kleine Kniffe:
→ Zum debuggen kann es manchmal auch helfen ein Modul zu deaktivieren. Dazu legt man eine leere Datei im Modulordner an und benennt sie mit .skip, um das Modul beim Laden zu überspringen. Das ist eigentlich nur nötig wenn wegen einem defekten Modul das BE nicht mehr erreichbar ist, da sich im BE unter System → Einstellungen → Inaktive Erweiterungen die Module komfortabler deaktivieren lassen.
→ Hat man im root Ordner eines Moduls eine Datei mit dem Namen runonce.php wird diese einmalig ausgeführt und anschließend gelöscht. Das kann nützlich sein wenn man beim portieren einer Erweiterung immer die gleichen Anpassungen (z.B. Tabellen mit default Werten füllen o.ä.) ausführen muss. Es ist praktisch eine Art Installationsroutine.
Seiten die mir zum Verständnis geholfen haben:
- Contao Wiki: Vorhandene Module erweitern
- Contao Wiki: Tutorial Extension Entwicklung
- Contao Kochbuch: Adding custom fields
- Contao Kochbuch: Hooks in Contao
Datenbankzugriffe
Manchmal möchte man vielleicht zusätzliche Daten aus der DB in einem Modul oder Template verfügbar machen, oder sogar Daten in die DB schreiben. Damit können nützliche Verknüpfungen zwischen Tabellen hergestellt werden. Generell sollte man natürlich gut acht auf die Datentypen geben und dass entsprechend Valide Einträge in die DB geschrieben werden, sowie auch Sicherheitsaspekte im Hinterkopf haben.
Allerdings macht es einen Unterschied ob man die DB in einem Modul oder einem Template einbinden möchte.
Datenbankzugriffe in Modulen
In Modulen ist es leicht. Mit
PHP:
$this->import('Database');
ist das DB-Objekt direkt Verfügbar. Alles weitere findet Man im Contao Wiki.
- Contao Wiki: Datenbank Klasse verwenden
Mit import() können aber auch schon vorgefertigte Instanzen importiert werden, wie z.B. die Benutzer mit
PHP:
$this->import('BackendUser', 'User');
wie es auch in Benutzerrechte → article_notEditable verwendet wurde.
Datenbankzugriffe in Templates
Hier muss eine neue Instanz erstellt werden, da $this schon als Instanz mit den übergeben Werden vom Modul belegt ist. In Templates verwendet man daher
PHP:
$db_data = Database::getInstance()->query("SELECT ...");
um ein Objekt mit den DB-Inhalten zu erhalten. Die weitere Behandlung ist jedoch analog dem import() wie es in Modulen verwendet wird. Man kann z.B. Tabellenwerte aus einer Spalte in ein Array schreiben:
PHP:
while($db_data->next()){
$db_data_array[] = $db_data->spaltenname;
}
Hier ist die Informationslage (zuweilen) etwas dünn und man muss im konkreten Fall eine Suchmaschine oder das Forum bemühen falls man mehr als das realisieren möchte.
publications_cron
Was das Modul macht: Beim Eintragen von Publikationen (siehe im BE Publications) gibt es die Möglichkeit den Status als Eigenschaft der Publikation zu setzen. Wählt man hier Accepted for publication ergeben sich weitere Eingabefelder für die Angabe eine Datums und eine Emailadresse. Werden diese korrekt ausgefüllt erhält der/die Empfänger/in zum angegebenen Datum eine automatisch generierte Email um einmalig an eine mögliche Statusänderung zu erinnern. Wird das Feld frei gelassen erfolgt keine Benachrichtigung.
Grober Aufbau: Das Modul publications_cron hat die Aufgabe täglich zu prüfen ob Emailbenachrichtigungen anstehen und diese zu versenden. Danach wird der Datumseintrag welcher vom Eingabefeld übernommen wurde in der DB gelöscht, um beim nächsten Durchlauf nicht erneut eine Erinnerung zu versenden. Natürlich kann danach (und zu jeder anderen Zeit) der Datumseintrag erneut gesetzt oder geändert werden um eine Erinnerung an einem anderen Datum auszulösen.
Es ist ist über einen Hook an den daily cron job von Contao gekoppelt und wird ein Mal täglich ausgeführt.
Detaillierter Aufbau: Das Script in der Datei [...]/system/modules/publications_cron/PubCron.php ist weitestgehend ausführlich kommentiert. Wir wollen kurz nur bestimmte Zeilen der Datei durchgehen:
PHP:
//Datenbank Objekt laden
$this→import('Database');
Damit wird das DB Objekt in der Funktion verfügbar gemacht. Näheres zum Umgang mit der DB in Modulen/Templates unter
Allgemeiner Aufbau von Modulen → Datenbankzugriffe.
PHP:
//Eintrag in Contao log
$this→log('Running daily cron job for publication email status notification', 'CronJobs run()', TL_CRON);
Mit dieser Zeile wird ein String (hier 'Running daily...') als Log-Eintrag in den Systemlog von Contao getätigt. Zum Umgang mit cron Jobs und System Logs hier ein paar Links:
- Contao Kochbuch: Cron Jobs
- Contao Forum: Cron Jobs
- Contao Wiki: System Log
- Als Hinweis → GitHub: [Contao 3] Cron messages in the system log #4729
calendar_cfaed
Was das Modul macht: Das Modul automatisiert die Weitergabe von Kalendereinträgen (Events welche über das BE eingetragen werden) an externe online-Veranstaltungskalender:
- Desden Science Calendar = dsc
- Hightech Startbahn (Kalender) = hts
- TU Veranstaltungskalender = tuvak
Dazu wurden teils vohandene Schnittstellen genutzt, aber auch eigene entworfen. Folgend wird {Kalender} als Abkürzung für alle drei online Kalender verwendet.
Grober Aufbau: Das Modul hat zwei große Teile. Zum einen ergänzt es das bestehende Modul calendar um weitere Eingabefelder, welche nötig geworden sind um den unterschiedlichen Anforderungen der online-Kalender gerecht zu werden. Zum anderen verwaltet es die Schnittstellen welche die automatisierte Übertragung möglich machen. Wie genau die Schnittstellen aufgebaut sind wird unten gesondert beschrieben.
Hinweise:
- Das Modul beinhaltet eine nicht Update sichere Anpassung. Siehe dazu: Nicht updatesichere Anpassungen → tl_calendar_events: addTime
Detaillierter Aufbau: Wir machen uns zuerst klar wo/wie die zusätzlichen Eingabefelder eingebaut werden (siehe dazu auch Allgemeiner Aufbau von Modulen → die Links am Ende). Die Werte der neuen Felder stehen dann auch in Templates zur Verfügung - den Sytax durchschaut man schnell. Ansonsten verschafft die Methode $this->showTemplateVars(); einen Überblick der verfügbare Variablen in einem Template. Weiterhin müssen wir noch zwei PHP Klassen kennenlernen welche zum handling der Übertragung verwendet werden. Zum Schluss wird auf die einzelnen Schnittstellen konkret eingegangen.
Die Datei [...]/system/modules/calendar_cfaed/dca/tl_calendar_events.php ist ein Eingriff in das DCA und fügt zusätzliche Felder in die Eingabemaske bei der Eingabe von Events ein, und regelt den Aufruf zusätzlicher Scripte beim Speichern und Löschen eines Events durch Callbacks (auf den oberen tuvak-Teil im Script wird später bei der Beschreibung der tuvak Schnittstelle eingegangen). Die Callbacks rufen dabei immer drei Scripte auf:
⇒ Snoopy PHP Klasse: [...]/system/modules/calendar_cfaed/script/Snoopy.class.php ist eine PHP Klasse um Formulareingaben und dessen Absenden mit PHP möglich zu machen. Dabei ist sogar das Annehmen, Zurückgeben und Manipulieren von Cookys möglich sowie das manuelle festlegen eines Web-Client.
- SourceForge: Snoopy PHP Klasse
Die Dokumentation befindet sich mit im *.zip.
⇒ simple_html_dom PHP Klasse: [...]/system/modules/calendar_cfaed/script/simple_html_dom.php ist eine PHP Klasse um html/XML zu parsen, manipulieren und zu erstellen. Der Input kann eine URL, String oder lokale Datei liefern.
- SourceForge: simple_html_dom PHP Klasse
- Dokumentations Webseite
Beide Klassen sind im Vergleich zur simplen Handhabung unheimlich leistungsfähig und werden im letzten nachfolgend aufgerufenen Script benötigt.
Zuletzt wird also im Speichern/Löschen-Callback ein Initialscript geladen das weitere Aktionen auslöst. Mit dem onsubmit_callback wird [...]/system/modules/calendar_cfaed/script/calendar_add.php geladen, und mit dem ondelete_callback [...]/system/modules/calendar_cfaed/script/calendar_del.php.
calendar_add.php übernimmt zuerst die Feldwerte des Formulars und schreibt diese in einzelne Arrays welche dann genau ein Element (den Feldwert) enthalten. Das ist etwas unpraktisch und ein Überbleibsel aus einer anfangs anders überlegten Struktur. Folgend werden die Arrayss also wie Variablen behandelt indem immer auf das erste Element ($array[0]) zugegriffen wird (mit wenigen Ausnahmen wo der Feldwert in $array[0][0] steht - das sieht man dann aber schon). Im weiteren fungiert dieses Script ebenfalls als Initialscript und ruft nacheinander die XML-Dateien der Schnittstellen (mit file_get_html("file"), was schon eine Methode aus der simple_html_dom PHP Klasse ist) und die Schnittstellen selbst zu den einzelnen externen online Kalendern auf, in denen nun die Feldwerte verfügbar sind. Die XML Dateien gehören zu den Schnittstellen die folgend erläutert werden.
Die XML Dateien werden wie kleine Datenbanken verwendet welche von den externen online Kalendern vom cfaed-Server abgerufen werden. Dazu wurde den Betreibern die URL der zugehörigen XML mitgeteilt. Die XMLs beinhalten die Feldwerte der einzelnen Events sowie dessen aktuellen Status (online/offline). Bei jedem Durchlauf (wenn irgend ein Event gespeichert wird) wird in allen XMLs geprüft ob noch Events aus der Vergangenheit enthalten sind und diese ggf. entfernt, um nur aktuelle Events vor zu halten. Der Ablauf der Schnittstellen Scripte selbst ist demnach im Groben bei allen ähnlich: Wir befinden uns im Ordner [...]/system/modules/calendar_cfaed/script/ und betrachten die drei calendar_add_{Kalender}.php Dateien. Zuerst wird der Status des Eintags (online/offline) festgelegt indem die Veröffentlichen-Checkboxen der verschiedenen Kalender abgerufen werden, und der Eintrag selbst mit calendar_output_{Kalender}.php in der jeweiligen XML Struktur generiert. Das muss noch vor der Festlegung ob der Eintrag überhaupt veröffentlicht werden soll geschehen, da es sein kann das es den Eintrag schon gibt und sich nur der Status oder Inhalt geändert hat. Dafür hat jeder Eintrag eine eindeutige ID welche nach der Vorgabe der einzelnen Dokumentationen zu den Schnittstellen generiert wird. In diesen Dokumentationen ist auch der vereinbarte XML Aufbau festgehalten. Nur beim tuvak gibt es keine Vorgaben und das XML wird hier nur zur internen Verwaltung genutzt.
⇒ dsc: Der dsc Kalender hat eine sehr gute PDF Dokumentation. Im Prinzip reicht es sich damit auseinander zu setzen und das calendar_add_dsc.php Script nach zu vollziehen um Details zu verstehen.
⇒ hts: Die Dokumentation zu diesem Kalender haben wir selbst entworfen und dem Betreiber übergeben. Es orientiert sich am Aufbau des dsc XMLs. Der wohl größte Unterschied ist jedoch die Statushandhabung. So verbleiben auch Events die in der Zukunft stattfinden welche man aber löschen möchte im XML, und bekommen den Status deleted. Ein Event kann praktisch nicht gelöscht, sondern nur als gelöscht markiert werden und wird erst aus der XML entfernt wenn das Veranstaltungsdatum in der Vergangenheit liegt.
⇒ tuvak: Hier ist alles anders. Eigentlich gibt es gar keine Schnittstelle. Die einzige Möglichkeit Events im tuvak ein zu tragen ist das Ausfüllen des Onlineformulars. Somit ist auch nicht möglich später den Inhalt oder den Status zu ändern (d.h. das ist nur im direkten Kontakt mit dem Betreiber möglich). Deswegen ist das Versenden des Formulars nur für finale Events vorgesehen welche dann auch nicht bei Änderungen wiederholt versendet werden dürfen. Das automatisierte Ausfüllen und Versenden des Formulars wird mit der snoopy PHP Klasse realisiert. Und obwohl die Übertragung über das Onlineformular getätigt wird, wird dafür dennoch eine XML angelegt. Dieses XML hat nur interne Zwecke zu erfüllen und keine Dokumentation, ist im Aufbau aber sehr einfach und durchschaubar. Um nun keine Events mehrfach an den tuvak zu senden wird zu Beginn des Scripts [...]/system/modules/calendar_cfaed/dca/tl_calendar_events.php die XML vom tuvak ausgewertet. Dort ist gespeichert welche Events schon versendet wurden. Ist das der Fall wird die Veröffentlichen-Checkbox für den tuvak bei diesen Events ausgegraut.
Das Löschen von Events wird wie erwähnt beim dsc und hts unterschiedlich gehandhabt. Beim tuvak ist es nur im direkten Kontakt mit dem Betreiber möglich. Generell sind für das Entfernen von Events aus dem XML (egal ob sie vorzeitig manuell gelöscht werden, oder automatisch entfernt werden weil sie in der Vergangenheit liegen) die [...]/system/modules/calendar_cfaed/script/calendar_del_{Kalender}.php Scripte zuständig, welche beim manuellen löschen durch das Initialscript [...]/system/modules/calendar_cfaed/script/calendar_del.php aufgerufen werden. Das entfernen von Events mit einem Veranstaltungsdatum in der Vergangenheit wird bei jedem Speichern/Löschen Vorgang durchgeführt. Das ist ausreichend da solche Events ehe vom Import der externen Kalender ignoriert werden. Um das Entfernen alter Events sauber zu behandeln könnte man es auch in den daily cron job (siehe im Kapitel publications_cron die Links am Ende) von contao aufnehmen, das sollte aber nicht nötig sein.
news_cfaed
Was das Modul macht: Dieses Modul fügt der Eingabemaske der Nachrichten (= News) zusätzliche Eingabefelder hinzu. Diese wurden zur Ausgabe dann auch im Template ergänzt. In diesem Fall ist es sogar nur ein einziges Eingabefeld welches ergänzt wird. Das macht es zu einem guten Beispiel zum verstehen der Herangehensweise.
Detaillierter Aufbau: Wir machen uns lediglich klar wo/wie die zusätzlichen Eingabefelder eingebaut werden (siehe dazu Allgemeiner Aufbau von Modulen → die Links am Ende).
remove Recipient
Was das Modul macht: Diese Erweiterung sendet eine Email (an Matthias) wenn sich ein Abonnent aus (irgend-)einem Newsletter austrägt. Die Email hat nur eine interne informierende Funktion.
Hinweise: Um den Emailversand in einem weiteren Beispiel nach zu vollziehen siehe publications_cron.
Detaillierter Aufbau: Das Modul folgt dem simplen Aufbau wie in Allgemeiner Aufbau von Modulen beschrieben. Um das Modul aus zu lösen wird in /srv/www/htdocs/system/modules/removeRecipient/config/config.php der gleichnamige Hook removeRecipient verwendet. Dieser übergibt in /srv/www/htdocs/system/modules/removeRecipient/RemoveRecipientClass.php auch die Emailadresse vom Abonnenten/der Abonnentin ($strEmail) und die Verteiler ($arrChannels) aus denen sich der/die Abonnent/in ausgetragen hat.
Nicht updatesichere Anpassungen
Es kann immer wieder passieren dass Lösungen umgesetzt werden welche nach einem Update verloren gehen. Dabei kann es sich z.B. um solche Anpassungen handeln, welche nicht in einem Template oder durch andere Module umgesetzt werden können, sondern direkt im System eingebaut werden. Solche Implementierungen gehen bei einem Update verloren.
In der Regel liegt das daran, dass angepasste Dateien beim Updaten von einer aktuelleren Version überschrieben werden. Das sollte aus Sicherheitsgründen auch so gemacht werden, außer man prüft, dass es bis auf die eigenen Änderungen keine weiteren in der Datei gibt. Nach einem Update ist es also nötig die nicht updatesicheren Anpassungen wiederholt ein zu pflegen.
tl_calendar_events: addTime
In der ursprünglichen Variante des Moduls war es optional bei einem Event in einem Kalender zum Veranstaltungsdatum zusätzlich eine Uhrzeit ein zu tragen. Dazu musste eine Checkbox aktiviert werden um die Felder für die Uhrzeit sichtbar zu machen. Für unsere Zwecke soll es aber immer möglich sein eine Uhrzeit an zu geben.
Um dies zu erreichen wurde im calendar Modul in der Datei [...]/system/modules/calendar/dca/tl_calendar_events.php in Zeile 857
PHP: 857 //cfaed: addTime auf 1 setzen - notlösung! 858 $dc→activeRecord→addTime = "1";
eingefügt. Wie im Kommentar erwähnt ist das nur eine Quick&Dirty Lösung. Eine updatesichere Variante könnte sein, im Modul calendar_cfaed in der Datei [...]/system/modules/calendar_cfaed/dca/tl_calendar_events.php das Feld
PHP: $dc→activeRecord→addTime
"irgendwie" dauerhaft auf checked zu setzen. Evtl. damit?
Aufgrund der seltenen Updates war eine saubere Lösung noch nicht überlegenswert.
Templates
Templates regeln das Aussehen und die Ausgabe von Modulen welche in einem Layout untergebracht sind. Ändert man ein Template wird dieses mit dem Original durch den Dateinamen identifiziert. Um ein Template also wirksam zu ändern (d.h. das Original gegen ein anderes aus zu tauschen) muss der Dateiname erhalten bleiben. Einzig angehängte Zeichen an den Originalnamen sind erlaubt. Z.B. wird aus gallery_default.html5 → gallery_default_cfaed.html5 und wird somit in der Auswahl der Templates für das Galerie-Inhaltselement mit angeboten. Wird der Dateiname des Templates nicht geändert ersetzt es ungefragt das gleichnamige Original.
Oft sind Templates als *.html5 und *.xhtml vorhanden. Wir arbeiten grundsätzlich mit den *.html5 Dateien. Ich glaube die *.xhtml sind nur für alte Contao-Versionen relevant.
Publications
Die Templates zur Ausgabe der Einträge sind bei MetaModels in zwei Teile gesplittet. Zum einen das metamodel_prerendered.html5 in welchem die Items aus der DB verfügbar sind, aber noch nicht (direkt) ausgegeben werden - die Items stehen hier also nur zur Weiterverarbeitung/Manipulation zur Verfügung. Zum anderen das ce_metamodel_list.html5 welches in diesem Fall dann die Liste der Items tatsächlich im FE ausgibt. In diesem Template ist hauptsächlich die Pagination und der Modulcontainer enthalten und bekommt die Items aus metamodel_prerendered.html5 übergeben.
Die eingepflegten Strings enthalten u.U. html Entitäten und LaTex Code für die Sonderzeichen.
- html Entitäten: Übersicht
- LaTex Zeichen: Übersicht
- PHP Funktion: html_entity_decode
metamodel_prerendered_bibtex
Zusätzliche Download Links können über das BibTex im comment = {...} übergeben werden (das ist nicht unbedingt üblich, im Bibtex Browser aber so implementiert). Das ist z.B. dann der Fall wenn ein Autor noch Folien oder Vorlesungsdokumente zu einer Publikation beilegen möchte. Die Links der hochgeladenen Dokumente werden hier (wenn vorhanden) über reguläre Ausdrücke in das comment eingefügt. Anschließend wird der BibTex String an die Globale Variable $GLOBALS['mm_bibtex'] angehängt.
Möchte man eine Publikation ohne einen BibTex Eintrag einstellen muss aus den seperaten Feldern wieder ein BibTex erstellt, und Anstelle von $arrItem['text']['bibtex'] an die globale Variable angehangen werden. Das ist noch offen und gegenwärtig nicht umgesetzt.
ce_metamodel_list_bibtex
Bevor durch include_once der Bibtex Browser eingebunden wird müssen für dieser $_GET Parameter gesetzt werden.
PHP: $_GET['all'] = 1;
Damit wird jeder Eintrag ungefiltert ausgegeben.
PHP: $_GET['bib'] = "/srv/www/htdocs/bibtexbrowser/empty.bib";
Der Bibtex Browser erwartet als $_GET Parameter einen Link zu einem BibTex File (*.bib). Die hier übergebene BibTex Datei ist leer. An diese wird dann der String aus der globalen Variable $GLOBALS['mm_bibtex'] angehangen.
Der Bibtex Browser ist ein fertiges PHP Script um Publications im BibTex Format online dar zu stellen (/srv/www/htdocs/bibtexbrowser/bibtexbrowser.php). Außerdem kann der Bibtex Browser nach verschiedenen Parametern (wie Jahr und Autor) sortieren/selektieren und entsprechende Listen erstellen. Eine solche Sortierung/Selektierung kann über entsprechende $_GET Parameter realisiert werden, oder durch z.B. einen Klick auf entsprechenden Link in einer generierten Autorenliste (siehe dazu u.a. die DEMO Seite in der Dokumentation).
In der /srv/www/htdocs/bibtexbrowser/bibtexbrowser.local.php ist festgehalten dass Bibtex Einträge zusätzlich von einer Stringvariable übernommen werden. Diesen Code hat der Entwickler vorgegeben. In der /srv/www/htdocs/bibtexbrowser/bibtexbrowser.after.php werden html Entitäten ersetzt und der String aus der globalen Variable $GLOBALS['mm_bibtex'] übergeben. Um hier die html Entitäten nicht alle einzeln ersetzen zu müssen könnte man die PHP Funktion html_entity_decode erproben, ob diese alle Sonderzeichen umfasst und der enthaltene LaTex Code dann ordentlich vom Bibtex Browser in html umgewandelt wird (siehe auch das metamodel_prerendered_BE_list Template und Links am Ende von Publications).
- Dokumentation: Bibtex Browser
- GitHub: Download/Source Code
metamodel_prerendered_BE_list
Dieses Template regelt die BE-Anzeige und muss ebenfalls noch für den Fall dass eine Publikation ohne einen BibTex Eintrag erstellt wurde angepasst werden. Weiter werden die html Entitäten aus den Strings für die BE Liste automatisch mit der PHP Funktion html_entity_decode in das entsprechende Zeichen umgewandelt, und anschließend der enthaltene LaTex Code mit einem Code-Schnippsel aus der bibtexbrowser.php mit dem entsprechende Sonderzeichen ersetzt (siehe Links am Ende von Publications)
moo_accordion_cfaed
Die Publications werden unter anderem als Akkordeon dargestellt. Da die Implementierung einen gesonderten Style für die BibTex Einträge vor sieht, ist es so gelöst, dass der Akkordeon-Punkt in welchem die Publikationen enthalten sind die CSS-ID publications_section bekommt. Diese ID wird dem Inahltselement Umschlag Anfang vergeben. Das ist wichtig damit das JavaScript vom Akkordeon im Template moo_accordion_cfaed herausfinden kann im wievielten Akkordeon-Punkt (d.h. in welcher section) die Publikationenliste steckt. Wird nämlich ein key oder bibtex_list als $_GET Parameter übergeben soll nicht der erste Akkordeon-Punkt, sondern der mit den Publikationen nach dem Laden der Seite (nach 750 Millisekunden) aufklappen. Das finden (abzählen) des Publikationen Akkordeon-Punkt und Abfragen der $_GET Parameter geschieht im oberen Teil des moo_accordion_cfaed Templates. Welcher Akkordeon-Punkt nun dementsprechend aufgeklappt werden soll wird mit den If-Abfragen im Mittleren Teil geregelt. Siehe ergänzend CSS Klassen → Akkordeon nicht aufklappen.
fe_page
Die Vererbung von CSS-Klassen einer Seite auf Unterseiten ist normaler Weise nicht möglich. Es kann jedoch sehr bequem sein CSS-Klassen auf Unterseiten zu vererben, da man dann bim Hinzufügen weiterer Unterseiten nicht jedes mal für diese die CSS-Klasse eintragen muss. Um es dennoch möglich zu machen wurde das Template entsprechend ergänzt. Es wird im unseren Fall dazu genutzt um CSS-Anweisungen für das zweite Menü im Content (z.B. im FE unter People & Institutions → irgendein Chair) durch zu reichen. (siehe auch CSS Klassen → Kein zweites Menü im Inhaltsbereich)
mod_article
Die hauptsächlichen Änderungen beziehen sich auf die zusätzlichen Sharebuttons. Außerdem wurde noch der Artikel als PDF Button (sicherheitshalber) ganz aus dem Template entfernt, da dies bisweilen wegen zusätzlich benötigter PHP Module ehe nicht funktioniert und auch nirgends auftauchen soll.
Sharebuttons
Contao bringt die Möglichkeit mit in den BE Einstellungen eines Artikel verschiedene Sharebutton zu aktivieren. Das sind Facebook, Twitter und Google+. Darüber hinaus sind weitere Sharebutton im mod_article Template eingebunden. Durch die direkte Einbindung über das Template sind diese dann dauerhaft sichtbar und können nicht im BE deaktiviert werden. Das spielte bisher keine Rolle, da grundsätzlich alles auf der Seite mit allen Portalen zum Teilen angeboten werden soll, und auch die Haken für die übrigen Portale in der Regel immer gesetzt werden.
LinkedIn ist einfach in Anlehnung der Code-Schnippsel für standardmäßig unterstützte Portale im mod_article Template eingebunden.
Für den Xing Sharebutton wird ein JavaScript benötigt. Dieses wurde im BE unter Themes → Layout → Eigener JavaScript-Code hinzugefügt. Dieses spricht die zugehörige div-Box im mod_article an und bindet einen iFrame ein. Die ursprüngliche Größe vom iFrame (und Button) ist 20 x 20 Pixel und wurde per CSS mit transform: scale(0.8); auf die Abmessung der übrigen Button mit 16 x 16 Pixel skaliert.
- Custom Button: Code Generator
Für den WhatsApp Sharebutton wird ein JavaScript benötigt. Dieses wurde im BE unter Themes → Layout → Eigener JavaScript-Code hinzugefügt und spricht dem Link im mod_article template an. Im Unterschied zum Xing Button wird hier kein JavaScript von einer externen Seite nachgeladen, sondern ein in [...]/files/themes/cfaed/whatsapp-sharing/dist/whatsapp-button.js lokal hinterlegtes JavaScript genutzt. Dieses kann heruntergeladen werden und hat hauptsächlich die Funktion zu identifizieren ob es sich um ein WhatsApp-fähiges Mobilgerät handelt, und blendet dementsprechend den Button ein/aus. Hier muss evtl. in regelmäßigen Abständen eine aktuelle Version hochgeladen werden, um sicher zu gehen dass auch neuere Geräte unterstützt werden.
- Custom Button: WhatsApp Sharing Button Generator
- GitHub: whatsapp-sharing javascript
Benutzerrechte
Wir haben bei der Vergabe von rechten an User schon vorgefertigte Benutzergruppen (quasi rechtegruppen) welche die meisten Fälle abdecken. Das einzige was für jeden User angepasst werden musss sind die Pagemounts und Filemounts. D.h. bei den Zugriffen auf Ordner und Seiten wird jeder User individuell behandelt. Bei der Wahl eines Ordners/einer Seite sind auch immer die Unterordner/Unterseiten enthalten.
Wenn nicht anders beschrieben gilt, dass zusätzlich zu Gruppenrechten keine weiteren Freigaben nötig sind. D.h. z.B. bei der vergabe vom Gruppenrecht article ist es nicht nötig bei den Userechten nochmal Artikel als BE-Modul zu setzen.
Benutzergruppen
⇒ user: Damit der Benutzer überhaupt etwas darf muss er erstmal die Gruppe user bekommen. Diese ist in den Rechten für den Webseitenbaum ab dem Startpunkt der (englischen) Webseite gültig.
⇒ article: Damit kann der Benutzer die Artikel auf Seiten welche durch die Pagemounts freigegeben sind bearbeiten. Nicht jedoch dessen Inhaltselemente.
⇒ article_notEditable: Häufig reicht es aus, dass ein Benutzer nur die Inhaltselemente von Artikeln (content) bearbeiten sollte, nicht aber die Artikel selbst anlegen/löschen/ändern. Das ist i.d.R. dann der Fall, wenn der Benutzer ehe keine Seitenstruktur bearbeiten darf. Um z.B. zu vermeiden dass ein ganzer Artikel (mit enthaltenen Inhaltselementen) gelöscht, oder ein neuer Artikel an einer falschen Position erstellt wird (z.B. in der rechten Event Spalte), kann diese Benutzergruppe vergeben werden. ⇒ content: Erst mit dieser Benutzergruppe sind auch die Inhaltselemente in Artikeln bearbeitbar.
⇒ dateiverwaltung: Der Benutzer kann in den Filemounts freigegebenen Ordnern Dateien hochladen und sehen.
⇒ events: Das Events-Modul wird im BE angezeigt. Allerdings müssen noch in den erweiterten Gruppenrechten des Benutzers die entsprechenden Kalender gewählt werden. Standardmäßig sind keine gesetzt.
⇒ nachrichten (news): Das Nachrichten-Modul wird im BE angezeigt. Allerdings müssen noch in den erweiterten Gruppenrechten des Benutzers die entsprechenden Archive gewählt werden. Standardmäßig sind keine gesetzt.
⇒ newsletter: Das Newsletter-Modul wird im BE angezeigt. Allerdings müssen noch in den erweiterten Gruppenrechten des Benutzers die entsprechenden Verteiler gewählt werden. Standardmäßig sind keine gesetzt.
⇒ seitenstruktur: Der Benutzer kann die Seitenstruktur im BE sehen, und Seiten welche durch die Pagemounts freigegeben sind anlegen/löschen. Dieses Recht benötigen nur sehr ausgewählte Benutzer.
article_notEditable
Diese Benutzergruppe enthält gar keine Rechte (alles ist deaktiviert) und dient nur als Trigger für einen DCA Eintrag welcher in system/config/dcaconfig.php hinterlegt ist. Dort steht
PHP:
$this->import('BackendUser', 'User');
if ($this->User->isMemberOf(23)) {$GLOBALS['TL_DCA']['tl_article']['config']['notEditable']=true;}
In der ersten Zeile muss zuerst das Objekt der BE-Benutzer verfügbar gemacht werden, da diese sonst nicht abgefragt werden können. Anschließend wird für Benutzer welche Mitglied in der Gruppe article_notEditable mit der ID 23 sind ein DCA Eintrag vorgenommen, welcher verhindert dass der Benutzer zugriff auf die Artikel Tabelle tl_article erhält. Damit wird im BE das Bearbeiten Symbol für Artikel ausgeblendet, oder erzeugt einen Fehler.
- Contao Kochbuch: Benutzer-Authentifizierung und Rechteprüfung
- Contao Kochbuch: DCA → Reference
- Contao Forum: Artikel Rechte anpassen
- Contao Forum: Zugriff auf Artikeleinstellungen sperren
CSS Klassen
Es wurden ein paar CSS Klassen in Contao angelegt die sehr allgemein zu handhaben sind. Sie sollen hier kurz zusammengefasst werden um doppelten Mühen vor zu beugen. Weiter sind aber auch Formatierungen erwähnenswert welche tatsächlich unbedingt benötigt werden damit z.B. ein Modul richtig funktioniert.
Kein zweites Menü im Inhaltsbereich
Eine vierte Menüebene wird im Hauptmenü nicht mehr angezeigt. Dafür wird ein zweites Menü im oberen Inhaltsbereich eingeblendet (siehe im BE unter Themes → Layout → Eingebundene Module).
Ist das Einblenden dieses Menüs auf einer Seite unerwünscht vergibt man dieser Seite die CSS Klasse:
CSS: hide_submenu_content_2nd_level
Akkordeon nicht aufklappen
Üblicher Weise klappt nach dem Laden einer Seite mit einem Akkordeon als Inhaltselement der erste Akkordeon-Punkt nach 750 Millisekunden automatisch auf. Ist das nicht gewünscht gibt man dem Artikel die CSS-Klasse
CSS: no_expand_first_element
mit. Das löst nicht Fälle wie es sich verhalten soll, wenn auf einer Seite meherer Akkodeons sind und nur ein bestimmtes davon nicht Aufklappen soll. Siehe ergänzend Templates → Publications → moo_accordion_cfaed.
Sammlung interessanter Links
- Contao Community Alliance: Security-Newsletter
- Contao Community Alliance: Sicherheitsupdates
- Contao News: Die Seiten- und Artikel-ID sichtbar im Backend anzeigen
- Contao Kochbuch: Eigene Inserttags entwickeln
