Template Generator

Aus THM-Wiki
Wechseln zu: Navigation, Suche
Kurs
Kursname Modellgetriebene Softwareentwicklung in der Praxis SS 15
Kurstyp Praktikum
Dozent Priefer
Semester SS 15
Studiengang Master
Link http://homepages.thm.de/~dprf53/lehre.html


Diese Seite dokumentiert die Ergebnisse sowie den Fortschritt des Gruppenprojektes.

Projekte der Projektgruppe iCampus:

Inhaltsverzeichnis

Projektorganisation

Projektteam

  • Ferhat Doğru
  • Resul Kavaklı

Projektziele

  1. Template Generator
  2. Plugin Generator

Moodle Kurs

Moodle [1]

Kommunikations-Tools


Entwicklungsumgebung

Eclipse Mars version 4.5.0

Mentor / Unterstützung

  • Dieudonne Timma (aka Joe)

Hiermit möchten wir uns als Team bei Dieudonne bedanken für die motivierende, unterhaltsame und vor allem hilfreiche Unterstützung bei schwierigen Fragen und Problemen während des MDD Praktikums.

Weitere Gruppenprojekte

Projekt-Historie / Hintergrundinformationen

Für Werkzeugentwickler Für Anwendungsentwickler
Projektverlauf der Gruppe "Werkzeugentwicklung" Projektverlauf der Gruppe "Anwendungsentwicklung"
Erklärung der Xtext-Sprachen für eSWAL und eJSL Erklärung der Sprachen eSWAL und eJSL

Git Workflow

Das joomdd_repo Projekt befindet sich auf Gitlab und ist privat. Das Repository joomd_repo muss vorerst geforked und anschließend geklont werden. Anschließend wird ein upstream hinzugegfügt:

git remote add upstream git@git.thm.de:JooMDD/joomdd_repo.git.

Um die Änderungen im Upstream auf die lokale Branch anzuwenden sollte man vorher git pull upstream MDD_SS201 ausführen. Die Branch MDD_SS201 muss wie folgt angelegt werden: git branch MDD_SS201. Alle Arbeiten finden in dieser Branch statt, müssen aber in den master branch rebased werden. Dazu gibt es verschiedene Wege, vorerst sollte der eigene Code aber committed werden. Am einfachsten geht dies wie folgt:

git add . gefolgt von git commit

Anschließend wechseln wir in den master branch und rebasen die Änderungen aus MDD_SS201 mit git checkout master gefolgt von: git rebase MDD_SS2015. Zu guter letzt sollten wir unsere Änderungen zu unserem fork auf Gitlab pushen:

git push --all origin.

In den Upstream senden wir nur Pull-Requests über Gitlab, falls nötig können wir auch direkt dorthin Pushen (bei entsprechender Vergabe von Rechten)

git checkout MDD_SS2015 && git push upstream MDD_SS2015

Modulhandbuch

Im Modulhandbuch für den Kurs mit der Modulnummer SE5012 finden Sie können Sie mehr zum Kurs erfahren.

Kurzbeschreibung

Der Kurs vermittelt und vertieft die Umsetzung von SE-Projekten unter Verwendung modellgetriebener Softwareentwicklung (Model-Driven Development, MDD). In einem praxisnahen Umfeld wird eine eigene Infrastruktur zur modellgetriebenen Entwicklung von Web-Applikationen konzipiert und umgesetzt.

Qualifikations- und Lernziele

Die Studierenden haben vertiefte Kenntnisse im Bereich der modellgetriebenen Softwareentwicklung. Sie sind sicher im Umgang mit Modellen und können selbständig modellgetriebene Software-Projekte im Bereich komplexer Content-Management-Systeme durchführen. Zusätzlich sind die Studierenden in der Lage, agile Methoden in ein solches Projekt einfließen zu lassen.

Lerninhalt

  • Einarbeitung in die modellgetriebene Softwareentwicklung (MDD): MDA, Rollen, Artefakte
  • MDD-Infrastruktur: DSL, Editoren, Generatoren
  • EMF: Ecore, Xtext, Xpand
  • Einführung und Umsetzung eines agilen SE-Prozesses
  • Content-Management-Systeme: Überblick, Joomla!
  • Praxisnahe Umsetzung eines MDD-Projektes

Creditpoints / Arbeitsaufwand

6 CrP; 180 Stunden, davon etwa 60 Stunden Präsenzzeit.

Projekttagebuch

Woche 1: 10.08.2015 bis 14.08.2015 (Einarbeitung)

Wochenrückblick

In dieser Wocher wurde das Projekt eJSL bearbeitet. Die Aufgabe bestand darin ein Template für Joomla! 3.x zu generieren. Dazu konnten anhand der offiziellen Dokumentationen von Joomla einige Informationen zur Template-Erstellung gesammelt werden. Dazu musste der vorhandene Code des Template-Generators genauer angeschaut werden. Es hat sich herausgestellt, dass die Grammatik für die Positionierung des Templates die vorgeschriebene jdoc-statements nicht umsetzt. Daher wurde während der Bearbeitung ein Vorschlag zur neuen Grammatik gemacht. Anhand der definierten Positionen können auch die dazugehörigen CSS-Dateien mit Style-Elementen gefüllt werden. Durch module chromes können Anwendungsentwickler aus der generierten "Modules.php"-Datei einen individuellen Style für die Module definieren (Siehe unten).

Tag 1 (10.08.2015)

Tagesplanung

  • Gitlab Projekt einrichten.
  • Joomla Template Struktur analysiseren.

Tagesziele

  1. Gitlab Projekt klonen und forken.
  2. Front-End Template analysieren.
  3. Back-End Template analysieren.

Tagesergebnisse

Git Konfiguration
Analyse der Templatestruktur

Tag 2 (11.08.2015)

Tagesplanung

  • Generator soll das Basis-Template erzeugen
  • Parameter-Typen dokumentieren
  • Formfeld-Typen dokumentieren
  • Backend-Template analysieren und dokumentieren
  • eJSL Grammatik soll durch Modulverantwortlichen um Params erweitert werden

Tagesziele

  1. Basis-Template erzeugen
  2. Backend-Template erzeugen (Basic)

Tagesergebnisse

Tag 3 (12.08.2015)

Tagesplanung

  • Fehlende Funktionalität im Frontend-Template ergänzen
  • Tagesergebnisse dokumentieren

Tagesziele

  1. Positionsparameter im Frontend-Template umsetzen und dokumentieren
  2. Template Parameter im Frontend umsetzen und dokumentieren

Tagesergebnisse

  • Einarbeitung in Jdoc statements
  • Jdoc-Typattribute "modules" und "components" sind vorhanden. Folgende müssen in der Grammatik ergänzt werden: (siehe Jdoc statements)
    • Head
    • Installation
    • Message
    • Module

Tag 4 (13.08.2015)

Tagesplanung

  • eJSL Instanz vollständig beschreiben
  • Anhand der eJSL-Instanz den Template-Generator vervollständigen
  • CSS-Style und Javascript anpassen

Tagesziele

  1. eJSL Instanz nach einem Beispiel-Template beschreiben
  2. CSS Dateien importieren
  3. Javascript Dateien importieren

Tagesergebnisse

  • eJSL Instanz wurde vollständig beschrieben
  • Stilelemente werden in das Template hinzugefügt

Tag 5 (14.08.2015)

Tagesplanung

  • Favicons für Apple, Microsoft und Google erzeugen
  • Die Funktion für Manifest.json und Bilderzeugung
  • Template-Positions und Jdoc-Statements umsetzen

Tagesziele

  • Den Template-Generator um die Template-Positionen erweitern
    • Dazu erforderlich: Jdoc-Statements und module_chromes

Tagesergebnisse

  • Der Template-Generator wurde um die Positionen erweitert
  • Module_Chromes sind implementiert und die Datei modules.php wird mit den "custom module chromes" beschrieben

Notiz: Die Grammatik könnte für die Positionen und Jdoc-Statements verbessert werden. Todo: Eine Beispiel-Grammatik schreiben!

Woche 2: 17.08.2015 bis 21.08.2015 (Nachbereitung)

Wochenrückblick

Tag 6 (17.08.2015)

Tages-Ergebnisse

  • Die Grammatik zur Template-Positionierung wurde überarbeitet.
    • Jdoc-statements können in der Instanz geschrieben werden.
    • Die Grammatik wurde nicht in das Hauptprojekt aufgenommen. Das Beispiel befindet sich hier

Tag 7 (18.08.2015)

Tag 8 (19.08.2015)

Tagesplanung

  • Joomla Plugin Grundlagen lernen
  • Such-Plugin untersuchen
  • Basis Such-Plugin Generator schreiben
  • FileHandler für Binär/Text fertigstellen

Tagesziele

  • Offizielle Dokumentationen von Joomla durchlesen
  • Vorhandene Plugins (Such-Plugin) untersuchen
  • Grundgerüst eines Plugins generieren
  • Generator soll (Binär/Text) Dateien lesen/schreiben können
  • Methoden ModulePositions/Header/ModChrome erweitern/erzeugen

Tages-Ergebnisse

  • Generator erzeugt nun Dateien aus beliebigen Pfaden aus dem Dateisystem
  • Grundgerüst eines Plugins wird generiert
  • Generator kann beliebige Dateien lesen/schreiben
  • Methode für Modul Positionen entsprechend der Angaben in der Instanz erweitert

Tag 9 (20.08.2015)

Tagesplanung

  • Gemeinsame Plugin Events ermitteln
  • Plan zur Vermeidung eigener Generatorklassen für große Plugins
  • Plugin Generator soll Grundgerüst der Joomla Plugins erzeugen können
  • Dynamische Teile des Themes an Methoden binden
  • Zwei Vorschläge zur Einbindung von CDNs/Links zu CSS/JS Dateien wurden gemacht
    • Die Beispiele befindet sich hier

Tagesziele

  • Offizielle Dokumentation von Joomla zu Events, Plugins und Plugin-Events durchlesen
  • Offizielle Dokumentation zu Xtend Expressions lesen
  • Vorhandene Plugins (Such-Plugin) untersuchen
  • Grundgerüst eines Plugins generieren
  • Generierte PhpDoc an PluginGenerator anpassen
  • Templatisierung der Generierung von Event-Typen
  • Spezielle Methoden soll nur einzigartige PlugIn Events implementieren müssen

Tages-Ergebnisse

  • Generator erzeugt nun Dateien aus beliebigen Pfaden aus dem Dateisystem
  • Methode generateFileDoc erzeugt nun Datum/Manifestionen und plugin spezifische Daten
  • getPluginFactory() kann nun beliebige eventTypen parametrisiert generieren für alle Plugins
  • Methoden der PluginFactory an Methoden Prototypen binden

Tag 10 (21.08.2015)

Tagesplanung

  • Nachlesen welcher Event gebundene code entfernt werden kann
  • Logik der PluginFactory Bindings an jeweilige Methoden überlegen

Tagesziele

  • Unnötigen code aus allen Plugin Methoden entfernen
  • Generischen code für Event bindings für 50% der Plugins schreiben
  • Methode zur Filterung von Keys basierend auf einem Array in einer Verlinkten HashMap zu einer Xtend Expression portieren
  • ModChrome anpassungen vornehmen

Tages-Ergebnisse

Woche 3: 24.08.2015 bis 27.08.2015 (Abschluss)

Wochenrückblick

Offene Punkte, Fehler und fehlende Features wurden zu dieser Zeit abhängig von der Priorität fertig gestellt.

  • Aufarbeitung der Wiki-Seite
  • Dokumentation des
    • Template-Generators
    • Plugin-Generators
    • Abschlusspräsentation
    • Mit PHP CodeSniffer mit den Joomla! Coding Standards überprüfen
    • Wünsche und Anregungen von Roland, dem Joomla! Core-Entwickler einholen

Projektdokumentation

Git Workflow

Das joomdd_repo Projekt befindet sich auf Gitlab und ist privat. Das Repository joomd_repo muss vorerst geforked und anschließend geklont werden. Anschließend wird ein upstream hinzugegfügt: git remote add upstream git@git.thm.de:JooMDD/joomdd_repo.git.

Um die Änderungen im Upstream auf die lokale Branch anzuwenden sollte man vorher git pull upstream MDD_SS201 ausführen. Die Branch MDD_SS201 muss wie folgt angelegt werden: git branch MDD_SS201. Alle Arbeiten finden in dieser Branch statt, müssen aber in den master branch rebased werden. Dazu gibt es verschiedene Wege, vorerste sollte der eigene Code aber committed werden. Am einfachsten geht dies wie folgt: git add . gefolgt von git commit

Anschließend wechseln wir in den master branch und rebasen die Änderungen aus MDD_SS201 mit git checkout master gefolgt von: git rebase MDD_SS2015. Zu guter letzt sollten wir unsere Änderungen zu unserem fork auf Gitlab pushen git push --all origin. In den Upstream senden wir nur Pull-Requests über Gitlab, falls nötig können wir auch direkt dorthin Pushen (bei entsprechender Vergabe von Rechten) git checkout MDD_SS2015 && git push upstream MDD_SS2015

Einleitung

Joomla! Erweiterungen

Übersicht

Erweiterungstyp Beschreibung
Component (seit Joomla 1.0) fügt benutzerdefinierte Funktionen zur Seite, welche aus Menüs ausgewählt werden können
Language (seit Joomla 1.0) definiert eine zusätzliche Sprache für die Seite
Library (seit Joomla 2.5) stellt Funktionen bereit, welche durch andere Erweiterungen genutzt werden kann
Module (seit Joomla 1.0) zeigt nicht-essentielle infos in einem block, möglich auch auf vielen Seiten
Package (seit Joomla 2.5) bündelt verwandte Erweiterungen
Plugin (seit Joomla 1.5) verändert inhalt in einem Artikel oder stellt Funktionen bereit um andere Erweiterungen zu erweitern
Template (since Joomla 1.0) definiert das Aussehen, die Ästhetik, und die Navigationsfähigkeiten der Webseite

Vorwort

Bei den Joomla Erweiterungen unterscheidet man Bibliotheken, Plugins, Komponenten, Module und Templates. Zum Verständnis: Plugins verändern den Programmcode von Joomla! durch Einbindung in vorgegebene oder benutzerdefinierte Ereignisse. Komponenten hingegen ergänzen das CMS um zusätzliche Funktionalitäten, welche jeweils Einstellungen im Backend bieten. Module zeigen Daten aus dem Joomla!-Kern, oder anderen Erweiterungen an. Schließlich bestimmt aber das Template das Aussehen und die Seitenstruktur, sowie die Anordnung der Module auf der Seite.

Bibliothek Erweiterungen

Bietet viele Funktionen und Lösungen für diverse Probleme an, welche innerhalb anderer Erweiterungen genutzt werden können, um viel Programmierarbeit zu ersparen, sowie eine gewisse einheitlichkeit von Lösungsansätzen zu bieten.

Language Erweiterungen

Eine aus konzeptioneller Sicht sehr simple Erweiterung stellt die Language Erweiterung dar. Diese kann den Core, oder eine andere Extension um sprachliche Anpassungen Erweitern. Die Internationalisierung (i18n) ist tatsächlich nur eine Sammlung von Konstanten, welche über gleichnamige Keys die englischen Strings zu anderen Sprachen übersetzen.

Komponenten Erweiterungen

Komponenten können Joomla! um komplexe Funktionen erweitern und bestehen zumeist aus Zwei Teilen:

  • Frontend Seite
  • Backend (Administrations) Seite

Dargestellt werden Komponenten im Homepageinhalt und sind dafür verantwortlich was im Inhaltsbereich von Joomla! angezeigt wird.

Virtuemart zählt zu einer der berühmtesten Komponenten und ergänz Joomla! um die gesamte Funktionalität eines Online-Shops.

Modul Erweiterungen

Am einfachsten stellt man sich Module als Blöcke vor. Diese Blöcke können an beliebigen Positionen im Tempate dargestellt werden. Ein Modul kapselt wiederverwendbare Bausteine einer seite und erlaubt so die Anzeige beliebiger Inhalte.

Module sind an Joomla! Komponenten gebunden und nutzen diese um Inhalte oder Bilder anzuzeigen.

Plugin Erweiterungen

Plugins sind im Grunde Scripte, die im Hintergrund abhängig von Ereignissen im System, in Modulen oder in Komponenten befehle Ausführen. Auf diese Weise kann ein Plugin zur Laufzeit einer Komponente dessen Inhalte manipulieren. Ein Plugin kann diese Manipulation nur ausführen, wenn ein Befehl oder eine Funktionalität an das entsprechende Ereignis gebunden wird.

Beispielsweise kann ein Content-Plugin dazu genutzt werden, um auf bestimmte Inhalte im Editor zu reagieren. So könnte ein findiger Autor ein Content-Editor Plugin schreiben, welches auf Links zu http://youtube.com reagiert indem es automatisch den Link durch ein eingebettetes YouTube Video ersetzt.

Template Erweiterungen

Ein Template ist losgelöst von den Inhalten und der Funktionalität einer Seite, stellt aber den Rahmen und das Design für diese bereit. Module können an belibigen Positionen in der Struktur eines Templates angezeigt werden. Hiermit strukturiert ein Template das Layout und das Aussehen der Inhalte durch etwa sogenannte Modulanpassungen (mod_Chrome).

Datenbank Schema für Erweiterungen

Extensions Tabelle
Feldbezeichnung Datentyp Kommentar
extension_id int(11) Unique extension ID
name varchar(100) Friendly name of the extension
type varchar(20) The extension type
element varchar(100) The unique name of the element
folder varchar(100) The folder of the element
client_id tinyint(3) The client ID of the extension
enabled tinyint(3) The enabled status of the extension
access tinyint(3) unsigned Primitive access control
protected tinyint(3) Uninstallation protection
manifest_cache text Cache of the XML manifest file
params text Parameters for the extensions
data text Unused excess data field
checked_out int(10) unsigned Checked Out (FKEY users.id)
checked_out_time datetime Checked Out Time
ordering int(11) Ordering
state int(11) Extension State (discovered, installed, etc)

Template Generator

Das Template ist in Joomla! eine Erweiterung. Damit kann das Aussehen und das Verhalten der Webseite verändert werden. In Joomla! gibt es zwei Arten von Templates, die sich in Front- und Backend-Template unterteilen. Das Frontend-Template repräsentiert die Webseite (z.B. für einen Besucher) und das Backend-Template wird im Backend des Systems zur Konfiguration verwendet. In Joomla! werden die Templates in einer Verzeichnisstruktur abgelegt. Ein komprimiertes Verzeichnis kann im Backend als Erweiterung installiert werden. Dafür wird die folgende Verzeichnisstruktur eingehalten:

/template_name
— /css
—— template.css
—— general.css
— /html
—— modules.php
— /images
— /javascript
— /language
—— /en-GB
——— en-GB.tpl_template_name.ini
——— en-GB.tpl_template_name.sys.ini
— component.php
— error.php
— favicon.ico
— index.php
— templateDetails.xml
— template_preview.png
— template_thumbnail.png

index.php: stellt die Logik für die Anzeige und die Positionierung von Modulen und Komponenten zur Verfügung.

component.php: bietet die Logik für eine barrierefreie Darstellung (oder z.B. für eine Druckansicht) an.

error.php: enthält Methoden zu Fehlerbehandlung, wie z.B. 404, Seite nicht gefunden.

favicon.ico: favicon Datei

template.css: Gestaltung des Templates (z.B. für Positions...)

general.css: Allgemeine Gestaltung des Templates (fonts, headings, margins, image borders etc..)

templateDetails.xml: beinhaltet Meta-Informationen zum Template. Es ist für den Installer und den Template Manager erforderlich.

/language: Das Verzeichnis enthält Sprachdateien, die die Übersetzung einer statischen Seite erlaubt.


Joomla! Erweiterungen verwenden die API des Frameworks, um auf Basis von Joomla!-CMS und -Framework, um weitere benutzerdefinierte Funktionen erweitert werden zu können. In vielen Erweiterungen mit dem gleichen Typ, wie z.B. ein Template oder ein Plugin, werden sehr oft ähnlicher Code geschrieben. Die immer wiederkehrende Code-Abschnitte können sinnvollerweise durch die modellgetriebene Entwicklung modelliert werden. Für die Modellierung ist eine Grammatik erforderlich, die die Erweiterung beschreibt. Zudem ist ein Generator zu implementieren, die aus der Instanz einen gültigen Joomla! konformen Code erzeugt.

Joomla system diagramm.png

Quelle: Joomla.de - Joomla entdecken!


Während des Projekts wurde ein Template-Generator entwickelt. Die Grammatik für das Template war bereits vorhanden und einige Ansätze konnten im Template Generator beobachtet werden. Als nächstes wird die Ausganssituaton beschrieben:

Ausgangssituation

Der Generator war vorher schon ansatzweise implementiert. Die Funktion zur der benötigten Verzeichnisstruktur und zur Generierung der benötigen Dateien war bereits vorhanden. Die TemplateDetails.xml Datei konnte soweit erstellt werden, dass die Installation über das Backend ohne Probleme funktionierte. Funktionen, die vor dem Projektbeginn vorhanden waren sind:

  • TemplateDetails.xml
    • Der Generator kann über den Instanz eine TemplateDetails.xml Datei beschreiben. Die Installation des Templates funktioniert einwandfrei.
  • CSS
    • Die Funktion, die die CSS-Datei beschreibt ist ansatzweise implementiert.
  • Verzeichnisstruktur
    • Die Verzeichnisstruktur eines Templates wird generiert. Die Funktionen zur Beschreibung der Dateien sind vorhanden.
  • phpComponent Funktion
    • Die Funktion für die component.php-Datei ist exemplarisch implementiert.

Zu den implementierten Funktionen im Generator war die benötigte Grammatik schon vorhanden. Das nachfolgende Diagramm stellt nun die Grammatik für das Template (teilweise) dar:

Before.png

Abbildung 1: Grammatik - vorher.

Grammatik - vorher:

Template returns Template:
	{Template}
	'Template' name=MYID
	'{'
		'Manifestation' '{' (manifest=Manifestation) '}'
		('languages' '{' (languages+=Language)* '}')?
		('parameters' '{' (localparameters+=Parameter)* '}')?
		('positions' '{' (positions+=Position)* '}')?
		('cssblocks' '{' (cssblocks+=CssBlock)* '}')?
	'}'
;


KeyValuePair returns KeyValuePair:
	{KeyValuePair}
	'Key' name=ID '=' value=STRING
;

Position returns Position:
	{Position}
	'Templateposition' (name=POSITION_TYPES | name=ID)
	'{'
		('positionparameters' '{' (positionparameters+=PositionParameter)* '}')?
	'}'
;

terminal POSITION_TYPES:
	'head' | 'contents' | 'footer' | 'left' | 'right'
;

PositionParameter:
	'Position Parameter' name = ID
	'{'
		('divId' '=' divid = ID)?
		('Positiontype' '=' type = POSITION_TYPES_NAMES)?
		('CSS keyvaluepairs' '{' (keyvaluepairs+=KeyValuePair)* '}')?
	'}'
;

terminal POSITION_TYPES_NAMES:
	'modules' | 'component'
;

CssBlock:
	'CssBlock' selector=STRING
	'('
		('keyvaluepairs' '{' (keyvaluepairs+=KeyValuePair)* '}')?
	')'
;

Soll-Zustand

Der Generator ist exemplarisch implementiert. Die Verzeichnisstruktur und TemplateDetails.xml-Datei sind die einzigen Funktionalitäten, die korrekt ausschauen. Nun ist das Ziel den Template-Generator soweit zu erweitern, dass ein Template mit den nötigsten und wiederkehrenden Code generiert wird. Ggf. soll die Grammatik um fehlende Ausdrücke erweitert werden. Dabei soll die Instanz den Anwender die Möglichkeit geben das Template zu individualisieren.

Umsetzung

Bei der Umsetzung wurde ein Joomla!-Template näher betrachtet, um die Funktionsweise eines Templates zu erkennen. Hingegen wurde die Joomla!-Dokumentation für die Template Entwicklung studiert und letztendlich wurden auch einige Beispiele ausprobiert. Daraus entstanden die unten aufgelisteten Punkte, die für die Modellierung sinnvoll erscheinen:

  • Einbindung von Bibliotheken und Dateien im Header.
  • Grundgerüst der Index-Datei -> Positionierung, Div-Container und CSS
  • Jdoc Statements: kennzeichnet die Position anderer Joomla Erweiterungen, die etwas ausgeben können.
  • Modules.php Grundgerüst
  • CSS Dateien beschreiben
  • Languages definieren
  • Favicons und weitere Dateien binär einlesen

Grammatik

Während der Umsetzung konnte festgestellt werden, dass die Grammatik nicht ausreichend für die Entwicklung des gewünschten Generators war. Bei der Modul-Positionierung im Template konnte mit der vorhandenen Grammatik keine Jdoc-Statements festgelegt werden. Darüber hinaus war es nicht möglich beliebige Div-Container anzulegen und sie individuell zu gestalten. Daher wurde die Positionierung in der Template-Grammatik verändert und um weitere Ausdrücke erweitert.

Ein Diagramm nach der Veränderung der Grammatik schaut folgendermaßen aus:

After.png

Abbildung 2: Grammatik - nachher

Grammatik - nachher:

Template returns Template:
	{Template}
	'Template' name=MYID
	'{'
		'Manifestation' '{' (manifest=Manifestation) '}'
		('languages' '{' (languages+=Language)* '}')?
		('parameters' '{' (localparameters+=Parameter)* '}')?
		('positions' '{' (positions+=Position)* '}')?
		('cssblocks' '{' (cssblocks+=CssBlock)* '}')?
		('libraries' '{' (libraries+=KeyValuePair)* '}')?
		('favicons' '{' (favicons+=FAVICON)* '}')?
	'}'
;
FAVICON: 
	keyvalue = KeyValuePair |
	platforms = PLATFORM 
;

PLATFORM: 
	'Platforms' '{'
		(keyvalue += KeyValuePair)*
	'}'
;

Manifestation returns Manifestation:
	{Manifestation}
	'authors' '{' (authors+=Author)+ '}'
	('creationdate' '=' creationdate=DATE)?
	('copyright' '=' copyright=STRING)?
	('license' '=' license=STRING)?
	('link' '=' link=STRING)?
	('version' '=' version=STRING)?
	('description' '=' description=STRING)?
;

KeyValuePair returns KeyValuePair:
	{KeyValuePair}
	'Key' name=ID '=' value=STRING
;

Position returns Position:
	{Position}
	'Templateposition' (name=ModulePositionNames)
	'{'
		('divId' '=' divid = ID)? 
		('PositionParameters' '{' (positionparameters+=PositionParameter)* '}')?
		('CSS keyvaluepairs' '{' (keyvaluepairs+=KeyValuePair)* '}')?
	'}'
;

ModulePositionNames:
	/* Joomla module positions (placeholder in the template) */
	'head'
	| 'contents' 
	| 'footer' 
	| 'left' 
	| 'right' 
	| STRING
;

PositionParameter:
	'PositionParameter' (name = TemplatePositionNames) //HTML5 semantic elements or div classes
	'{'
		('divId' '=' divid = ID) //add div id to the html5 elements or to the div classes
		('PositionParameterTypes' '{' (positionparametertypes += PositionParameterType)* '}')? 
		('CSS keyvaluepairs' '{' (keyvaluepairs+=KeyValuePair)* '}')?
	'}'
;

TemplatePositionNames:
	/* HTML5 semantic elements for Templating */ 
	'nav' | 'footer' | 'header' | 'main' | ID
;

PositionParameterType returns PositionParameterType:
	{PositionParameterType}
	'PositionParameterType' '{'
		('divId' '=' divid = ID)?
		('jdoc' '=' (type = PositionParamsName))?
		('CSS keyvaluepairs' '{' (keyvaluepairs+=KeyValuePair)* '}')?
	'}'
;

PositionParamsName:
	POSITION_PARAMETER_NAME | Modules 
;

/*
 * module chrome for jdoc-statments
 */
POSITION_PARAMETER_NAME returns POSITION_PARAMETER_NAME:
	{POSITION_PARAMETER_NAME} (type='component' | type='message' | type='head' | type='module')
; 

Modules returns Modules:
	{Modules}
	'modules' '{'
	'type' '=' jdoc = 'modules'
	('style module_chrome' '=' style = ModuleChromes)?
	('jdoc_attributes' '{' (keyvaluepairs+=KeyValuePair)* '}')?
	'}'	
;

ModuleChromes returns ModuleChromes:
	{ModuleChromes}
	style = 'xhtml' 
	| style = 'rounded' 
	| style = 'table' 
	| style = 'horz' 
	| style = 'html5' 
	| style = 'outline' 
	| style = STRING 
;

CssBlock:
	'CssBlock' selector=STRING
	'('
		('keyvaluepairs' '{' (keyvaluepairs+=KeyValuePair)* '}')?
	')'
;

Generatorcode

Im Generator ist für jede erstellte Datei eine Funktion definiert, in der die Datei beschrieben werden kann. Es können weitere Funktionen angelegt werden, die z.B. als Hilfsfunktionen dienen oder einen weiteren Zweck erfüllen. Die Modul-Positionierung des Templates geschieht (siehe oben) in der index.php Datei und daher wird in die Funktion …phpIndex(…) der Code geschrieben. Der Generator Code besteht aus einem statischen Teil (HTML, PHP,…) und aus dem dynamischen Teil, der aus dem übergebenen Template Objekt stammt.

Als Beispiel:

  • Zunächst werden die Dateien in dem Verzeichnis generiert
override generate() {
    generateJoomlaDirectory("")
    generateFile("index.php", template.phpIndex)
    generateFile("component.php", template.phpComponent)
    generateFile("offline.php", template.phpOffline)
    generateFile("error.php", template.phpError)
....
}


  • Als nächstes würde die Funktion phpIndex(..) die generierte Datei mit dem Code beschreiben.
def CharSequence phpIndex(Template template) '''
<?php
	«generateFileDoc(template, true)»
?>	
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
	<jdoc:include type="head" />
	«generateLibraries(template, "css")»
	«generateFavicons(template)»
	<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang=""> <![endif]-->
	<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8" lang=""> <![endif]-->
	<!--[if IE 8]>         <html class="no-js lt-ie9" lang=""> <![endif]-->
	<!--[if gt IE 8]><!--> <html class="no-js" lang="<?php echo $this->language; ?>"> <!--<![endif]-->
</head>
<body>
	«generateModulePositions(template)»
	«generateLibraries(template, "js")»
</body>
</html>
'''
  • Der generierte Code sieht dann wie folgt aus:
<?php
/**
* @package     Joomla.Site
* @subpackage  Template.TemplateGen
* @version 0.4
* @name TemplateGenView
* @author Ferhat Dogru, <ferhat.dogru@mni.thm.de>
* @author Resul Kavakli, <resul.kavakli@mni.thm.de>
* @copyright © 2015 THM – MDDP Course
* @license MIT
*/

defined('_JEXEC') or die('Restricted access');

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
	<jdoc:include type="head" />
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"></script>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"></script>
...
	<meta name="msapplication-TileColor" content="#2b5797">
	<meta name="msapplication-TileImage" content="<?php echo $this->baseurl ?>/templates/<?php echo $this->template; ?>/favicons/mstile-144x144.png">
	<meta name="theme-color" content="#ffffff">
	<meta name="mobile-web-app-capable" content="yes">
	<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang=""> <![endif]-->
	<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8" lang=""> <![endif]-->
	<!--[if IE 8]>         <html class="no-js lt-ie9" lang=""> <![endif]-->
	<!--[if gt IE 8]><!--> <html class="no-js" lang="<?php echo $this->language; ?>"> <!--<![endif]-->
</head>
<body>
	<div id="main_menu">  
		<nav id="page_navigation"/>
			<div id="firstlevel">
		              <jdoc:include type="modules" name="head" style="rounded" />
			</div><!-- #firstlevel--> 
			<div id="seconlevel">
		               <jdoc:include type="modules" name="head" style="customModuleChrome" />
			</div><!-- #seconlevel--> 
		</nav>
		<div class="upper_left" id="head_search">
		        <div id="mylogo">
		             <jdoc:include type="modules" name="head" style="navSearch" />
			</div><!-- #mylogo-->
		</div><!-- #upper_left-->
	</div><!-- #main_menu -->
	...
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">
	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>


Falls bei der Positionierung jdoc-Statements von Type “modules” mit benutzerdefiniertem Style angelget worden ist, wird in die modules.php Datei der Grundgerüst für die Spezifizierung geschreiebn. Standardmäßig gibt es einige von Joomla!, die ohne weiteres verwendet werden können. Zu den definierten Positionen können nun CSS-Gestaltungen hinzugefügt werden. Diese erfolgen ebenfalls nach dem gleichen Schma in der Funktion für die zugehörige CSS-Datei, in diesem Fall template.css. Es gibt auch allgemein gültige CSS-Regeln, die in die Datei general.css geschrieben werden. Für alle anderen Dateien des Templates können die definierten Funktionen zur Beschreibung dienen. Wichtig dabei ist, dass die Grammatik dem erzielten Zweck entspricht, da sonst die gewünschte Funktionalität durch Umstände oder gar nicht umgesetzt werden kann.

HTML, Instanz, Grammatik Beispiel

Grammar overview.png

Vorschlag für eine Erweiterung der Grammatik

Es wurde festgestellt, dass die vorhandene Grammatik für die Festlegung von häufig verwendeten CSS- und Javascript Frameworks nicht flexibel genug ist. Daher wird basierend auf einer vorherigen Erweiterung der Grammatik vorgeschlagen, mit hilfe diser in der Instanz eine bessere Möglichkeit für die Parametrisierung von Stylesheets und Javascript im Templates zu bieten. Durch eine Kombination von Instance Aliasing und Typecasting ermöglichen die Erweiterten Funktionen im Interface IFileSystemAccessExtension3 das kopieren und schreiben von Dateien sowohl in binärer als auch Textueller Form. Komponenten aus dem entsprechenden Content Delivery Networks (CDN) können hiermit direkt geladen werden bzw. direkt in die entsprechenden Verzeichnisse im Template eingebunden werden.

Ein Beispiel aus der Instanz sieht folgendermaßen aus:

parameters {
        Parameter jquery {
                type = "Javascript"
                resource = "MaxCDN"
                file = "jquery"
                version = "2.1.4"
                description = "Descripton"
        }
        Parameter bootstrap {
                type = "Stylesheet"
                resource = "Filesystem"
                file = "bootstrap.min.css"
                path = "css/"
                version = "3.3.5"
                description = "Descripton"
        }
}

Alternative Notation

Libraries keyvaluepairs {
    // CDN -> Erzeugt <script> bzw. <rel> tag zur entsprechenden URI
    Key js  = "https://code.jquery.com/jquery-2.1.4.min.js"
    Key css = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"
    Key js  = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"
}

Parameter-Typen Unterstützung

<?xml version="1.0" encoding="utf-8"?>
<extension version="3.4" type="template">
	<name>mynewtemplate</name>
	<creationDate>2015-08-11</creationDate>
	<author>John Doe</author>
	<authorEmail>john@example.com</authorEmail>
	<authorUrl>http://www.example.com</authorUrl>
	<copyright>John Doe 2015</copyright>
	<license>GNU/GPL</license>
	<version>1.0.2</version>
	<description>My New Template</description>
	<files>
		<filename>index.php</filename>
		<filename>templateDetails.xml</filename>
		<folder>images</folder>
		<folder>css</folder>
	</files>
	<positions>
		<position>breadcrumb</position>
		<position>left</position>
		<position>right</position>
		<position>top</position>
		<position>user1</position>
		<position>user2</position>
		<position>user3</position>
		<position>user4</position>
		<position>footer</position>
	</positions>

	<!--  -->
	<forms>

	</forms>

	<params>
	    <param name="templateColour" type="list" default="blue" 
	            label="Template Colour" description="Choose the template colour.">
	        <option value="blue">Blue</option>
	        <option value="red">Red</option>
	        <option value="green">Green</option>
	        <option value="black">Black</option>
	    </param>
	    <param name="authorCopyright" type="radio" default="1" 
	            label="Author Copyright" description="Show/Hide author copyright.">
	        <option value="0">hide</option>
	        <option value="1">show</option>
	    </param>
	</params>

	<param name="mycalendar" type="calendar" default="11-08-2015" label="Select a date" description="" format="%d-%m-%Y" />
	<param name="mycategory" type="category" label="Select a category" description="" section="3" />
	<param name="myeditor" type="editors" default="none" label="Select an editor" />
	<param name="myfile" type="filelist" default="" label="Select a file" description="" directory="administrator" filter="" exclude="" stripext="" />
	<param name="myfolder" type="folderlist" default="" label="Select a folder" directory="administrator" filter="" exclude="" stripext="" />
	<param name="myhelpsite" type="helpsites" default="" label="Select a help site" description="" />
	<param name="mysecretvariable" type="hidden" default="" />
	<param name="myimage" type="imagelist" default="" label="Select an image" description="" directory="" exclude="" stripext="" />
	<param name="mylanguage" type="languages" client="site" default="en-GB" label="Select a language" description="" />
	<param name="mylistvalue" type="list" default="" label="Select an option" description="">
	  <option value="0">Option 1</option>
	  <option value="1">Option 2</option>
	</param>
	<param name="mymenu" type="menu" default="mainmenu" label="Select a menu" description="Select a menu" />
	<param name="mymenuitem" type="menuitem" default="45" label="Select a menu item" description="Select a menu item" />
	<param name="mypassword" type="password" default="secret" label="Enter a password" description="" size="5" />
	<param name="myradiovalue" type="radio" default="0" label="Select an option" description="">
	  <option value="0">1</option>
	  <option value="1">2</option>
	</param>
	<param type="spacer" default="&lt;b&gt;Advanced parameters&lt;/b&gt;" />
	<param name="myfield" type="sql" default="10" label="Select an article" query="SELECT id, title FROM #__content" key_field="id" value_field="title" />
	<param name="mytextvalue" type="text" default="Some text" label="Enter some text" description="" size="10" />
	<param name="mytextarea" type="textarea" default="default" label="Enter some text" description="" rows="10" cols="5" />
	<param name="mytimezone" type="timezones" default="-10" label="Select a timezone" description="" />
	<param name="myusergroups" type="usergroup" default="" label="Select a user group" description="" />

	<!-- Custom Param Types -->
	<params addpath=”[path-Joomla]/templates/mytemplate/elements”>
	    <param type=”newparm” name=”setting1” default=”12” />
	    <param type=”text” name=”setting2” value=”Some text” />
	</params>


</extension>

CSS

Joomla! Klassenbezeichner
Layout Entsprechende CSS Klassenbezeichner
Article Layout componentheading, contentpaneopen, contentheading, contentpagetitle
Category Blog, Frontpage Blog, Section Blog componentheading, contentpagetitle, blog, contentpaneopen, contentheading, readon, blog_more
Category List, Section List componentheading, contentpane, contentdescription
Contact Category componentheading, contentpane, contentdescription, sectiontablefooter, sectiontableheader, category
Contact Layout componentheading, contentpaneopen, contentheading

Plugin Generator

Beschreibung

Der Plugin Generator ist als eine Art Vorlage gedacht für Plugin-Entwickler gedacht, um das Nachschlagen im Joomla! Wiki zu erübrigen. Es gibt nahzu keine Dokumentation zu den Plugins-Events, daher ist eine Einarbeitung in den Joomla! Quellcode unerlässlich.

Klassendiagramm – Extensionen

Ausgangssituation

Der Generator war vorher schon ansatzweise implementiert. Die Funktion zur der benötigten Verzeichnisstruktur und zur Generierung der benötigen Dateien war bereits vorhanden. Die pluginName.xml Datei konnte soweit erstellt werden, so dass die Installation über das Backend ohne Probleme funktionierte. Funktionen, die vor dem Projektbeginn vorhanden waren sind: pluginName.xml

Der Generator kann über die Instanz eine pluginName.xml Datei beschreiben. Die Installation des Plugins funktioniert.

Zu den implementierten Funktionen im Generator war die benötigte Grammatik schon teilweise vorhanden. Das nachfolgende Diagramm stellt nun die Grammatik für das Plugin (teilweise) dar:

Grammatik

Plugin returns Plugin:
	{Plugin}
	'Plugin' name=MYID 
	'{'
		'Manifestation' '{' (manifest=Manifestation) '}'
		'Plugintype' '=' type=PluginKinds
		('languages' '{' (languages+=Language)* '}')?
		('*Entities' entities+=[Entity|STRING] (',' entities+=[Entity|STRING])*)?
		('parameters' '{' (localparameters+=Parameter)* '}')?
	'}'	
;

enum PluginKinds:
    authenticate | captcha | content | contact |
    editors | extensions | finder | quick_icons |
    search | system | user | xml_rpc
;

enum SimpleDatatypeKinds:
	string | bool | int | float | array

Parameter returns Parameter:
	{Parameter}
	'Parameter' name=ID 
	'{'
		//'type' '=' ((dtype=[Datatype|QualifiedName]) | ('jvmtype' jvmtype=[jvmTypes::JvmType|QualifiedName]))
		'type' '=' ((dtype=Type))
		('defaultvalue' '=' defaultvalue=STRING)?
		('label' '=' label=STRING)?
		('size' '=' size=INT)?
		('description' '=' descripton=STRING)?
	'}'
;

ParameterGroup returns ParameterGroup:
	{ParameterGroup}
	'ParameterGroup' name=ID 
	'{'
		('label' '=' label=STRING)?
		('Parameters' '{' ((globalparameters+=[Parameter]) | (parameters+=Parameter))* '}')
	'}'
;

Statische Elemente

Bis auf die xmlContent() funktion waren alle Plugin-Events statisch und größtenteils direkt aus dem Joomla! Core kopiert.

Installation und Funktionsweise

Das Plugin kann nach der Installation nicht direkt verwendet, da Plugin-Events Auslöser für beliebige Funktionen sein können. Ohne eine konkrete Absicht des Plugin Autors kann nicht genau vorherbestimmt werden welche Funktionalität erwartet wird.

Soll-Zustand

Der Generator ist exemplarisch implementiert worden. Die Verzeichnisstruktur und pluginName.xml-Datei sind die einzigen nicht-statischen Funktionalitäten.

Es ist Ziel den Plugin-Generator soweit zu erweitern, dass ein Plugin mit den nötigsten und wiederkehrenden Code generiert wird. Die Grammatik soll von unserer Seite nicht um fehlende Ausdrücke erweitert werden, da bereits geplant ist ComponentInformation und ModuleInformation in die Grammatik einzubauen. So, dass auf diese weise aufgelöst werden kann, von welcher Komponente oder welchem Modul aus ein Plugin-Event initiert wurde.

Es soll möglich sein neue Plugin-Events und Typen Zentral erweitern zu können.

Umsetzung

Bei der Umsetzung wurde Wert darauf gelegt möglichst alle originalen Joomla!-Plugins zu unterstützen. Die Joomla!-Dokumentation bot für die Plugin-Entwicklung eine kleine Hilfe.

  • Einbindung aller gemeinsamer Event-Suffixe in die jeweiligen Plugin-Events
  • Templatisierte generierung aller Plugin-Events
  • Languages definieren
  • Editor Icons binär einlesen

Plugin-Events

	authenticateEvents()
	captchaEvents()
	contentEvents()
	contactEvents()
	editorsEvents()
	extensionsEvents()
	finderEvents()
	quickiconsEvents()
	searchEvents()
	systemEvents()
	userEvents()
	getPluginFactory()
	xmlrpcEvents()

Generatorcode

	override generate() 
	{
		generateJoomlaDirectory("")
		generateFile(plugin.name.toLowerCase + ".xml", plugin.xmlContent)
		generateFile(plugin.name.toLowerCase + ".php", plugin.phpContent)
                ...
	}

Generische und Statische Elemente

PHP CodeSniffer – Joomla!-Coding-Standards

Instanz

Ordnerstruktur

PluginDirectory.png

Roadmap

Erweiterung der Grammatik für Install Hooks

Joomla erlaubt die Erweiterung durch Komponenten, Module, Plugins und Templates. Diese können über Installer Hooks diverse Pre- und Post-Bedingungen stellen. Wir empfehlen die Erweiterung der Grammatik, um eine Unterstützung der script Sektion der Manifest Datei:

        <!-- Runs on install/uninstall/update; New in 2.5 -->
	<scriptfile>script.php</scriptfile>
 
	<install> <!-- Runs on install -->
		<sql>
			<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
		</sql>
	</install>
	<uninstall> <!-- Runs on uninstall -->
		<sql>
			<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
		</sql>
	</uninstall>
	<update> <!-- Runs on update; New in 2.5 -->
		<schemas>
			<schemapath type="mysql">sql/updates/mysql</schemapath>
		</schemas>
	</update>

Wir würden daraufhin die Datei script.php mit folgendem Inhalt generieren:

class PlgNameInstallerScript
{
	/**
	 * Run after installing.
	 *
	 * @param   object  $parent  The calling class.
	 *
	 * @return  bool  True on success | False on failure.
	 *
	 * @since   2.0
	 */
	public function postflight($parent)
	{
        }

	/**
	 * Cleanup after uninstallation.
	 *
	 * @param   object  $parent  The parent class.
	 *
	 * @return  void.
	 *
	 * @since   2.0
	 */
	public function uninstall($parent)
	{
		JFile::delete(JPATH_ADMINISTRATOR . '/components/com_name/models/addons/file.php');
	}
}

Die Inhalte dieser Funktionen sind abhängig vom Werkzeugentwickler und neben diesen werden folgende Eventhandler unterstützt:

  • preflight()
  • discover_install()
  • install()
  • update()
  • uninstall()
  • postflight()

Jede Erweiterung kann zu einer Update Site verweisen, wenn die unten gegebenen Anweisungen generiert werden.

        <!-- UPDATESERVER DEFINITION -->
	<updateservers>
		<!-- Note: No spaces or linebreaks allowed between the server tags -->
		<server type="extension" priority="1" name="DemoPlugin Update Site">http://example.org/update/demo-plugin.xml</server>
	</updateservers>

Anwendungsbeispiel aus Sicht des Werkzeugentwicklers

/*
 * This is an example model with the needed model elements entities, pages, and extensions
 * '..' are just placeholders for names and should be replaced in concrete models!
 */
eJSLModel "name of the model" {

	datatypes {
		Datatype "varchar(255) NOT NULL",
		Datatype "text NOT NULL",
		Datatype "datetime NOT NULL DEFAULT '0000-00-00 00:00:00'",
		Datatype "date",
		Datatype "textarea",
		Datatype "text",
		Datatype "editor"
	} 
	
	entities { 
		Entity entity1 {
			attributes {
				Attribute attribute1 { 
					dbtype = "varchar(255) NOT NULL"
					htmltype = "text"
					Primary attribute
				}
				Attribute attribute2 {
					dbtype = "varchar(255) NOT NULL"  
					htmltype = "editor"
				}  
			}
		} 
		Entity entity2 {
			attributes { 
				Attribute attribute1 {
					dbtype = "varchar(255) NOT NULL"
					htmltype = "text" 
					Primary attribute
				}
				Attribute attribute2 {
					dbtype = "varchar(255) NOT NULL"
					htmltype = "text"
				}
			}
			references {
				Reference {
					Attribute = attribute2
					*Entity = entity1
					Reference = entity1.attribute1
					lower = 1
					upper = 1
				}
			}
		}
	}

	pages {
		IndexPage IndexPage1 {
			*Entities entity1
			table columns = entity1.attribute1, 
				entity1.attribute2
		} 
		DetailsPage DetailsPage1 {
			*Entities entity1
		}
		IndexPage IndexPage2 {
			*Entities entity1, entity2
			table columns = entity2.attribute1, 
				entity2.attribute2
		}
		DetailsPage DetailsPage2 {
			*Entities entity2
		}
	}
	  
	extensions {
		Plugin Demo {
			Manifestation {
				authors { 
					Author "Max Mustermann" {
						authoremail = "max.mustermann@mni.thm.de"
						authorurl = "http://max.thm.de"
					}
				}
				creationdate = 19.08.2015
				copyright = "© 2015 THM – MDDP Course"
				license = "MIT"
				link = "https://wiki.thm.de/Template_Generator"
				version = "1.4"
				description = "Finder Plugin example"
			}
			Plugintype = quick_icons 
			languages {
				Language de-DE {
					keyvaluepairs {
						Key Greeting = "Hallo"
					}
				}
				Language en-EN {
					keyvaluepairs {
						Key Greeting = "Hello"
					}	
				}
			}
			parameters {
				Parameter ParamName {
					type = "date"
				}
			}
		}		
		Plugin Finder {
			Manifestation {
				authors {
					Author "Max Mustermann" {
						authoremail = "max.mustermann@mni.thm.de"
						authorurl = "http://max.thm.de"
					}
				}
				creationdate = 19.08.2015
				copyright = "© 2015 THM – MDDP Course"
				license = "MIT"
				link = "https://wiki.thm.de/Template_Generator"
				version = "1.4"
				description = "Finder Plugin example"
			}
			Plugintype = finder 
			languages {
				Language de-DE {
					keyvaluepairs {
						Key Greeting = "Hallo"
					}
				}
				Language en-EN {
					keyvaluepairs {
						Key Greeting = "Hello"
					}	
				}
			}
			parameters {
				Parameter ParamName {
					type = "date"
				}
			}
		}  
		
		Template TemplateGen { 
			Manifestation { 
				authors {
					Author "Max Mustermann" {
						authoremail = "max.mustermann@mni.thm.de"
						authorurl = "http://max.thm.de"
					}
				}
				creationdate = 13.08.2015
				copyright = "© 2015 THM – MDDP Course"
				license = "MIT"
				link = "https://wiki.thm.de/Template_Generator"
				version = "0.4"
				description = "<![CDATA[
	                <h1>Generated by the MDD Template Generator for Joomla! 2 &amp; 3</h1>
	                <p>This template was generated using Model Driven Development (MDD). It goes beyond designing a theme by hand and integrates Twitter's Bootstrap with Joomla.</p>
	                <h4>Technologies used in this template:</h4>
	                <ul>
	                    <li>Twitter's Bootstrap Framework in v3.3.5</li>
	                </ul>
	                <br><p>Created during the <a href=\"https://wiki.thm.de/Template_Generator\" target=\"_blank\">MDD Course</a></p>
                ]]>" 
			}
			languages { 
				Language de-DE { 
					keyvaluepairs {
						Key TPL_Template1_TOP = "Hoch"
					}
	   			}
				Language en-GB {
					keyvaluepairs {
						Key TPL_Template1_TOP = "Top"
					} 
				}
			}
			 
			positions {
				Templateposition head {
					divId = main_menu
  					 PositionParameters {
						PositionParameter nav { 
							divId = page_navigation
							PositionParameterTypes {  
								PositionParameterType { 
									divId = firstlevel
									jdoc = modules { 
										type = modules  
										style module_chrome = "rounded"  
										jdoc_attributes {  
											Key headerlevel="3" 
										} 
									} 
									CSS keyvaluepairs {
										Key width = "100%" 
					 				}
								}      
								PositionParameterType {
									divId = seconlevel
									jdoc = modules {
										type = modules
										style module_chrome = "customModuleChrome"
										jdoc_attributes { 
											Key headerlevel = "4"
										}
									}
								} 
							} 
							CSS keyvaluepairs {
								Key width = "50%" 
								Key height = "15%" 
							}
						}
						PositionParameter upper_left {
							divId = head_search
							PositionParameterTypes  { 
					   			PositionParameterType {
									divId = mylogo 
									jdoc = modules {
										type = modules
										style module_chrome = "navSearch"
									}
									
									CSS keyvaluepairs { 
										Key width="50px"
										Key height="50px"
									}
								}
							}	
							CSS keyvaluepairs { 
								Key position = "relativ"
								Key padding = "3px"
							}  
						} 
					}
					CSS keyvaluepairs {
						Key height = "100%"
						Key width = "100%"
					}   
				}
				Templateposition contents {
				 	 
					PositionParameters {
						PositionParameter article {
			 				divId = weekly
							PositionParameterTypes {
								PositionParameterType { 
									divId = highlighted
									jdoc = message 
									CSS keyvaluepairs {  
										Key position = "relative"
									} 
								}
								PositionParameterType {
									divId = blog
									jdoc = component
									CSS keyvaluepairs {
										Key position = "relative"
									}
								}    
							}
							CSS keyvaluepairs {
								Key background_color = "white"
							}
						}
					}
				}
			} 
			
			cssblocks {
				CssBlock "#main_nav" (
					keyvaluepairs {
						Key color = "#fefefe"
					}
				)
			}
			
			libraries { 
				Key css = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"
				Key css = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"
				Key js = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"
			}
			
			favicons { 
				Key image = "http://orig09.deviantart.net/3042/f/2014/276/2/c/gnome_control_center_icon_by_master_user-d81gqqq.png"
				Key ressource = "url"
				Platforms {
					Key Android = "true"
					Key iPhone = "true"
					Key WindowsPhone = "true"
					Key WindowsTile = "true"
				}
			}
		
		}
	}
}