Spezielle Tags

Auf dieser Dokumentationsseite werden Funktionen des Frameworks besprochen die für spezielle Anwendungsfälle oder komplexere Designs verwendet werden können.

Bitte beachten Sie, dass innerhalb von Tag-Definitionen ausschließlich Leerzeichen eingesetzt werden dürfen. Tabs oder Zeilenumbrüche werden nicht erkannt und es kommt u.U. zu Fehlern beim Auslesen der Tag-Definitionen!

1. Iterator

Das Iterator-Tag hilft Ihnen die Ausgabe von Listen von Objekten oder assoziativen Arrays zu bewerkstelligen. Die Tag-Definition in einer Template-Datei definiert dabei die Formatierung der Ausgabe, die Daten erhält der Iterator im Controller.

1.1. Aufbau

Der Iterator-Tag ist wie folgt aufgebaut:

  • Der umschließende <html:iterator />-Tag definiert ein wiederverwendbares Fragment innerhalb eines APF-Templates. Der Iterator verhält sich dabei ähnlich wie der <html:template />-Tag. Dieser ist ebenfalls ein wiederverwendbares Element, das durch den Controller gesteuert bzw. zur Erzeugung der Ausgabe genutzt wird. Wird der Iterator im Controller nicht durch HtmlIteratorTag::transformOnPlace() zur Darstellung freigegeben oder die Ausgabe mit Hilfe der Methode HtmlIteratorTag::transformIterator() in einen Platzhalter eingesetzt, generiert er selbst keine Ausgabe.
  • Der <iterator:item />-Tag beschreibt das sich wiederholende Element innerhalb des Iterators. Innerhalb des Tags können beliebiger HTML-Code, Platzhalter und weitere Tags zur Ausgabe definiert werden.
  • Sofern gewünscht, können Sie den <iterator:fallback />-Tag nutzen, um eine elternative Ausgabe zu erzeugen, falls der Iterator keine Elemente zur Ausgabe vorfindet. Der Tag basiert auf dem <html:template />-Tag und besitzt daher alle Funktionalitäten, die Sie bereits kennen.
  • Der Bereich innerhalb des <html:iterator />- und ausserhalb des <iterator:item />-Tags kann für beliebigen HTML-Code sowie weitere Platzhalter und eigene Tags genutzt werden, die für die Ausgabe eingesetzt werden.

Die Definition des Tags gestaltet sich wie folgt:

APF-Template
<html:iterator name=""> ... [<iterator:addtaglib class="" prefix="" name="" />] [<iterator:getstring namespace="" config="" entry="" />] [<iterator:placeholder name="" />] ... <iterator:item [getter=""]> ... <item:placeholder[ name=""][ getter=""] /> [<item:getstring namespace="" config="" entry="" />] [<item:addtaglib class="" prefix="" name="" />] ... </iterator:item> ... [<iterator:fallback> ... [<fallback:placeholder name="" />] [<fallback:getstring namespace="" config="" entry="" />] [<fallback:addtaglib class="" prefix="" name="" />] ... </iterator:fallback>] ... </html:iterator>

Innerhalb eines <iterator:item />-Tags können beliebig viele Platzhalter (<item:placeholder />) und HTML-Elemente definiert werden.

Beschreibung der Attribute:
  • name (1): Name des Iterators. Wird zur Referenzierung innerhalb des Controllers benötigt. (Zeichen: [A-Za-z0-9])
  • getter: Name der Methode, mit der Attribute eines Objekts abgerufen werden können. (Zeichen: [A-Za-z0-9_])
  • name (2): Name des Platzhalters. (Zeichen: [A-Za-z0-9])

Details zur Verwendung des <iterator:item />- und <iterator:fallback />-Tags entnehmen Sie bitten den folgenden Kapiteln.

Für die Ausgabe von sprachabhängigen Werten können die Tags <iterator:getstring /> sowie <item:getstring /> verwendet werden. Diese funktionieren analog zum Tag <html:getstring />. Reicht die Funktionalität nicht aus, können per <iterator:addtaglib /> und <item:addtaglib /> eigene Taglibs analog zu <core:addtaglib /> eingebunden werden.

1.2. Definition der Datenstruktur

Der Iterator kann mit zwei Arten von Inhalten umgehen: assoziativen Arrays und Objekt-Listen. Aus Gründen der Flexibilität bei der Erstellung des Templates innerhalb des <iterator:item />-Tags empfiehlt sich die Nutzung von Objekt-Listen (siehe Kapitel 1.2.2).

1.2.1. Assoziative Arrays
Bitte beachten Sie, dass der Array-Zugriff mit Hilfe der erweiterten Template-Syntax erst in der Version 2.1 verfügbar ist.

Zur Ausgabe von Listen beherrscht der Iterator die Verarbeitung von assoziativen Arrays als Daten-Strukturen für ein <iterator:item />. Zur Ausgabe einer Produkt-Liste der Form

APF-Template
<html:iterator name="products-list-simple"> <h2>Produkte</h2> <p> Die folgende Liste stellt unsere Produkte dar: </p> <ul> <iterator:item> <li> <h3><item:placeholder name="name" /></h3> <img src="<item:placeholder name="img" />" /> <span><item:placeholder name="price" /></span> </li> </iterator:item> </ul> </html:iterator>

erwartet der Iterator folgende Datenstruktur:

PHP-Code
class IteratorTestController extends BaseDocumentController { public function transformContent() { $data = [ [ 'name' => 'Günstiges Mobiltelefon', 'price' => '150€', 'img' => 'cheapo.png' ], [ 'name' => 'Mittelklasse Mobiltelefon', 'price' => '350€', 'img' => 'mid-range.png' ], [ 'name' => 'Premium Mobiltelefon', 'price' => '550€', 'img' => 'premium.png' ] ]; $iterator = &$this->getIterator('products-list-simple'); $iterator->fillDataContainer($data); $iterator->transformOnPlace(); } }
Bitte beachten Sie, dass der Iterator eine nummerische Liste von Inhalten erwartet, die dann als assoziatives Array ausgeprägt sind. Assoziative Listen mit wiederum assoziativen Inhalten können nicht verarbeitet werden.

Die Methode fillDataContainer() liefert die Instanz des gewünschten Iterators zurück, der im Dokument definiert wurde, mit Hilfe von transformOnPlace() wird der Iterator dargestellt.

Die innerhalb des <iterator:item />-Tag definierten Platzhalter (z.B. <item:placeholder name="name" />) referenzieren auf die in der Datenstruktur enthaltenen Werte. Der Name des Schlüssels muss dabei mit den Wert des Attributs name übereinstimmen. Nicht gefundene Werte werden mit null ersetzt.

Neben der klassichen Definition von Platzhaltern lässt sich im <iterator:item />-Tag auch die erweiterte Template-Syntax zur Definition von Platzhaltern einsetzen:

APF-Template
<html:iterator name="products-list-simple"> <h2>Produkte</h2> <p> Die folgende Liste stellt unsere Produkte dar: </p> <ul> <iterator:item> <li> <h3>${name}</h3> <img src="${img}" /> <span>${price}</span> </li> </iterator:item> </ul> </html:iterator>

Details entnehmen Sie bitte dem Kapitel Templates.

Im Rahmen der erweiterten Template-Syntax können Sie auf die Inhalten eines Arrays innerhalb eines Schleifen-Durchlaufs auch wie folgt zugreifen:
APF-Template
<iterator:item> <li> <h3>${item['name']}</h3> <img src="${item['img']}" /> <span>${item['price']}</span> </li> </iterator:item>
Der Iterator stellt dazu das aktuell Objekt im Data-Attribut item zur Verfügung. Mischformen aller drei Varianten (klassiche Platzhalter, Platzhalter nach der erweiterten Template-Syntax und Array-Zugriffe) sind ebenfalls zulässig.
1.2.2. Objekt-Listen
Bitte beachten Sie, dass der Objekt-Zugriff mit Hilfe der erweiterten Template-Syntax erst in der Version 2.1 verfügbar ist.

Der Zugriff auf Objekt-Listen verhält sich sehr ähnlich wie der im Kapitel 1.2.1 beschrieben Modell. Unterschied ist dabei, dass es sich beim Inhalt der Listen um Instanzen von beliebigen Objekten handelt.

Zur Ausgabe einer Produkt-Liste der Form

APF-Template
<html:iterator name="products-list-objects"> <h2>Produkte</h2> <p> Die folgende Liste stellt unsere Produkte dar: </p> <ul> <iterator:item> <li> <h3><item:placeholder getter="getName" /></h3> <img src="<item:placeholder getter="getImg" />" /> <span><item:placeholder getter="getPrice" /></span> </li> </iterator:item> </ul> </html:iterator>

erwartet der Iterator folgende Datenstruktur:

PHP-Code
class Article { private $name; private $price; private $img; public function __construct($name, $price, $img) { $this->name = $name; $this->price = $price; $this->img = $img; } public function getImg() { return $this->img; } public function getName() { return $this->name; } public function getPrice() { return $this->price; } } class IteratorTestController extends BaseDocumentController { public function transformContent() { $data = [ new Article('Günstiges Mobiltelefon', '150€', 'cheapo.png'), new Article('Mittelklasse Mobiltelefon', '350€', 'mid-range.png'), new Article('Premium Mobiltelefon', '550€', 'premium.png') ]; $iterator = &$this->getIterator('products-list-objects'); $iterator->fillDataContainer($data); $iterator->transformOnPlace(); } }
Bitte beachten Sie, dass der Iterator eine nummerische Liste von Objekten erwartet. Assoziative Listen mit Objekt-Inhalten können nicht verarbeitet werden.

Die Methode fillDataContainer() liefert die Instanz des gewünschten Iterators zurück, der im Dokument definiert wurde, mit Hilfe von transformOnPlace() wird der Iterator dargestellt.

Die innerhalb des <iterator:item />-Tag definierten Platzhalter (z.B. <item:placeholder getter="name" />) referenzieren auf die in den Objekten enthaltenen Werte. Der Name der Methode wird im Attribut getter definiert. Nicht gefundene Methoden führen zu einer Exception.

Das Auslesen eines Attributes eines Objektes kann auf zwei Arten stattfinden:

  • Auf Ebene des <iterator:item/>-Tag wird eine für alle Platzhalter gültige Methode definiert. Ist das der Fall, kann innerhalb des <item:placeholder/>-Tags über das Attribut name der Name des Attributes angegeben werden, über den die Eigenschaft des Objekts referenziert wird. Beispiel:
    APF-Template
    <html:iterator name="..."> <iterator:item getter="getProperty"> <item:placeholder name="DisplayName" /> </iterator:item> </html:iterator>
    In dieser Konstellation erwartet das Tag, dass das auszugebende Objekt eine Methode
    PHP-Code
    public function getProperty($name)
    implementiert, die den Wert des Attributes (hier DisplayName) zurück liefert. Dies ist das Standard-Verhalten in allen Releases vor 1.14.
  • Ist keine generische Methode für das Abrufen von Objekt-Eigenschaften vorhanden, kann diese auf der Ebene des <item:placeholder/>-Tag granular für jeden Platzhalter definiert werden. Beispiel:
    APF-Template
    <html:iterator name="..."> <iterator:item> <item:placeholder getter="getDisplayName" /> </iterator:item> </html:iterator>
    In dieser Konstellation erwartet das Tag, dass das auszugebende Objekt eine Methode
    PHP-Code
    public function getDisplayName()
    implementiert, die den Wert des Attributes zurück liefert.
Eine Mischung der der beiden Varianten ist ebenso möglich. Sollte sowohl eine generische als auch eine dedizierte Getter-Methode definiert sein, so wird die lokale bevorzugt.
Im Rahmen der erweiterten Template-Syntax können Sie auf die Inhalten der Objekte innerhalb eines Schleifen-Durchlaufs auch wie folgt zugreifen:
APF-Template
<iterator:item> <li> <h3>${item->getName()}</h3> <img src="${item->getImg()}" /> <span>${item->getPrice()}</span> </li> </iterator:item>
Der Iterator stellt dazu das aktuell Objekt im Data-Attribut item zur Verfügung. Mischformen der drei Varianten (generische Getter, konkrete Getter und Objekt-Zugriff nach der erweiterten Template-Syntax) sind ebenfalls zulässig.

1.3. Anwendung

1.3.1. Einbindung im Template

Um den Iterator verwenden zu können muss der Tag zunächst im aktuellen Temlate bakannt gemacht werden. Dies können Sie wie folgt erledigen:

APF-Template
<core:addtaglib class="APF\tools\html\taglib\HtmlIteratorTag" prefix="html" name="iterator" />

In einem Document-Controller stehen Ihnen dann folgende Methoden zur Verfügung, mit der Sie den Iterator nutzen lässt:

PHP-Code
class ListController extends BaseDocumentController { public function transformContent() { // Iterator aus dem aktuellen Dokument beziehen $iterator = &$this->getIterator('...'); // Daten an den Iterator übergeben (Liste mit assoziativen Arrays oder Objekten) $iterator->fillDataContainer(array( ... )); // Ausgeben des Iterators wo er im Template definiert wurde, ... $iterator->transformOnPlace(); // ... oder den Inhalt in einen Platzhalter einsetzen $this->setPlaceHolder('...', $iterator->transformIterator()); } }
1.3.2. Nummerierung von Listen

Sollen die Einträge einer Liste bzw. Tabelle nummeriert werden, können Sie innerhalb eines <iterator:item />-Tags einen Platzhalter definieren der den Namen IterationNumber trägt. Beispiel:

APF-Template
<html:iterator name=""> <iterator:item [getter=""]> <item:placeholder name="IterationNumber"> </iterator:item> </html:iterator>

Bei Bedarf kann sie Start-Position der Zählvariable kann im Controller manipuliert werden. Hierzu lässt sich die Methode HtmlIteratorTag::setIterationNumber() nutzen:

PHP-Code
class ListController extends BaseDocumentController { public function transformContent() { $iterator = &$this->getIterator('...'); $iterator->fillDataContainer(array( ... )); $iterator->setIterationNumber(5); $iterator->transformOnPlace(); } }

Zu weiteren Optionen der Manipulation, ziehen Sie bitte Kapitel 1.3.3 zu Rate.

Die Definition des Platzhalters IterationNumber kann sowohl in klassischer Form über einen <item:placeholder />-Tag als auch mit der erweiterten Templating-Syntax erfolgen.
1.3.3. Nutzung des Pagers

Nutzt man das Iterator-Tag in Verbindung mit dem Pager, sollte die Nummerierung auf einer anderen Seite nicht wieder bei 1 beginnen, sondern fortgesetzt werden. Um dies zu erreichen, muss für den <html:iterator />-Tag das Attribut pager definiert werden. Als Wert muss das pager-Attribut den Namen einer Sektion der Pager-Konfigurationsdatei erhalten.

Im folgenden Beispiel würde die Iterator-TagLib die Konfiguration /APF/config/modules/pager/{ENVIRONMENT}_pager.ini aufrufen und die Konfigurations-Werte der Sektion PagerExample verwenden:

APF-Template
<html:iterator name="" pager="PagerExample"> <iterator:item [getter=""]> <item:placeholder name="IterationNumber"> </iterator:item> </html:iterator>
1.3.4. Definition von Alternativ-Inhalten
Bitte beachten Sie, dass dieses Feature erst in der Version 2.1 verfügbar ist.

Bei der Ausgabe von Listen ist häufig auch die Darstellung eines Alternativ-Inhalts gefragt. Diesen Anwendungsfall unterstützt der Iterator über das <iterator:fallback />-Tag. Dieses wird ausgegeben, sofern dem Iterator keine Inhalte zur Ausgabe zur Verfügung stehen.

Zur Steuerung der Ausgabe stehen zwei Optionen zur Verfügung:

  • normal (Standard): der Alternativ-Inhalt wird zusätzlich zum übrigen HTML-Markup ausgegeben.
  • replace: der Alternativ-Inhalt ersetzt das übrige HTML-Markup vollständig.

Der Modus kann über da Attribut fallback-mode des <html:iterator />-Tag gesteuert werden.

Der folgende Code-Block zeigt die Ausgabe einer Produkt-Liste inkl. Alternativ-Inhalt:

APF-Template
<html:iterator name="products-list-simple" fallback-mode="replace"> <h2>Produkte</h2> <p> Die folgende Liste stellt unsere Produkte dar: </p> <ul> <iterator:item> <li> <h3><item:placeholder name="name" /></h3> <img src="<item:placeholder name="img" />" /> <span><item:placeholder name="price" /></span> </li> </iterator:item> </ul> <iterator:fallback> <h2>Keine Produkte verfügbar</h2> <p> Leider sind aktuell keine Produkte erhältlich. Bitte besuchen Sie uns in <fallback:placeholder name="count" /> Tagen wieder. </p> </iterator:fallback> </html:iterator>

Solange Produkte verfügbar sind, wird eine Liste von Produkten ausgegeben, sofern keine Produkte erhältlich sind, wird dir Liste durch den Alternativ-Inhalt ersetzt.

Die Alternativ-Inhalte lassen sich wie vom <html:template />-Tag gewohnt anpassen. Der folgende Code-Block zeigt Ihnen, wie Sie den Platzhalter im <iterator:fallback />-Tag mit der gewünschten Anzahl an Tagen füllen können:

PHP-Code
class ProductsController extends BaseDocumentController { public function transformContent() { $iterator = $this->getIterator('products-list-simple'); ... $fallback = &$iterator->getFallbackContent(); $fallback->setPlaceHolder('count', '3'); $iterator->transformOnPlace(); } }
1.3.5. Auswertung von Status-Variablen
Bitte beachten Sie, dass dieses Feature erst in der Version 2.1 verfügbar ist.

Der Iterator stellt für jeden Schleifen-Durchlauf mehrere Status-Variablen zur Verfügung. Diese können zur direkten Ausgabe genutzt werden oder in eigenen Tags ausgewertet werden. Die Informationen lassen sich über das Data-Attribut status abfragen, das eine Instanz der Klassen APF\tools\html\taglib\IteratorStatus beinhaltet. Dieses verfügt über folgende Methoden:

PHP-Code
class IteratorStatus { public function getCssClass() { return $this->cssClass; } public function isFirst($asString = false) { return $asString === false ? $this->isFirst : $this->convertToString($this->isFirst); } public function isLast($asString = false) { return $asString === false ? $this->isLast : $this->convertToString($this->isLast); } public function getItemCount() { return $this->itemCount; } public function getCounter() { return $this->counter; } }

Die Methoden lassen sich wie folgt für die Generierung der Ausgabe nutzen:

  • getCssClass(): liefert eine für den Schleifen-Durchlauf passende CSS-Klasse zur Formatierung zurück. Im Auslieferungszustand des APF erhalten Sie first für den ersten Eintrag, middle für die Folgenden und last für das letzte Element der Liste. Die Namen der CSS-Klassen können über die Attribute first-element-css-class, middle-element-css-class und last-element-css-class des <html:iterator /> an den jeweiligen Anwendungsfall angepasst werden.
  • isFirst(): liefert true, falls das aktuelle Element das erste in der Liste ist. Wird das optionale Argument mit dem Wert true belegt, liefert die Methode keinen boolean-Wert, sondern einen string, der sich - insbesondere für den Wert false - einfacher verarbeiten lässt (z.B. als Präfix/Suffix einer CSS-Klasse).
  • isLast(): liefert true für das letzte Element der Liste. Wird das optionale Argument mit dem Wert true belegt, liefert die Methode keinen boolean-Wert, sondern einen string, der sich - insbesondere für den Wert false - einfacher verarbeiten lässt (z.B. als Präfix/Suffix einer CSS-Klasse).
  • getItemCount(): liefert die Gesamt-Anzahl der Elemente in der Liste.
  • getCounter(): liefert eine fortlaufende Nummer zurück, die zur Beschriftung genutzt werden kann.

Das folgende Beispiel zeigt die Ausgabe einer Produkt-Liste, die das Status-Objekt zur Formatierung der Ausgabe nutzt:

APF-Template
<html:iterator name="products-list-objects-extended" first-element-css-class="prd-first separator" middle-element-css-class="prd-center" last-element-css-class="prd-last"> <h2>Produkte</h2> <p> Die folgende Liste stellt unsere Produkte dar: </p> <ul> <iterator:item> <li class="${status->getCssClass()}" data-item-count="${status->getItemCount()}" data-is-first="${status->isFirst(true)}" data-is-last="${status->isLast(true)}"> <h3>(${item->getCounter()}) ${item->getName()}</h3> <img src="${item->getImg()}" /> <span>${item->getPrice()}</span> </li> </iterator:item> </ul> </html:iterator>

Die entsprechende HTML-Ausgabe gestaltet sich daraus wie folgt (gekürzt):

APF-Template
<ul> <li class="prd-first separator" data-item-count="3" data-is-first="1" data-is-last="0"> <h3>Cheap mobile phone</h3> <img src="cheapo.png"/> <span>150€</span> </li> <li class="prd-center" data-item-count="3" data-is-first="0" data-is-last="0"> <h3>Mid-range mobile phone</h3> <img src="mid-range.png"/> <span>350€</span> </li> <li class="prd-last" data-item-count="3" data-is-first="0" data-is-last="1"> <h3>Premium mobile phone</h3> <img src="premium.png"/> <span>550€</span> </li> </ul>

2. Mediastream-Tags

Die Mediastream-Tags ermöglichen es dem Entwickler, Ressourcen zur Gestaltung der GUI direkt im Namespace des Moduls abzulegen und daraus auszuliefern. Hierzu stellt das Framework einerseits eine abstrakte TagLib-Implementierung und einige konkrete TagLibs zur Verfügung, die eine Medien-URL generieren, andererseite eine allgemeingültig verwendbare FrontController-Action, die die adressierten Medien ausliefert.

Um die Tags einsetzen zu können, muss sichergestellt sein, dass für die Action, die mit der Auslieferung betraut ist eine validie Konfiguration für den aktuellen Applikations-Kontext existiert. Die Konfiguration wird dabei unter

Code
/APF/config/tools/media/actions/{CONTEXT}/{ENVIRONMENT}_actionconfig.ini

erwartet. Der Inhalt der Datei kann der nachfolgenden Code-Box entnommen werden:

APF-Konfiguration
[streamMedia] ActionClass = "APF\tools\media\actions\StreamMediaAction"

Eine Beispieldatei findet sich ebenfalls in der apf-configpack-*-Release-Datei unter tools/media/actions/.

Für den konkreten Einsatz existieren bereits folgende TagLibs:

  • FormMediaInclusionTag: Einsatz innerhalb des <html:form />-Tags
  • MediaInclusionTag: Einsatz innerhalb einer Template-Datei
  • MediaInclusionTag: Einsatz innerhalb des <html:template />-Tags

Um das Tag einzusetzen, muss dieses im gewünschten Gültigkeitsbreich mit dem <*:importdesign />-Tag bekannt gemacht werden. Die folgende Code-Box zeigt die Anwendung innerhalb eines Formulars:

APF-Template
<core:addtaglib class="APF\tools\form\taglib\HtmlFormTag" prefix="html" name="form" /> <html:form name="TestFormular"> <form:addtaglib class="APF\tools\media\taglib\FormMediaInclusionTag" prefix="form" name="mediastream" /> <img src="<form:mediastream namespace="APF\modules\mymodule\pres\images" filename="phone_icon.png" />" alt="" /> <form:text name="phonenumber" /> <br /> <form:button name="send" value="Absenden" /> </html:form>

Wie dem Beispiel zu entnehmen ist, erwarten die <*:mediastream />-Tags folgende Attribute:

  • namespace: Namespace zur gewünschten Medien-Datei. (Zeichen:: [A-Za-z0-9:])
  • filename: Name der Medien-Datei. (Zeichen: [A-Za-z0-9_.-])
Möchten Sie den Namespace der auszuliefernden Datei zusätzlich beeinflussen um z.B. diese beispielsweise abhängig vom aktuellen Kontext ablegen zu können, so kann folgende Vorgehenweise gewählt werden:
  1. Ausstatten des Tags mit einer eindeutigen ID:
    APF-Template
    <core:addtaglib class="APF\tools\media\taglib\MediaInclusionTag" prefix="html" name="mediastream" /> <img src="<html:mediastream namespace="APF\modules\mymodule\pres\images" filename="phone_icon.png" id="PhoneIcon" />" alt="" />
  2. Manipulieren des Namespaces im Document-Controller:
    PHP-Code
    class ExampleController extends BaseDocumentController { public function transformContent(){ $mediaStreamTag = &$this->getMediaStreamTagByID('PhoneIcon'); $mediaStreamTag->setAttribute($mediaStreamTag->getAttribute('namespace').'\\'.$this->getContext()); } private function &getMediaStreamTagByID($id){ $children = &$this->getDocument()->getChildren(); foreach($children as $objectId => $DUMMY){ if(get_class($children[$objectId]) == 'MediaInclusionTag'){ return $children[$objectId]; } } throw new InvalidArgumentException('No media stream tag contained within the current document!'); } }
  3. Manipulation des Datei-Namens innerhalb eines Templates:
    PHP-Code
    class ExampleController extends BaseDocumentController { public function transformContent() { $FileTemplate = &$this->getTemplate('file'); $mediaStreamTag = &$this->getMediaStreamTagByID('FileIconID', $FileTemplate); $mediaStreamTag->setAttribute('extension', 'png'); $mediaStreamTag->setAttribute('filebody', 'dateinameOhneEndung'); } private function &getMediaStreamTagByID($id, TemplateTag &$template) { $children = &$template->getChildren(); foreach ($children as $objectId => $DUMMY) { if (get_class($children[$objectId]) == 'MediaInclusionTag' && $children[$objectId]->getAttribute('id') == $id ) { return $children[$objectId]; } } throw new InvalidArgumentException('No media stream tag contained within the current template "' . $template->getAttribute('name') . '"!'); } }

Die zur Auslieferung der Bilder eingesetzte Front-Controller-Action StreamMediaAction bietet die Möglichkeit, erlaubte Datei-Typen und deren MIME-Typen explizit zu konfigurieren. Damit ist es möglich die Standard-Werte zu überschreiben um weniger oder mehr Typen zuzulassen. Im Standard-Setup sind folgende Endungen erlaubt:

  • png bzw. image/png
  • jpeg bzw. image/jpg
  • jpg bzw. image/jpg
  • gif bzw. image/gif
  • css bzw. text/css
  • js bzw. text/javascript

Um die vorhandenen Werte neu zu definieren muss die Konfigurations-Datei {ENVIRONMENT}_allowed_extensions.ini unter dem Pfad APF\tools\media\{CONTEXT} angelegt werden. Die erlaubten Endungen können dann in der Form

APF-Konfiguration
[Default] jpg = "image/jpg" xml = "text/xml" psd = "application/psd"

definiert werden.

3. Generischer importdesign-Tag

In komplexeren Applikationen ist es oft notwendig, die durch <*:importdesign />-Tags definierten Views dynamisch füllen zu können. Vielfach möchte der Entwickler in aufwändigeren Strukturen die Informationen des Applikationsmodels verwenden. Um dies uneingeschränkt zu ermöglichen und eine Applikationssteuerung aus der Business-Schicht zu ermöglichen, wurde das Framework mit einem generischen importdesign-Tag ausgestattet, der es erlaubt sowohl den Namen des Templates aus auch den Namespace desselben dynamisch aus einem Model-Objekt zu beziehen.

Die Signatur des generischen Tags gestaltet sich dabei wie folgt:

APF-Template
<generic:importdesign model-class="" model-mode="NORMAL|SINGLETON|SESSIONSINGLETON" namespace-param="" template-param="" [get-method=""] [dependent-action-namespace="" dependent-action-name="" [dependent-action-params=""]] />
Den Attributen kommt dabei folgende Bedeutung zu:
  • model-class: Voll-qualifizierter Klassen-Name der Model-Klasse. (Zeichen: [A-Za-z0-9_\])
  • model-mode: Instanzierungsmodus des Models. (Erlaubte Werte: NORMAL|SINGLETON|SESSIONSINGLETON)
  • namespace-param: Name des Model-Parameters für den Template-Namespace. (Zeichen: [A-Za-z0-9_.-])
  • template-param: Name des Model-Parameters für den Template-Namen. (Zeichen: [A-Za-z0-9_.-])
  • get-method: Name der Mode-Methode mit dem die Parameter abgefragt werden können. Dieser wird der Wert des namespaceparam bzw. templateparam als Parameter übergeben und erwartet den zugehörigen Rückgabewert. Standardmäßig wird die Funktion getAttribute() verwendet. (Zeichen: [A-Za-z0-9_])
  • dependent-action-namespace / dependent-action-name / dependent-action-params: Die drei Optionen dienen dazu, eine abhängige Action automatisch beim Front-Controller zu registrieren. Dies ist vor Allem dann hilfreich, wenn ein Modul über das Tag eingebunden wird und eine Front-Controller-Action zur Steuerung der Navigation verwendet wird.
    Das Attribut dependent-action-namespace definiert den Namespace der Action (z.B. ACME\site\biz) und dependent-action-name den Namen/Alias der Action (z.B. Navigate). dependent-action-params beinhaltet die Parameter der Action in der Form param1:value1|param2:value2, wie aus dem URL-Layout des Front-Controllers bekannt.

Um das Tag anwenden zu könen, muss dieses zunächst via

APF-Template
<core:addtaglib class="APF\tools\html\taglib\GenericImportTemplateTag" prefix="generic" name="importdesign" />

im aktuellen Gültigkeitsbereich bekannt gemacht werden.

Hinweise:
  • Als Anwendungsbeispiel kann der Artikel Behind the site (englisch) herangezogen werden. Dieser beschreibt, wie die vorliegende Dokuentationswebseite aufgebaut ist und welche Mittel des Frameworks sie nutzt.
  • Soll eine Front-Controller-Action zu Navigationszwecken verwendet werden, so muss bei der Klassendefinition die Variable $keepInURL mit true initialisiert werden. Dies bewirkt, dass die Action bei der Link-Generierung mit dem LinkGenerator erfasst wird.
  • Die Registrierung der Action wird nur dann durchgeführt, wenn die Attribute dependent-action-namespace und dependent-action-name gefüllt sind und die Action noch nicht gegistriert ist. Die Angabe von Parametern ist optional.

4. core:appendnode-Tag

Aus einer Diskussion über wiederverwendbare Template-Fragmente (z.B. Formulare) entstand die Idee, eine TagLib zu entwerfen, die Inhalte aus einem beliebigen Template in den aktuellen Gültigkeitsbereich zu importieren. Durch die generische DOM-Struktur der GUI-Elemente des Frameworks ist dies auf sehr einfache Weise möglich.

Um die Funktion allgemeingültig zur Verfügung zu stellen, wurde im 1.8er-Zweig der <core:appendnode />-Tag hinzugefügt, der beliebige Templates "importieren" kann. Der Tag erwartet - ähnlich dem importdesign-Tag - die statischen Attribute namespace und template.

Ab Version 1.12 ist zusätzlich das Attribut includestatic verfügbar. Ist dieses vorhanden und auf den Wert true eingestellt, so wird sämtlicher Inhalt des inkludierten Templates übernommen. Enthält es einen anderen Wert oder ist nicht vorhanden, werden nur die aktuell im eingebundenen Template enthaltenen DOM-Knoten (Instanzen von Taglibs) übernommen.

4.1. Einbindung von Templates

Um ein wiederverwendbares Template einbinden zu können, muss das Tag im gewünschten Template wir folgt platziert werden:

APF-Template
<core:appendnode namespace="..." template="..." [includestatic="true" ]/>

Soll beispielweise ein Template zur Ausgabe eines Domänen-Objekts in mehreren View-Templates eingesetzt werden, so schickt es sich, dieses in einem eigenen Template (Namespace: APF\sites\testsite\pres\templates\generic; Template: generic_templates) zu definieren. Die Definition kann dabei folgende Gestalt haben:

APF-Template
<html:template name="ReusableTemplate"> ... <template:placeholder name="DisplayName"> ... </html:template>

Um das Template in einem anderen verwenden zu können, muss die Template-Datei wie folgt in die bestehende eingebunden werden:

APF-Template
<core:appendnode namespace="APF\sites\testsite\pres\templates\generic" template="generic_templates" />

4.2. Verwendung der Elemente

Die Verwendung der durch das <core:appendnode />-Tag eingebundenen Elements gestaltet sich identisch zur bisherigen Vorgehensweise, da die Elemente in den Gültigkeitsbereich des gewünschten Templates importiert werden. Damit können weiterhin die im Document-Controller zur Verfügung stehenden Methoden (z.B. getTemplate()) verwendet werden.

Das im Kapitel 4.1 aufgezeigte Template könn wie auch bisher mit

PHP-Code
$tmpl = &$this->getTemplate('ReusableTemplate');

adressiert werden.

4.3. Wichtige Hinweise

Das Parsen des eingebundenen Templates erfolgt identisch zu den per importdesign-Tag eingebundenen Template-Dateien. Das bedeutet, dass der Entwickler dafür Sorge tragen muss, dass die gewünschten Tags im eingebundenen Template auch erkannt werden.

Die <core:appendnode />-TagLib legt im Ursprungstemplate Marker-Tags an, damit die transformOnPlace()-Methoden genutzt werden können. Bitte beachten Sie, dass die eingebundenen Kinder in der Reihenfolge der Definition im zusätzlichen Template eingebunden werden!

Sofern auch statischer Inhalt des eingebundenen Templates wie z.B.

APF-Template
<div class="formattingContainer"> <html:template name="ReusableTemplate"> ... </html:template> </div>

übernommen werden soll, muss das Attribut includestatic auf den Wert true gestellt werden.

Kommentare

Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.
« 1   »
Einträge/Seite: | 5 | 10 | 15 | 20 |
1
Christian 06.12.2008, 22:47:46
Der Unterschied ist, dass der core:importdesign-Tag einen neues Kind im aktuellen DOM-Knoten erzeugt und seine Kinder verarbeitet, der core:appendnode-Tag bindet seine Kinder in den Vater-Knoten dein. Das bedeutet, dass die "eingepflanzten" Kinder im ursprünglichen Knoten wie "eigene" Kinder verwendet werden können.
So ist es möglich, Template-Fragmente ohne Kopieren wieder zu verwenden.
2
fliegermichl 17.11.2008, 11:06:51
Wo besteht der Unterschied zum core:importdesign Tag?