TEE-02 Extension Creator: Unterschied zwischen den Versionen

Aus Contao Community Documentation

(Die Seite wurde neu angelegt: „{{stub}} Tagebuch einer Extension-Entwicklung Category:Tagebuch_einer_Extension-Entwicklung {{AppliesTo |Ext1=Extension Creator |TLVersion=ab TL 2.8}} =Exten…“)
 
K (div. Korrekturen)
 
(4 dazwischenliegende Versionen von einem Benutzer werden nicht angezeigt)
Zeile 7: Zeile 7:
  
 
=Extension-Creator=
 
=Extension-Creator=
Ich verwende den [http://www.contao.org/erweiterungsliste/view/development.de.html Extension-Creator] aus dem Extension-Repository. Der ''Extension-Creator'', ehemals: ''Module Creator'', wurde von Leo Fey programmiert, war ursprünglich Teil des TL-Cores und wurde dann in eine separate Extension ausgelagert. Sie müssen den ''Extension-Creator'' also zunächst aus dem Repository installieren. Er firmiert im Repository allerdings nicht als ''Extension-Creator'', sondern als ''development''!
+
Ich verwende den [http://www.contao.org/erweiterungsliste/view/development.de.html Extension-Creator] aus dem Extension-Repository. Der ''Extension-Creator'', ehemals: ''Module Creator'', programmiert von Leo Feyer, war ursprünglich Teil des TL-Cores und wurde dann in eine separate Extension ausgelagert. Sie müssen den ''Extension-Creator'' also zunächst aus dem Repository installieren. Er firmiert im Repository allerdings nicht als ''Extension-Creator'', sondern als ''development''!
  
[[Datei:ext_crea01.png]]
+
[[Datei:ext_crea01.png|Extension Repository - development]]
  
 
Der ''Extension-Creator'' erscheint dann in der Dateistruktur unter ''tl/system/modules/development'' und in der Sidebar des Backends unter ''System''.
 
Der ''Extension-Creator'' erscheint dann in der Dateistruktur unter ''tl/system/modules/development'' und in der Sidebar des Backends unter ''System''.
  
[[Datei:ext_crea02.png]]
+
[[Datei:ext_crea02.png|Backend - Extension Creator]]
  
 
Also, los geht es mit dem Skelett für die geplante Extension.
 
Also, los geht es mit dem Skelett für die geplante Extension.
  
[[Datei:ext_crea03.png]]
+
[[Datei:ext_crea03.png|Extension Creator]]
  
 
* Titel: Es geht um Turnierpaar-"Verwaltung", und um Namenskonflikte zu vermeiden möchte ich gerne einen spezifischen Präfix nutzen: ''gw'' angelehnt an den Vereinsnamen "Grün-Weiß". Also: Titel = ''gw_turnierpaare''. An dieser Stelle bin ich mir noch nicht so sicher, wo dieser "Titel" überall erscheinen wird, und ob es deshalb ein beliebiger Text sein soll, oder eher ein "identifier", also z.b. ohne Leerzeichen u.ä. Sicherheitshalber gehe ich den Identifier-Weg. Besser hässlich als nicht-funktionierend.
 
* Titel: Es geht um Turnierpaar-"Verwaltung", und um Namenskonflikte zu vermeiden möchte ich gerne einen spezifischen Präfix nutzen: ''gw'' angelehnt an den Vereinsnamen "Grün-Weiß". Also: Titel = ''gw_turnierpaare''. An dieser Stelle bin ich mir noch nicht so sicher, wo dieser "Titel" überall erscheinen wird, und ob es deshalb ein beliebiger Text sein soll, oder eher ein "identifier", also z.b. ohne Leerzeichen u.ä. Sicherheitshalber gehe ich den Identifier-Weg. Besser hässlich als nicht-funktionierend.
Zeile 25: Zeile 25:
 
* Autor, Copyright und Lizenz: Selbsterklärend
 
* Autor, Copyright und Lizenz: Selbsterklärend
  
* Paket: Ein Paketname ist gefragt. Der Hilfetext unter dem Eingabefeld schlägt hilfreich "z.B. meinEigenesModul" vor. Ist das Modul jetzt das Paket? Was ist ein Paket? Sowas wie ein Namensraum? Da ich noch nicht weiß, ob ich für die Vereinsseite noch andere Extensions pogrammieren werde, nehme ich die Vereinsabkürzung als "Paketname", also ''GW''. Weitere vereinsspezifische Extensions würde ich dann in dasselbe Paket stecken.
+
* Paket: Ein Paketname ist gefragt. Der Hilfetext unter dem Eingabefeld schlägt hilfreich "z.B. meinEigenesModul" vor. Ist das Modul jetzt das Paket? Was ist ein Paket? So was wie ein Namensraum? Da ich noch nicht weiß, ob ich für die Vereinsseite noch andere Extensions programmieren werde, nehme ich die Vereinsabkürzung als "Paketname", also ''GW''. Weitere vereinsspezifische Extensions würde ich dann in dasselbe Paket stecken.
  
 
* Ein Backend-Modul hinzufügen: Ja klar, schließlich sollen Daten im Backend bearbeitet werden. Also dort ein Häkchen.
 
* Ein Backend-Modul hinzufügen: Ja klar, schließlich sollen Daten im Backend bearbeitet werden. Also dort ein Häkchen.
Zeile 31: Zeile 31:
 
* Backend-Klassen: Wenig hilfreicher Erklärungstext: "Hier können Sie eine kommagetrennte Liste der zu erstellenden Backend-Klassen eingeben." - Was sind Backend-Klassen? Wofür brauche ich die? Eigentlich müsste doch alles, was ich im Backend vorhabe, durch Einträge im DCA-File realisierbar sein, schließlich geht es nur um Pflege von zwei abhängigen Datenbanktabellen. Also mal mutig leer gelassen, falls das falsch ist kann man es später noch hinzufügen.
 
* Backend-Klassen: Wenig hilfreicher Erklärungstext: "Hier können Sie eine kommagetrennte Liste der zu erstellenden Backend-Klassen eingeben." - Was sind Backend-Klassen? Wofür brauche ich die? Eigentlich müsste doch alles, was ich im Backend vorhabe, durch Einträge im DCA-File realisierbar sein, schließlich geht es nur um Pflege von zwei abhängigen Datenbanktabellen. Also mal mutig leer gelassen, falls das falsch ist kann man es später noch hinzufügen.
  
* Backend-Tabellen: Das sind wohl meine Datentabellen, ich will eine für Turnierpaare, eine für Meldungen, also: ''tl_gw_turnierpaare,tl_gw_meldungen''.
+
* Backend-Tabellen: Das sind wohl meine Datentabellen. Ich will eine für Turnierpaare, eine für Meldungen, also: ''tl_gw_turnierpaare,tl_gw_meldungen''.
  
 
* Backend-Templates: Auch hier wieder wenig erhellender Hilfetext. Auch das TL-Buch beschränkt sich da leider fast auf das Abschreiben der Hilfetexte unter den Eingabefeldern. Ich kenne Templates nur für das Frontend, also beschließe ich mutig, dass ich das wohl nicht brauche. Sollte sich das später als Irrtum herausstellen, wird es sich hoffentlich noch korrigieren lassen.
 
* Backend-Templates: Auch hier wieder wenig erhellender Hilfetext. Auch das TL-Buch beschränkt sich da leider fast auf das Abschreiben der Hilfetexte unter den Eingabefeldern. Ich kenne Templates nur für das Frontend, also beschließe ich mutig, dass ich das wohl nicht brauche. Sollte sich das später als Irrtum herausstellen, wird es sich hoffentlich noch korrigieren lassen.
Zeile 37: Zeile 37:
 
* Ein Frontend-Modul hinzufügen: Aber klar, die Daten sollen schließlich im Frontend visualisiert werden. Also Haken dran.
 
* Ein Frontend-Modul hinzufügen: Aber klar, die Daten sollen schließlich im Frontend visualisiert werden. Also Haken dran.
  
* Frontend-Klassen: So weit wie ich es bisher verstanden habe, braucht jedes Modul eine eigene Klasse. Nach meiner bisherigen Planung brauche ich ein Modul ''Turnierpaarliste'' inklusive Detail-Ansicht der einzelnen Paar-Einträge. Die Unterscheidung aktiv/nicht aktiv würde ich gerne über einen Parameter im Modul lösen, so dass dasselbe Modul die Liste der aktiven und der ehemaligen Paare anzeigen kann. Außerdem benötige ich ein Modul ''Meldeliste'' mit der chronologisch sortierten Übersicht der Meldungen. Also: ''gwTurnierpaarliste,gwMeldeliste'' als Klassennnamen.
+
* Frontend-Klassen: So weit wie ich es bisher verstanden habe, braucht jedes Modul eine eigene Klasse. Nach meiner bisherigen Planung brauche ich ein Modul ''Turnierpaarliste'' inklusive Detail-Ansicht der einzelnen Paar-Einträge. Die Unterscheidung aktiv/nicht aktiv würde ich gerne über einen Parameter im Modul lösen, so dass dasselbe Modul die Liste der aktiven und der ehemaligen Paare anzeigen kann. Außerdem benötige ich ein Modul ''Meldeliste'' mit der chronologisch sortierten Übersicht der Meldungen. Also: ''gwTurnierpaarliste,gwMeldeliste'' als Klassennamen.
  
 
* Frontend-Tabellen: Ratlosigkeit. Was unterscheidet Frontend-Tabellen von Backend-Tabellen? Da ich meine Tabellen schon in den Backend-Tabellen abgehandelt habe, lasse ich das Feld leer.
 
* Frontend-Tabellen: Ratlosigkeit. Was unterscheidet Frontend-Tabellen von Backend-Tabellen? Da ich meine Tabellen schon in den Backend-Tabellen abgehandelt habe, lasse ich das Feld leer.
Zeile 45: Zeile 45:
 
* Sprachpakete erstellen: Natürlich. Auch wenn es wahrscheinlich niemand in Englisch benutzen wird, tut es mir aber auch nicht weh, also Sprachen = ''en,de''.
 
* Sprachpakete erstellen: Natürlich. Auch wenn es wahrscheinlich niemand in Englisch benutzen wird, tut es mir aber auch nicht weh, also Sprachen = ''en,de''.
  
[[Datei:ext_crea04.png]]
+
[[Datei:ext_crea04.png|Extension Creator - Einstellungen]]
  
Dann "speichern und schließen", und auf den grünen Haken am Ende der neuen Zeile ''gw_turnierpaare'' im Extension-Creator geklickt.  
+
Dann "Speichern und schließen", und auf den grünen Haken am Ende der neuen Zeile ''gw_turnierpaare'' im Extension-Creator geklickt.  
  
[[Datei:ext_crea05.png]]
+
[[Datei:ext_crea05.png|Extension Creator - Übersicht]]
  
 
Die Warnung bestätigt,  
 
Die Warnung bestätigt,  
  
[[Datei:ext_crea06.png]]
+
[[Datei:ext_crea06.png|Extension Creator - Warnung]]
  
und der Extension-Creator hat mir erstmal den Grundstock an Files in ''/system/modules/gw_turnierpaare/'' erzeugt. Und zwar:
+
und der Extension-Creator hat mir erst mal den Grundstock an Files in ''/system/modules/gw_turnierpaare/'' erzeugt. Und zwar:
  
 
* ''gwMeldeliste.php,gwTurnierpaarliste.php'': meine Frontendklassen
 
* ''gwMeldeliste.php,gwTurnierpaarliste.php'': meine Frontendklassen
Zeile 74: Zeile 74:
 
Genauso freue ich mich über Aufklärung zu Dingen, die ich selbst nicht verstehe...Backendklassen, Backend-
 
Genauso freue ich mich über Aufklärung zu Dingen, die ich selbst nicht verstehe...Backendklassen, Backend-
 
Templates, Frontend-Tabellen, Paket...
 
Templates, Frontend-Tabellen, Paket...
 +
 +
==Diskussion==
 +
'''user: Schnippsel'''
 +
 +
1. Irritiert bin ich über eine Inkonsistenz Deiner Namenskonvention. Während Du die Mehrzahl der Objekte mit dem Präfix ''gw_'' einleitest, verwendest Du bei den Frontend-Klassen das Präfix ''gw'' (also ohne Unterstrich). Für ein simples Gemüt wie mich würde das unweigerlich zu Fehlern führen. Ich bin da ein Entweder-/Oder-Mensch. Dass die Tabellen durch ein weiteres Präfix (ein Präpräfix?) gekennzeichnet sind, stört und verwirrt mich hingegen überhaupt nicht.
 +
 +
2. Etwas sehr rasant bist Du für mein Empfinden über die Thematik "Autor, Copyright und Lizenz" hinweggehuscht, indem Du sie als "Selbsterklärend" deklariert hast.
 +
 +
Gut: wer der Autor ist, ist tatsächlich meist selbsterklärend, Allerdings würde eine kleine Änderung die Sache noch deutlicher machen, indem man nämlich einfach "Autor(en)" - bei tl_extension.php in den Language Files - schriebe. Da ich selber in vielen Projekten (mit)arbeite, an denen verschiedene Leute am Quellcode arbeiten, ist mir der Hinweis wichtig.
 +
 +
Schwieriger sieht es beim Copyright aus, selbst bei Einzelkämpfern. Wurde der Code z.B. in Rahmen eines normalen Arbeitsverhältnisses erstellt, liegt das Copyright vermutlich nicht beim Autor, sondern bei der Firma (oder dem Verein?), für die er programmiert. Bei Freelancern ist die Frage des Copyrights ggf. abhängig von der Art des Vertrages (Werkvertrag/Dienstvertrag) und/oder entsprechenden vertraglichen Regelungen.
 +
 +
Auch die Frage der Lizenz ist nicht unbedingt trivial, obwohl ich natürlich bei einem "echten" Entwickler (also jemand, der sich beruflich und bezahlt mit derlei Dingen beschäftigt) davon ausgehe, dass er sich über Lizenzfragen im Klaren ist.
 +
 +
Es sei darauf hingewiesen, dass der ''Extension-Creator'' im Kopf der generierten Dateien generell den Text für die GNU/LGPL einträgt, egal was man selbst unter "Lizenz" reinschreibt. Das beruht auf den Templates, die sich unter ''/system/modules/development/templates'' finden.
 +
 +
Für diejenigen, die sich über die GNU/LGPL informieren möchten, hier ein paar Links:
 +
 +
[http://www.gnu.de/documents/lgpl-3.0.de.html GNU Lesser General Public License Version 3.0]
 +
 +
Siehe dazu auch:
 +
 +
[http://www.gnu.de/free-software/index.de.html Freie Software]
 +
 +
[http://www.gnu.de/free-software/open-source.de.html Freie Software/Open Source]
 +
 +
3. Mir ist auch der Zusammenhang zwischen Copyright und Lizenz nicht wirklich klar. Ist ''Copyright'' nicht eigentlich auch eine Art ''Lizenz''? Da wäre es schön, wenn ein juristischer Fachmann Licht ins Dunkel bringen könnte - ein Link auf eine verständliche Seite würde mir genügen.
 +
 +
Zu guter Letzt: gibt es nicht auch eine Art ''Vererbung'' der Lizenz? So weit ich es verstanden habe, darf ich in ein Open Source Projekt (Parent) auch nur Open Source Erweiterungen (Child) einbringen.

Aktuelle Version vom 12. Juli 2010, 00:17 Uhr

MsgError.png Unvollständiger Artikel: dieser Artikel ist noch nicht sauber bearbeitet.

Bitte erweitere ihn und entferne erst anschliessend diesen Hinweis.

Tagebuch einer Extension-Entwicklung

betrifft
TYPOlight Version ab TL 2.8
Extensions Extension Creator


Extension-Creator

Ich verwende den Extension-Creator aus dem Extension-Repository. Der Extension-Creator, ehemals: Module Creator, programmiert von Leo Feyer, war ursprünglich Teil des TL-Cores und wurde dann in eine separate Extension ausgelagert. Sie müssen den Extension-Creator also zunächst aus dem Repository installieren. Er firmiert im Repository allerdings nicht als Extension-Creator, sondern als development!

Extension Repository - development

Der Extension-Creator erscheint dann in der Dateistruktur unter tl/system/modules/development und in der Sidebar des Backends unter System.

Backend - Extension Creator

Also, los geht es mit dem Skelett für die geplante Extension.

Extension Creator

  • Titel: Es geht um Turnierpaar-"Verwaltung", und um Namenskonflikte zu vermeiden möchte ich gerne einen spezifischen Präfix nutzen: gw angelehnt an den Vereinsnamen "Grün-Weiß". Also: Titel = gw_turnierpaare. An dieser Stelle bin ich mir noch nicht so sicher, wo dieser "Titel" überall erscheinen wird, und ob es deshalb ein beliebiger Text sein soll, oder eher ein "identifier", also z.b. ohne Leerzeichen u.ä. Sicherheitshalber gehe ich den Identifier-Weg. Besser hässlich als nicht-funktionierend.
  • Ordnername: Ebenfalls gw_turnierpaare.
  • Autor, Copyright und Lizenz: Selbsterklärend
  • Paket: Ein Paketname ist gefragt. Der Hilfetext unter dem Eingabefeld schlägt hilfreich "z.B. meinEigenesModul" vor. Ist das Modul jetzt das Paket? Was ist ein Paket? So was wie ein Namensraum? Da ich noch nicht weiß, ob ich für die Vereinsseite noch andere Extensions programmieren werde, nehme ich die Vereinsabkürzung als "Paketname", also GW. Weitere vereinsspezifische Extensions würde ich dann in dasselbe Paket stecken.
  • Ein Backend-Modul hinzufügen: Ja klar, schließlich sollen Daten im Backend bearbeitet werden. Also dort ein Häkchen.
  • Backend-Klassen: Wenig hilfreicher Erklärungstext: "Hier können Sie eine kommagetrennte Liste der zu erstellenden Backend-Klassen eingeben." - Was sind Backend-Klassen? Wofür brauche ich die? Eigentlich müsste doch alles, was ich im Backend vorhabe, durch Einträge im DCA-File realisierbar sein, schließlich geht es nur um Pflege von zwei abhängigen Datenbanktabellen. Also mal mutig leer gelassen, falls das falsch ist kann man es später noch hinzufügen.
  • Backend-Tabellen: Das sind wohl meine Datentabellen. Ich will eine für Turnierpaare, eine für Meldungen, also: tl_gw_turnierpaare,tl_gw_meldungen.
  • Backend-Templates: Auch hier wieder wenig erhellender Hilfetext. Auch das TL-Buch beschränkt sich da leider fast auf das Abschreiben der Hilfetexte unter den Eingabefeldern. Ich kenne Templates nur für das Frontend, also beschließe ich mutig, dass ich das wohl nicht brauche. Sollte sich das später als Irrtum herausstellen, wird es sich hoffentlich noch korrigieren lassen.
  • Ein Frontend-Modul hinzufügen: Aber klar, die Daten sollen schließlich im Frontend visualisiert werden. Also Haken dran.
  • Frontend-Klassen: So weit wie ich es bisher verstanden habe, braucht jedes Modul eine eigene Klasse. Nach meiner bisherigen Planung brauche ich ein Modul Turnierpaarliste inklusive Detail-Ansicht der einzelnen Paar-Einträge. Die Unterscheidung aktiv/nicht aktiv würde ich gerne über einen Parameter im Modul lösen, so dass dasselbe Modul die Liste der aktiven und der ehemaligen Paare anzeigen kann. Außerdem benötige ich ein Modul Meldeliste mit der chronologisch sortierten Übersicht der Meldungen. Also: gwTurnierpaarliste,gwMeldeliste als Klassennamen.
  • Frontend-Tabellen: Ratlosigkeit. Was unterscheidet Frontend-Tabellen von Backend-Tabellen? Da ich meine Tabellen schon in den Backend-Tabellen abgehandelt habe, lasse ich das Feld leer.
  • Frontend-Templates: Natürlich! gw_turnierpaarliste,gw_turnierpaarliste_detail,gw _meldeliste fallen mir sofort ein, vielleicht genügt das schon. Falls nicht, kann ich später noch welche hinzufügen.
  • Sprachpakete erstellen: Natürlich. Auch wenn es wahrscheinlich niemand in Englisch benutzen wird, tut es mir aber auch nicht weh, also Sprachen = en,de.

Extension Creator - Einstellungen

Dann "Speichern und schließen", und auf den grünen Haken am Ende der neuen Zeile gw_turnierpaare im Extension-Creator geklickt.

Extension Creator - Übersicht

Die Warnung bestätigt,

Extension Creator - Warnung

und der Extension-Creator hat mir erst mal den Grundstock an Files in /system/modules/gw_turnierpaare/ erzeugt. Und zwar:

  • gwMeldeliste.php,gwTurnierpaarliste.php: meine Frontendklassen
  • config/config.php und config/database.sql (Letzteres für meine SQL-Tabellenstruktur)
  • dca/tl_gw_turnierpaare.php und dca/tl_gw_meldungen.php: Die DCA-Definitionen für meine Tabellen zur Bearbeitung im Backend
  • languages/...: Die Sprachfiles in en und de-Variante
  • templates/...: Die drei Frontend-Templates, die ich angegeben hatte

Im nächsten Schritt orientieren wir uns etwas und beginnen, die vorgegebenen Files zu modifizieren.

P.S.: Wenn die erfahrenen TL-Programmierer jetzt schon Gänsehaut haben: Sorry. Ich mache das zum ersten Mal, und stelle mich nicht künstlich dumm an. Ich versuche so zu schildern, wie ich als Einsteiger die Sachen sehe, was mich verwirrt usw...Bin für Verbesserungsvorschläge z.B. zu Namens-Schemata usw immer zu haben. Genauso freue ich mich über Aufklärung zu Dingen, die ich selbst nicht verstehe...Backendklassen, Backend- Templates, Frontend-Tabellen, Paket...

Diskussion

user: Schnippsel

1. Irritiert bin ich über eine Inkonsistenz Deiner Namenskonvention. Während Du die Mehrzahl der Objekte mit dem Präfix gw_ einleitest, verwendest Du bei den Frontend-Klassen das Präfix gw (also ohne Unterstrich). Für ein simples Gemüt wie mich würde das unweigerlich zu Fehlern führen. Ich bin da ein Entweder-/Oder-Mensch. Dass die Tabellen durch ein weiteres Präfix (ein Präpräfix?) gekennzeichnet sind, stört und verwirrt mich hingegen überhaupt nicht.

2. Etwas sehr rasant bist Du für mein Empfinden über die Thematik "Autor, Copyright und Lizenz" hinweggehuscht, indem Du sie als "Selbsterklärend" deklariert hast.

Gut: wer der Autor ist, ist tatsächlich meist selbsterklärend, Allerdings würde eine kleine Änderung die Sache noch deutlicher machen, indem man nämlich einfach "Autor(en)" - bei tl_extension.php in den Language Files - schriebe. Da ich selber in vielen Projekten (mit)arbeite, an denen verschiedene Leute am Quellcode arbeiten, ist mir der Hinweis wichtig.

Schwieriger sieht es beim Copyright aus, selbst bei Einzelkämpfern. Wurde der Code z.B. in Rahmen eines normalen Arbeitsverhältnisses erstellt, liegt das Copyright vermutlich nicht beim Autor, sondern bei der Firma (oder dem Verein?), für die er programmiert. Bei Freelancern ist die Frage des Copyrights ggf. abhängig von der Art des Vertrages (Werkvertrag/Dienstvertrag) und/oder entsprechenden vertraglichen Regelungen.

Auch die Frage der Lizenz ist nicht unbedingt trivial, obwohl ich natürlich bei einem "echten" Entwickler (also jemand, der sich beruflich und bezahlt mit derlei Dingen beschäftigt) davon ausgehe, dass er sich über Lizenzfragen im Klaren ist.

Es sei darauf hingewiesen, dass der Extension-Creator im Kopf der generierten Dateien generell den Text für die GNU/LGPL einträgt, egal was man selbst unter "Lizenz" reinschreibt. Das beruht auf den Templates, die sich unter /system/modules/development/templates finden.

Für diejenigen, die sich über die GNU/LGPL informieren möchten, hier ein paar Links:

GNU Lesser General Public License Version 3.0

Siehe dazu auch:

Freie Software

Freie Software/Open Source

3. Mir ist auch der Zusammenhang zwischen Copyright und Lizenz nicht wirklich klar. Ist Copyright nicht eigentlich auch eine Art Lizenz? Da wäre es schön, wenn ein juristischer Fachmann Licht ins Dunkel bringen könnte - ein Link auf eine verständliche Seite würde mir genügen.

Zu guter Letzt: gibt es nicht auch eine Art Vererbung der Lizenz? So weit ich es verstanden habe, darf ich in ein Open Source Projekt (Parent) auch nur Open Source Erweiterungen (Child) einbringen.

Ansichten
Meine Werkzeuge

Contao Community Documentation

Irgendwie wird es im Mumble immer ruhiger wenn sich der Kim-Faktor verkleinert.

Sascha Müller
Navigation
Verstehen
Verwenden
Entwickeln
Verschiedenes
Werkzeuge