Operationen

Die Template-Engine unterstützt einige Manipulationen, die es dem Designer erlauben mit Hilfe von data- Attributen Operationen zu definieren. Der Teil nach dem data- ist hierbei der Name der Operation. Der Webdesigner kann eine valide HTML5 Datei mit Beispieldaten erzeugen. Dies kann in einem zweiten Arbeitsschritt mit einer Brücke zu den Daten versehen werden.

<div data-[OPERATION]=""></div>

Eine konkrete Operation ist das Ersetzen von Werten in einem Tag mittels data-replace.

<div data-replace="auto"></div>

Der Zugriff auf die Daten kann mittels der folgenden Zugriffsmethoden erfolgen.

Schlüsselwort Aufruf Beschreibung Beispiel
dataset dataset:key:[default] Als Wert wird der Eintrag mit dem Schlüssel key aus dem Dataset genommen. Wird kein Wert mit diesem Schlüssel gefunden, so wird der optionale Defaultwert genommen data-repace="dataset:index:the default"
static static:content Der Inhalt content wird als statischer Inhalt verwendet. data-replace="static:my title"

Der Schlüssel key kann hierarchisch aufgebaut sein. Auf den letzten Datensatz in dem folgenden Beispiel kann man entweder über dataset:a | index:c | index:d oder über dataset:a.c.d zugreifen

+ a
| + b
| + c
| | + d => "Hallo Welt!"

Wenn es im Datensatz einen Wert mit dem gesamten Schlüssel gibt, so wird dieser genommen. In dem Beispiel ist das Ergebnis Frag mich! und nicht Hallo Welt!

+ a
| + b
| + c
| | + d => "Hallo Welt!"
+ a.c.d => "Frag mich!"

Syntax

Viele Operatoren unterstützen die Verarbeitung von Werten aus einem Dataset.

Pipes

Über die aus Unix bekannten Pipes, können die Daten nachfolgende Funktionen übergeben werden. Für unterschiedliche Datentypen stehen verschiedene Funktionen zur Verfügung.

Zeichenketten

Zeichenkettenoperationen erlauben die Manipulation von Zeichen. Mehrere Funktionen können mit einer Pipe verbunden werden. Das nachfolgende Beispiel ersetzt den Inhalt des p-Tags mit dem Text aus dem Dataset mit dem Index text, wandelt die Zeichen in Kleinbuchstaben um und führt ein trim durch.

<div>
  <p data-replace="dataset:text | strtolower | trim">placeholder</p>
</div>

Mit dem Wert My World im Dataset ist das Ergebnis dann:

<div>
  <p>my world</p>
</div>

Eine Liste der verfügbaren Operatoren ist hier verfügbar.

Doppelpunkt: Wird als Parameter einer Operation ein Doppelpunkt benötigt, so muss dieser mit vorangestelltem Backslash  definiert werden.

<div>
  <p data-replace="dataset:text | prefix:\:">placeholder</p>
</div>

Leezeichen: Will man zum Beispiel beim prefix- ein Leerzeichen anfügen, so muss man das Leerzeichen mit einem Doppelpunkt abschliessen.

<div>
  <p data-replace="dataset:text | prefix:  :">placeholder</p>
</div>

Collections

Operationen für Collection erlauben den Zugriff auf spezifische Einträge einer Collection.

<div>
  <a data-attributes="href dataset:url | index:2 | strtolower, title string:Mein Titel | trim">My World</a>
</div>

Eine Liste der verfügbaren Operatoren für Collections ist hier verfügbar.

Maps

Operationen für Maps erlauben den Zugriff auf spezifische Einträge einer Map.

<div>
  <a data-attributes="href dataset:url | index:name | strtolower, title string:Mein Titel | trim">My World</a>
</div>

Eine Liste der verfügbaren Operatoren für Collections ist hier verfügbar.

Standard Operationen

Standardoperationen sind direkt in der Komponente implementiert und stehen bei der Verwendung der Komponete sofort zur Verfügung. Die Reihenfolge der Attribute ist von Links nach rechts.

Achtung

Wird zuerst eine replace und dann ein repeat Operation definiert, kann replace nicht auf die Iteration von repeat zugreifen.

Die beiden Definitionen sind unterschiedlich:

<!-- Falsch: In dem Beispiel kann data-replace nicht auf myindex zugreifen -->
<div data-replace="dataset:myindex" data-repeat="myindex dataset:list"></div> 

<!-- Richtig: In der Definition kann replace auf myindex zugreifen -->
<div data-repeat="myindex dataset:list" data-replace="dataset:myindex"></div> 

Ersetzen (data-replace)

Die einfachste Operation ist das Ersetzen des Inhaltes einer Node mit einem statischen Wert.

$html = <<<EOF
<div>
  <p data-replace="static:myurl">empty</p>
</div>
EOF;

echo (new \Alvine\Markup\Html\Engine())
    ->getHTML($html);
return;

ergibt folgende Ausgabe

<div>
  <p>myurl</p>
</div>

Neben dem Ersetzen von statischen Werten können die Werte aus einem Dataset ersetzt werden. Dazu muss der Engine ein Dataset übergeben werden.

$html = <<<EOF
<div>
  <p data-replace="dataset:url">url</p>
</div>
EOF;

echo (new \Alvine\Markup\Html\Engine())
    ->setDataset((new \Alvine\Markup\Html\Dataset)
        ->setValue('url', new \Alvine\Net\Resource\URI('http://www.example.com')))
    ->getHTML($html);

ergibt folgende Ausgabe

<div>
  <p>http://www.example.com</p>
</div>

Ersetzen inklusive des Tags (data-replaceself)

Beim Ersetzen einschließlich des Tags wird der Tag und alle Kinder und Inhalt durch den zu ersetzenden Inhalt ersetzt.

$html = <<<EOF
<div>
  <p data-replaceself="static:myurl">empty</p>
</div>
EOF;

echo (new \Alvine\Markup\Html\Engine())
    ->getHTML($html);

ergibt folgende Ausgabe

<div>
  myurl
</div>

Wie man sieht, wird bei replaceself der Ausgangstag ebenfalls ersetzt. Dies ist nützlich, wenn man eine Markierung einfügen möchte, die aber im finalen HTML nicht erscheinen soll.

Node Entfernen (data-remove)

Möchte man einzelne Nodes entfernen, so kann man das Attribute data-remove einsetzen.

$html = <<<EOF
<div>
  <p data-remove>empty</p>
</div>
EOF;

echo (new \Alvine\Markup\Html\Engine())
    ->getHTML($html);

ergibt folgende Ausgabe

<div>

</div>

Wie man sieht, wird der komplette Tag inklusive Inhalt entfernt.

Tag entfernen (data-removetag)

Der Unterschied dieser Operation zu remove ist, dass der Inhalt des Tags erhalten bleibt.

$html = <<<EOF
<div>
  <p data-removetag>em<b>p</b>ty</p>
</div>
EOF;

echo (new \Alvine\Markup\Html\Engine())
    ->getHTML($html);

ergibt folgende Ausgabe

<div>
  em
    <b>p</b>
  ty
</div>

Wie man sieht wird der Ausgangstag ersetzt, aber der Inhalt bleibt erhalten.

Bedingtes anzeigen (data-condition)

Hinweis

Ein Element mit data-condition benötigt ein Elternelement.

Die Bedingung steuert, ob ein Tag ausgeblendet oder angezeigt wird. Der Tag wird entfernt, wenn das Ergebnis der Prüfung gleich false ist.

$html = <<<EOF
<div>
  <p data-condition="dataset:myindex | length | iszero">empty</p>
</div>
EOF;

echo (new \Alvine\Markup\Html\Engine())
    ->getHTML($html);

ergibt folgende Ausgabe, falls der Wert in myindex eine leere Zeichenkette ist.

<div>

</div>

Wie man sieht wird der Ausgangstag ersetzt, da kein Wert mit dem Index myindex vorhanden ist.

Eine weitere Möglichkeit der Prüfung ist mit isnull.

dataset:myindex | isnull | not
Wert Type Ausblenden Anzeigen
null Null isnull isnull | not
3 Integer iszero iszero | not
"3" Integer tointeger | iszero tointeger | iszero | not
4.5 Float tointeger | iszero tointeger | iszero | not
"test" string length | iszero length | iszero | not

Attribute setzen (data-attributes)

Mit der Attribut-Operation können die Attribute innerhalb eines Tags bearbeitet werden. Mit dem folgenden Beispiel.

/**
 * HTML-Template
 */
$html = <<<EOF
<div>
  <a data-attributes="href dataset:url">My World</a>
</div>
EOF;

/** 
 * Ausgabe
 */
echo (new \Alvine\Markup\Html\Engine())
    ->setDataset((new \Alvine\Markup\Html\Dataset)
        ->setValue('url', new \Alvine\Net\Resource\URI('http://www.example.com')))
    ->getHTML($html);

wird dieses Ergebnis ausgegeben.

<div>
  <a href="http://www.example.com">My World</a>
</div>

Mehrere Attribute lassen sich durch ein Komma trennen. Wird der Wert für das Attribut im Dataset nicht gefunden (null) wird das Attribut nicht gesetzt.

<div>
  <a data-attributes="href dataset:url, title string:Mein Titel">My World</a>
</div>

Diese Anweisung ergibt

<div>
  <a href="http://www.example.com" title="Mein Titel">My World</a>
</div>

Wiederholung (data-repeat)

Mit Hilfe der Wiederholung lassen sich ganz Blöcke duplizieren und mit den Werten einer Collection füllen. Die im folgende HTML-Datei soll für jeden Datensatz in der Liste list ein Zeile erhalten. Die Anweisung bei der Iteration besteht aus zwei Bestandteilen: dem Schlüssel und der Collection. Über den Schlüssel (im Beispiel citty) wird die Variabel bei jedem Durchlauf angesprochen. Existiert bereits ein anderer Eintrag mit dem Namen so wird der bestehende überschrieben.

Hinweis

Ein Element mit data-repeat muss ein Elternelement haben.

<div>
    <table>
  <tr data-repeat="city dataset:list"> 
    <td data-replace="dataset:city">placeholder</td>   
  </tr>
    </table>
</div>

In PHP-Code sieht die Funktion folgendermaßen aus:

$html = <<<EOF
<div>
    <table>
  <tr data-repeat="city dataset:list"> 
    <td data-replace="dataset:city">placeholder</td>   
  </tr>
    </table>
</div>
EOF;

echo (new \Alvine\Markup\Html\Engine())
    ->setDataset((new \Alvine\Markup\Html\Dataset)
        ->setValue('list', (new \Alvine\Types\Collection())
            ->append(new \Alvine\Types\String('München'))
            ->append(new \Alvine\Types\String('Frankfurt'))
            ->append(new \Alvine\Net\Resource\URI('http://www.example.com'))
            ->append(new \Alvine\Types\String('Berlin'))))
    ->getHTML($html);

Das Ergebnis ist eine Tabelle mit 4 Zeilen.

<div>
    <table>  
      <tbody>  
        <tr><td>München</td></tr>
        <tr><td>Frankfurt</td></tr>
        <tr><td>http://www.example.com</td></tr>
        <tr><td>Berlin</td></tr>
      </tbody>
    </table>
</div>

An dem Beispiel sieht man auch gut, das andere Typen (die über eine __toString() Methode verfügen verwendet werden können. Wiederholung mit mehreren Werten (data-repeat)

<div>
    <table>
        <tr data-repeat="city dataset:list"> 
            <td data-replace="dataset:city | index:name">Musterstadt</td>
            <td data-replace="dataset:city | index:plz">12345</td> 
            <td data-replace="dataset:city | index:einwohner">98456</td>     
        </tr>
    </table>
</div>

...

$cityList=new \Alvine\Types\Collection();

$cityA=new \Alvine\Types\Map();
$cityA->setValue('name', 'München');
$cityA->setValue('plz', '80331');
$cityA->setValue('einwohner', '1365015');

$cityList->append($cityA);

$cityB=new \Alvine\Types\Map();
$cityB->setValue('name', 'Frankfurt');
$cityB->setValue('plz', '60311');
$cityB->setValue('einwohner', '691520');

$cityList->append($cityB);

$dataset=new \Alvine\Markup\Html\Dataset();
$dataset->setValue('list', $cityList);

$engine=new \Alvine\Markup\Html\Engine();
$engine->setDataset($dataset);

// Variable $template muss das HTML-Template als Zeichenkette enthalten
echo $engine->getHTML($template);

Das HTML-Ergebnis

<div>
    <table> 
        <tbody>
            <tr>
                <td>München</td>
                <td>80331</td>
                <td>1365015</td>
            </tr>
            <tr>
                <td>Frankfurt</td>
                <td>60311</td>
                <td>691520</td>
            </tr>
        </tbody>
    </table>
</div>

Sollen bestimmte Zeilen Einträge im Dataset nicht in der Wiederholung angeziegt werden, so kann eine Condition verwendet werden.

<div>
    <div data-repeat="city dataset:list" data-condition="dataset:city | index:visibility | isnull | not"></div>
</div> 

Nur wenn die Stadt im Dataset einen Eintrag visibility=true hat, wird der Eintrag angezeigt.

Die Reihenfolge der Tags ist wichtig. Das folgende Beispiel funktioniert nicht, da city nicht
im Dataset ist, solange das Repeat nicht verarbeitet wurde.

<div>
    <div data-condition="dataset:city | index:visibility | isnull | not" data-repeat="city dataset:list" ></div>
</div> 

Fehler anzeigen (data-debug)

Der Unterschied dieser Operation zu remove ist, dass der Inhalt des Tags erhalten bleibt.

$html = <<<EOF
<div>
  <div data-debug></div>
</div>
EOF;

echo (new \Alvine\Markup\Html\Engine())
    ->getHTML($html);

Dieses Attribute fügt in das Ergebnis eine Liste mit den während des Parsens auftretenden Fehler an.

Eigene Operationen

Neben den in der Komponente verfügbaren Operationen können auch eigene Operationen integriert werden. Dazu muss man lediglich eine Klasse erstellen, die von AlvineMarkupHtmlAbstractOperation abgeleitet ist.

namespace My\Html;

class MyOperation extends \Alvine\Markup\Html\AbstractOperation {
    public static function process($value, \Alvine\Markup\Html\Node $element, \Alvine\Types\Map $map = null) {
        $element->setValue('My');
        return $element;
    }
}

In der HTML-Datei wird die Operation über die folgende HTML5 kompatible Struktur aufgerufen.

5a2462be-bd40-46ed-e1f1-3d1dc6f6cc1d