C3: Tutorial Extension Entwicklung 2.Teil: Selective DCA Paletten und Subpaletten

Aus Contao Community Documentation


I'm on a mission: In diesem und hoffentlich nachfolgenden Tutorials bringe ich die Videos von Tristan Lins zu "Papier". Dies ist immer etwas zeitaufwändig. Meist brauche ich dazu so 1-2 Wochen. Bitte ändert daher nichts an diesem Artikel, solange dieser Hinweis hier steht. Anschließend natürlich gerne. Stand:24.4.13

"Warnhinweis"


Einleitung

Dieses Tutorial basiert auf dem ersten Teil dieser Reihe:
http://de.contaowiki.org/C3:_Tutorial_Extension_Entwicklung_1.Teil:_Grundlagen

Auch dieses Tutorial basiert auf der großartigen Screencast-Reihe von Tristan Lins. Unbedingt ansehen!
Videolink : DCA Paletten und Subpaletten, MetaPalettes

An wen richtet sich dieses Tutorial?

Dieses Tutorial ist für all diejenigen gedacht, die ein Step-by-Step Tutorial zum Einstieg in die Extension-Entwicklung mit Contao 3 suchen.

Lernziel

Das Screencast-Modul aus dem ersten Teil wird um zusätzliche Funktionen erweitert: Der BE-User kann nun unter verschiedenen Screencast-Quellen auswählen. In Abhängigkeit der Quellen ändern sich die nachfolgenden Eingabe- bzw. Auswahlfelder. Diese kontextsensitiven Felder bezeichnet man in Conato als selektive Paletten.

<--Bild des fertigen Moduls-->

Was man wisen sollte

Grundlagen in PHP, objektorientierter Programmierung und SQL sind nötig. Ferner sollte man Grundlagen der Extension-Entwicklung in Conato verstanden haben (Verzeichnisstruktur, DCA, Templates).

Wer damit noch Schwierigkeiten hat, der sollte hier:
http://de.contaowiki.org/C3:_Tutorial_Extension_Entwicklung_1.Teil:_Grundlagen
nochmal die Grundlagen nachlesen.

Vorbereitung

Der fertige Quellcode aus dem ersten Teil muss vorhanden sein.

Source-Code

Den Quellcode könnt ihr hier: https://github.com/bit3/contao-screencast3 herunterladen.

Hinweis.png Hinweis: Es kann sein, dass der Quellcode auf github bereits einer fortgeschritteneren Version entspricht. Passt die Dateien daher ggf. dem Code dieses Tutorials an oder (am besten) programmiert alles selber!


Definition der Anwendungsfälle

Unsere Anwendung soll folgendes leisten:

  1. Zunächst hat der BE-User nur die Auswahl, welche Screencast-Quelle er eingeben möchte und welchen Titel er dieser Quelle gibt. Zur Auswahl stehen hier: Keine Quelle (default), Remote oder Lokal.
  2. Hat er die Wahl getroffen, werden zusätzliche Optionen sichtbar.

Fall: Keine Quelle

Es werden keine zusätzlichen Optionen angezeigt.

Fall: Lokal

Video 11:19 Es wird die Möglichkeit gegeben, direkt auf eine Datei aus der Dateiverwaltung zu verlinken.

Fall: Remote

Video 11:19

Es wird die Möglichkeit gegeben, zwischen zwei Remote-Plattformen zu wählen (Youtube und Vimeo).

Entscheidet sich der User für "Youtube", erhält er die Optionen die Video-URL einzutragen, nach Ende des Videos vorgeschlagene Video einzublenden, über HTTPS zu streamen, erweiterten Datenschutz zu aktivieren und die Größe anzugeben.

Bei "Vimeo" erhält er die Optionen die Video-URL einzutragen und eine Größe anzuwählen.

<--Bild der selektiven Lokal-Paletten-->


Die DCA-Paletten

Was sind Paletten und Subpaletten?

Bei Paletten handelt es sich um eine Gruppe von Eingabe und Auswahlfeldern, die zu einem Modul oder Element gehören. Paletten sind logischerweise immer an den Anwendungsfall angepasst.

<--Bild unterschiedlicher Paletten-->

Paletten können sich aber nicht nur grundsätzlich (News, Calendar, FAQ, etc.) sondern auch dynamisch innerhalb eines Moduls bzw. Elements unterscheiden.

Subpaletten ergänzen Paletten um einzelen Felder. Subpaletten werden innerhalb eines Moduls oder Elements meist von mehreren Paletten gemeinsam verwendet.

<--Bild unterschiedlicher Paletten eines Moduls-->

Für die unterschiedlichen Ansichten müssen daher die jeweiligen Paletten definiert werden.

Definition der Paletten

  • Öffnet die Datei dca/tl_screencast.php und modifiziert den Code im Bereich palettes wie folgt:
	// Palettes
	'palettes' => array
	(
		'__selector__'  => array('type', 'platform', 'defineSize'),
		'default'       => '{title_legend},type,title',
		'remote'        => '{title_legend},type,title;{screencast_legend},platform',
		'remoteyoutube' => '{title_legend},type,title;{screencast_legend},platform,url,youtubeShowSuggestions,youtubeHttps,youtubeExtendedDataSecurity;{display_legend:hide},defineSize',
		'remotevimeo'   => '{title_legend},type,title;{screencast_legend},platform,url;{display_legend:hide},defineSize',
		'local'         => '{title_legend},type,title;{screencast_legend},path',
	),
		// Subpalettes
	'subpalettes' => array
	(
		'defineSize_predefined' => 'sizePredefined',
		'defineSize_custom'	=> 'sizeCustom'
	),

Was passiert hier? Im ersten Teil dieser Reihe gab es nur eine Palette (default). In unserem erweiterten Modul Screencast werden für die verschiedenen Anwendungsfälle unterschiedliche Eingabe- und Auswahlfelder nötig. Diese werden in den Paletten definiert.

Gehen wir die Paletten in der Reihenfolge durch, wie sie ich auch im Modul auftauchen:

Die default Palette

Die default-Palette wird immer zuerst angezeigt. In unserem Beispiel hat der BE-User also zuächst nur die Möglichkeit, einen bestimmten Screencast-Typ (type) auszuwählen und einen Titel (title) einzugeben.

<--Bild default Palette-->

Die local Palette

Die local Palette zeigt sich dem User, wenn er im Bereich type die Auswahl local trifft.

<--Bild local Palette-->

Die remote Palette

Die remote Palette zeigt sich dem User, wenn er im Bereich type die Auswahl remote trifft. <--Bild remote Palette-->

Die remoteyoutube Palette

Die remoteyoutube Palette zeigt sich dem User, wenn er im Bereich type die Auswahl remote trifft und anschließend im Feld Plattform youtube wählt.

<--Bild remoteyoutube Palette-->

Die remotevimeo Palette

Die remotevimeo Palette zeigt sich dem User, wenn er im Bereich type die Auswahl remote trifft und anschließend im Feld Plattform vimeo wählt.

<--Bild remotevimeo Palette-->

Die Subpalette defineSize

Die defineSize Subpalette ist eine Zusatzpalette, die angezeigt wird, wenn der User im Bereich type die Auswahl remote trifft und anschließend im Feld Plattform vimeo oder youtube wählt.



Wozu dient dann __selector__?

Im Bereich palettes wird auch definiert, welche Felder zu einem Wechsel der Paletten führen können.

In unserem Beispiel wechseln die Paletten also, wenn der User einen bestimmten type, eine platform oder eine betimmte Größe (defineSize) ausgewählt hat.

Dies sagt jedoch noch nichts darüber aus, welche Werte die Felder haben müssen, um z.B. die Palette remoteyoutube aufzurufen. Dies geschieht in der Definition der Felder:

Die Eingabe- und Auswahlfelder anlegen

  • Ergänzt euren Code im Bereich fields um folgende Zeilen. Der Ordnung halber am besten unter dem Feld tstamp:
	'type'  => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['type'],
			'inputType' => 'select',
			'exclude'   => true,
			'sorting'   => true,
			'flag'      => 1,
			'options'   => array('remote', 'local'),
			'reference' => &$GLOBALS['TL_LANG']['tl_screencast'],
			'eval'      => array(
				'includeBlankOption' => true,
				'submitOnChange'     => true,
				'mandatory'          => true,
				'tl_class'           => 'w50',
			),
			'sql'       => "varchar(10) NOT NULL default ''"
		),

Was passiert hier? Die meisten Einträge sollten aus dem 1. Tutorial bekannt sein. Interessant sind folgende Elemente: *inputType: Hier soll nun ein Select-Feld angezeigt werden. *options: Hier werden die Optionen des Select-Feldes definiert. *includeBlankOption: In den Optionen der Select-Felder erscheint auch ein leerer Eintrag (nichts gewählt). *submitOnChange: Die Formularfelder werden immer abgesendet, wenn ihr eine neue Option im Selectfeld wählt. Das ist praktisch, da der User sonst immer erst auf "Speichern" klicken müsste, um die geänderte Palette zu sehen.


  • Speichert die Datei und aktualisiert eure Datenbank.
  • In euren Datei solltet ihr nun die Typ-Auswahlmöglichkeiten haben.

Da jedoch noch jede Menge Felder, die bereits in den Paletten definiert wurden noch fehlen, hält sich der Spaß noch in Grenzen.

  • Tauscht euren Code im fields-Bereich mit folgenden Code aus bzw. modifiziert ihn entsprechend:
	// Fields
	'fields'   => array
	(
		'id'     => array
		(
			'sql' => "int(10) unsigned NOT NULL auto_increment"
		),
		'tstamp' => array
		(
			'sql' => "int(10) unsigned NOT NULL default '0'"
		),
		'type'  => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['type'],
			'inputType' => 'select',
			'exclude'   => true,
			'sorting'   => true,
			'flag'      => 1,
			'options'   => array('remote', 'local'),
			'reference' => &$GLOBALS['TL_LANG']['tl_screencast'],
			'eval'      => array(
				'includeBlankOption' => true,
				'submitOnChange'     => true,
				'mandatory'          => true,
				'tl_class'           => 'w50',
			),
			'sql'       => "varchar(10) NOT NULL default ''"
		),
		'title'  => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['title'],
			'inputType' => 'text',
			'exclude'   => true,
			'sorting'   => true,
			'flag'      => 1,
			'search'    => true,
			'eval'      => array(
				'mandatory' => true,
				'unique'    => true,
				'maxlength' => 255,
				'tl_class'  => 'w50'
			),
			'sql'       => "varchar(255) NOT NULL default ''"
		),
		'platform'  => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['platform'],
			'inputType' => 'select',
			'exclude'   => true,
			'sorting'   => true,
			'flag'      => 1,
			'options'   => array('youtube', 'vimeo'),
			'reference' => &$GLOBALS['TL_LANG']['tl_screencast'],
			'eval'      => array(
				'includeBlankOption' => true,
				'submitOnChange'     => true,
				'mandatory'          => true,
				'tl_class'           => 'w50',
			),
			'sql'       => "varchar(10) NOT NULL default ''"
		),
		'url'    => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['url'],
			'inputType' => 'text',
			'exclude'   => true,
			'eval'      => array(
				'tl_class' => 'w50'
			),
			'sql'       => "text NULL"
		),
		'path'    => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['path'],
			'inputType' => 'fileTree',
			'exclude'   => true,
			'sql'       => "text NULL"
		),
		'youtubeShowSuggestions'    => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['youtubeShowSuggestions'],
			'inputType' => 'checkbox',
			'exclude'   => true,
			'eval'      => array(
				'tl_class' => 'w50 m12'
			),
			'sql'       => "char(1) NOT NULL default ''"
		),
		'youtubeHttps'    => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['youtubeHttps'],
			'inputType' => 'checkbox',
			'exclude'   => true,
			'eval'      => array(
				'tl_class' => 'w50 m12'
			),
			'sql'       => "char(1) NOT NULL default ''"
		),
		'youtubeExtendedDataSecurity'    => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['youtubeExtendedDataSecurity'],
			'inputType' => 'checkbox',
			'exclude'   => true,
			'eval'      => array(
				'tl_class' => 'w50 m12'
			),
			'sql'       => "char(1) NOT NULL default ''"
		),
		'defineSize'    => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['defineSize'],
			'default'   => 'predefined',
			'inputType' => 'select',
			'exclude'   => true,
			'options'   => array('predefined', 'custom'),
			'reference' => &$GLOBALS['TL_LANG']['tl_screencast'],
			'eval'      => array(
				'submitOnChange' => true,
				'tl_class'       => 'clr w50 m12'
			),
			'sql'       => "varchar(12) NOT NULL default ''"
		),
		'sizeCustom'    => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['sizeCustom'],
			'inputType' => 'text',
			'exclude'   => true,
			'eval'      => array(
				'multiple' => true,
				'size'     => 2,
				'tl_class' => 'clr w50'
			),
			'sql'       => "varchar(255) NOT NULL default ''"
		),
			'sizePredefined'    => array
		(
			'label'     => &$GLOBALS['TL_LANG']['tl_screencast']['sizePredefined'],
			'inputType' => 'radio',
			'exclude'   => true,
			options 	=> array('640x480', '854x480'),
			'eval'      => array(
				'multiple' => true,
				'size'     => 2,
				'tl_class' => 'clr w50'
			),
			'sql'       => "varchar(12) NOT NULL default ''"
		),
	)
);

Ich habe hier jetzt das komplette Ende der DCA-Datei aufgeführt, damit evtl. Tipp-, Klammerfehler o.ä. vermieden werden.

Die Beziehung zwischen den Paletten und den Feldern

Wer sein Augenmerk auf die Eigenschaft options der Felder type und platform richtet, wird feststellen, dass an dieser Stelle die Werte für den Aufruf der entsprechenden Paletten definiert werden.

Die Beziehung zwischen den Subpaletten und den Feldern

Bei den Subpaletten ist das ein klein wenig anders (wenigsten bei select-Feldern und radio-Buttons). Das Feld defineSize ist ein Select-Feld, welches als options die Werte predefined und custom erhält. Um je nach Auswahl die Paletten wechseln zu lassen, müssen diese Werte in der Definition der Subpalettes als Suffix an den aufrufenden Feldnamen angehängt werden. Bei checkboxen reicht der direkte Verweis auf das neue Feld. Schaut da z.B. mal in die DCA tl_news.php. Dort sieht man das ganz schön.


Was fehlt?

Die Erweiterung der Klasse ModuleScreencastList.php. Das überlasse ich erstmal euch.

Ausblick

Sobald Tristan einen neuen Screencast zum Thema bringt, haue ich wieder in die Tasten. Grüße von kobajashi

Weiterführende Links

Die Erweiterung Metapallets http://de.contaowiki.org/MetaPalettes


Ansichten
Meine Werkzeuge

Contao Community Documentation

God: "what is your job?"
me: "i am a software developer ... i develop websites with Contao 3"
God: "sounds cool, what are you working on today? Web sockets? Ajax? HTML5 video streaming?"
me: "no, i am trying to send an email ...."

Leo Unglaub
Navigation
Verstehen
Verwenden
Entwickeln
Verschiedenes
Werkzeuge