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.

So sieht eine Ansicht unserer fertigen Erweiterung aus:
T2 youtube.png

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-Quelle oder Lokale-Quelle.
  2. Hat er die Wahl getroffen, werden zusätzliche Optionen sichtbar.

1. Fall: Keine Quelle

Es werden keine zusätzlichen Optionen angezeigt.

2. Fall: Lokal

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

3. 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 Videos einzublenden, über HTTPS zu streamen, erweiterten Datenschutz zu aktivieren und die Größe anzugeben. Bei der Größe kann er zusätzlich zwischen zwei Optionen wählen: Vordefinierte Größe und individuelle Größe.

Bei "Vimeo" erhält er die Optionen die Video-URL einzutragen und eine Größe anzuwählen. Auch hier hat er bei der Größe zusätzlich die Wahl zwischen zwei Optionen: Vordefinierte Größe und individuelle Größe.

<--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.

Hier zwei Beispiele für wohlbekannte Paletten: Die der Inhaltselemente "Überschrift" und "Hyperlink". Unterschiedliche C3 Paletten

Paletten können sich aber nicht nur grundsätzlich (Überschrift, Hyperlink, News,...) sondern auch dynamisch innerhalb eines Moduls bzw. Elements unterscheiden:
Hier ein Beispiel für unterschiedliche Paletten unserer Extension "Screencast":
T2 mcPaletten.png

Subpaletten ergänzen Paletten um einzelne Felder. Subpaletten werden innerhalb eines Moduls oder Elements meist von mehreren Paletten gemeinsam verwendet.
Hier ein Beispiel für Anzeigeoptionen der Videos. Diese wird gemeinsam von der Palette Youtube und Vimeo verwendet:
T2 subPaletten.png

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 nun für die verschiedenen Anwendungsfälle unterschiedliche Eingabe- und Auswahlfelder nötig. Diese werden in den unterschiedlichen 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.

T2 pdefault.png

Die local Palette

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

T2 plocal.png

Die remote Palette

Die remote Palette zeigt sich dem User, wenn er im Bereich type die Auswahl remote trifft. T2 premote.png>

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.

T2 pyoutube.png

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.

T2 pvimeo.png

Die Subpalette defineSize

Die defineSize Subpalette ist eine Zusatzpalette, die angezeigt wird, wenn der User im Bereich type die Auswahl remote trifft, sich daraufhin im Feld Plattform für vimeo oder youtube entscheidet und dann noch eine Option zur Einstellung der Videogröße wählt. T2 subPaletten.png

Wozu dient dann __selector__?

Im Bereich palettes wird auch definiert, welche Felder überhaupt 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 bestimmte 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 eurer Erweiterung solltet ihr nun eine Typ-Auswahlmöglichkeit haben.

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

  • Tauscht euren Code im fields-Bereich mit folgendem 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('remote_youtube', 'remote_vimeo'),
			'reference' => &$GLOBALS['TL_LANG']['tl_screencast'],
			'eval'      => array(
				'includeBlankOption' => true,
				'submitOnChange'     => true,
				'mandatory'          => true,
				'tl_class'           => 'w50',
			),
			'sql'       => "varchar(20) 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 Subpaletten 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, die Ausgabe im template und die Übersetzung. 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 Metapalletes http://de.contaowiki.org/MetaPalettes

Ansichten
Meine Werkzeuge

Contao Community Documentation

Dann sollte da auch 3.1.5 stehen. Wenn nicht mach mal Systemwartung, dreh dich im Kreis, ruf: "uga uga uga" und opfer ein kleines huhn... aber nur ein KLEINES, ist ja kein major.

Marc Reimann
Navigation
Verstehen
Verwenden
Entwickeln
Verschiedenes
Werkzeuge