Die attach Elemente der erweiterten Blöcke können weiter erweitert werden, um komplexe dynamische Blöcke zu erstellen.
Der Wert für item kann dabei mit einem @ vorangestellt ein relativer Pfad zu einem Template sein. Hier ein Beispiel mit Bootstrap 5:
{
"blocks": {
"foobar": {
"title": "Dynamischer Block",
"controls": [{
"title": "Preis",
"type": "attach",
"name": "foobar",
"elements": [{
"selector": ".items",
"item": "@blocks/attach/foobar.tpl"
}]
}]
}
}
}
Der Pfad in item, in dem die Templates für attach Elemente abgelegt sind, ist frei wählbar.
Das HTML des Blocks foobar sieht wie folgt aus (blocks/foobar.tpl). Zu beachten ist, dass das DIV Element mit der CSS Klasse items leer ist:
<section class="mt-md-7 mt-5 pricing">
<div class="container">
<div class="mx-3 mb-3 border-radius-xl pricing-image bg-gradient-dark">
<div class="container pb-lg-9 pb-10 pt-7 position-relative z-index-0">
<span class="mask bg-gradient-dark opacity-6 border-radius-xl"></span>
<div class="row z-index-1 position-relative">
<div class="col-md-6 text-white mx-auto text-center pt-3 extra-value">
{value var="title1" type="text" title="Überschrift" wrapper="<h2><%></h2>"}
{value var="content1" type="content" title="Inhalt"}
</div>
</div>
</div>
</div>
<div class="mt-n10">
<div class="container">
<div class="row my-7 items"></div>
</div>
</div>
</div>
</section>
Das HTML des eingebundenen attach Templates sieht wie folgt aus (blocks/attach/foobar.tpl):
<div class="col-lg mb-lg-0 mb-4">
<div class="card shadow-lg">
<span class="badge bg-light text-dark w-30 mt-n2 mx-auto">{value var="title" type="text" title="Bezeichnung" default="Bezeichnung"}</span>
<div class="card-header text-center pt-4 pb-3">
<h1 class="font-weight-bold mt-2 d-inline-block">
{value var="number" type="text" title="?" default="-"}
<small class="text-lg d-inline-block">{value var="unit" type="text" title="€" default="€"}</small>
</h1>
</div>
<div class="card-body text-lg-start text-center pt-0{if $highlight} text-white{/if}">
{value var="content" type="content" title="Argumente"}
{value var="link" type="link" title="Link" attr.class="btn btn-icon bg-gradient-dark d-lg-block mt-3 mb-0"}
</div>
</div>
</div>
Das Einfügen dieses Blocks erzeugt einen Bereich, in welchem Überschrift und Inhalt gesetzt werden können. Darunter sind beliebig viele weitere Elemente platziert, die ebenfalls über unterschiedliche Eingabe Möglichkeiten verfügen.
Wird für item ein Template verwendet, entfällt die Eigenschaft values und die Platzhalter, wie <%>. Stattdessen können im Template beliebige {value} Elemente gesetzt werden.
In diesem attach Template gibt es zusätzlich zu den bekannten Smarty Variablen nun auch die Variable $_element. Diese beinhaltet als Array alle Informationen, die für dieses Element relevant sind. Da man für den Block auch mehrere attach Elemente definieren kann, wird der Wert für name des Elements als Schlüssel in diesem Array verwendet, um gezielt die Informationen für dieses Element abzufragen:
{$_element.foobar|@var_dump}
Neben den Werten für alle {value} Elemente in diesem attach Template, finden Sie immer folgende Variablen:
- index: Nummerierung dieses Elements (beginnend bei 0).
- count: Anzahl aller Elemente.
Zum Beispiel:
{$_element.foobar.index} von {$_element.foobar.count}
Über die Block Toolbar können nun beliebig viele Elemente hinzugefügt oder entfernt werden.
Es ist weiter auch möglich, über die Block Einstellungen für die einzelnen Elemente weitere Einstellungen zu treffen. Dafür wird die conf.json entsprechend erweitert:
{
"blocks": {
"foobar": {
"title": "Dynamischer Block",
"controls": [{
"title": "Preis",
"type": "attach",
"name": "foobar",
"elements": [{
"selector": ".items",
"item": "@blocks/attach/foobar.tpl"
}]
}, {
"title": "Einstellungen",
"type": "conf",
"tpl_name": "admin/blockconf/foobar.tpl"
}]
}
}
}
Das Template sieht wie folgt aus:
{elements name="foobar"}
{input type="checkbox" name="highlight" title="Hervorheben"}
{/elements}
Es wird empfohlen den Smarty Block {elements} zu verwenden. Dieser generiert mit allen beinhalteten Input Plugins für jedes attach Element einen Tab in einem Tab Container. Der Parameter name gibt hierbei an, um welches attach Element es sich handelt.
Und erzeugt mit den entsprechenden Änderungen am attach Template folgende Ausgabe (man beachte den Einsatz von $_element.foobar.highlight):
<div class="col-lg mb-lg-0 mb-4">
<div class="card shadow-lg{if $_element.foobar.highlight} bg-gradient-dark{/if}">
<span class="badge{if $_element.foobar.highlight} bg-primary{else} bg-light text-dark{/if} w-30 mt-n2 mx-auto">{value var="title" type="text" title="Bezeichnung" default="Bezeichnung"}</span>
<div class="card-header text-center pt-4 pb-3{if $_element.foobar.highlight} bg-transparent{/if}">
<h1 class="font-weight-bold mt-2 d-inline-block{if $_element.foobar.highlight} text-white{/if}">
{value var="number" type="text" title="?" default="-"}
<small class="text-lg d-inline-block">{value var="unit" type="text" title="€" default="€"}</small>
</h1>
</div>
<div class="card-body text-lg-start text-center pt-0{if $_element.foobar.highlight} text-white{/if}">
{value var="content" type="content" title="Argumente"}
{capture assign="class"}btn btn-icon{if $_element.foobar.highlight} bg-gradient-primary{else} bg-gradient-dark{/if} d-lg-block mt-3 mb-0{/capture}
{value var="link" type="link" title="Link" attr.class=$class}
</div>
</div>
</div>
Die Bezeichnungen der generierten Tabs lauten standardmäßig Element mit der jeweiligen Position des Elements (z.B. Element 1). Diese kann dynamisch erzeugt werden. Dafür muss die Eigenschaft label gesetzt werden, die über den Wert für value die Bezeichnug bestimmt. Dieser Wert kann ein beliebiger Wert sein, der optional mit dem Platzhalter <#> für die Position des jeweiligen Elements ergänzt werden kann. z.B.
{
"blocks": {
"foobar": {
"title": "Dynamischer Block",
"controls": [{
"title": "Preis",
"type": "attach",
"name": "foobar",
"label": {
"value": "LABEL <#>"
},
"elements": [{
"selector": ".items",
"item": "@blocks/attach/foobar.tpl"
}]
}, {
"title": "Einstellungen",
"type": "conf",
"tpl_name": "admin/blockconf/foobar.tpl"
}]
}
}
}
Verwenden Sie stattdessen einen Wert, der mit einem = Zeichen beginnt, um den eingestellten {value} Wert im Template zu verwenden. Hierbei wird nach dem = Zeichen die Variablen-Bezeichnung gesetzt. z.B.:
{
"blocks": {
"foobar": {
"title": "Dynamischer Block",
"controls": [{
"title": "Preis",
"type": "attach",
"name": "foobar",
"label": {
"value": "=title"
},
"elements": [{
"selector": ".items",
"item": "@blocks/attach/foobar.tpl"
}]
}, {
"title": "Einstellungen",
"type": "conf",
"tpl_name": "admin/blockconf/foobar.tpl"
}]
}
}
}
Geben Sie zudem einen Wert für default an, um diesen Text anzuzeigen, wenn es für das {value} keinen Wert geben sollte. Auch hier kann der Platzhalter <#> für die Position des Elements verwendet werden. z.B.:
{
"blocks": {
"foobar": {
"title": "Dynamischer Block",
"controls": [{
"title": "Preis",
"type": "attach",
"name": "foobar",
"label": {
"value": "=title",
"default": "LABEL <#>"
},
"elements": [{
"selector": ".items",
"item": "@blocks/attach/foobar.tpl"
}]
}, {
"title": "Einstellungen",
"type": "conf",
"tpl_name": "admin/blockconf/foobar.tpl"
}]
}
}
}
Innerhalb des Smarty Blocks {elements} sind Input Plugins mit den Bezeichnungen index und count zu vermeiden. Diese werden automatisch im attach Template gesetzt.
Auch sollten die Bezeichnungen der Input Plugins mit keinen anderen {value} Elementen im attach Template kollidieren, wobei man dann die Möglichkeit hätte, diese {value} Elemente zusätzlich auch in den Block Einstellungen zu ändern.
Weitere controls Typen wie option oder color sind ebenfalls kombinierbar. Dazu wird die conf.json entsprechend erweitert:
{
"blocks": {
"foobar": {
"title": "Dynamischer Block",
"controls": [{
"title": "Icon <#>",
"type": "option",
"name": "icon",
"attach": "foobar",
"selector": ".icon > i",
"value": "text-3xl mb-3 <%>",
"preset": "font-awesome-5"
}, {
"title": "Farbe <#>",
"type": "color",
"name": "color",
"attach": "foobar",
"selector": ".icon > i",
"attribute": "style",
"value": "color: <%>",
"preset": "basic"
}, {
"title": "Preis",
"type": "attach",
"name": "foobar",
"elements": [{
"selector": ".items",
"item": "@blocks/attach/foobar.tpl"
}]
}, {
"title": "Einstellungen",
"type": "conf",
"tpl_name": "admin/blockconf/foobar.tpl"
}]
}
}
}
Wichtig ist hierbei, dass Sie für diese controls Typen die Eigenschaft attach mit dem Namen des zugehörigen attach Elements setzen. Verwenden Sie zudem den Platzhalter <#> in title, um die Nummerierung des attach Elements anzuzeigen. Das System generiert je nach Anzahl an attach Elementen entsprechende Block Toolbar Elemente zum Auswählen der Icons/Farben.
Das attach Template wird nun entsprechend erweitert (man beachte das DIV Element mit der CSS Klasse icon):
<div class="col-lg mb-lg-0 mb-4">
<div class="card shadow-lg{if $_element.foobar.highlight} bg-gradient-dark{/if}">
<span class="badge{if $_element.foobar.highlight} bg-primary{else} bg-light text-dark{/if} w-30 mt-n2 mx-auto">{value var="title" type="text" title="Bezeichnung" default="Bezeichnung"}</span>
<div class="card-header text-center pt-4 pb-3{if $_element.foobar.highlight} bg-transparent{/if}">
<h1 class="font-weight-bold mt-2 d-inline-block{if $_element.foobar.highlight} text-white{/if}">
{value var="number" type="text" title="?" default="-"}
<small class="text-lg d-inline-block">{value var="unit" type="text" title="€" default="€"}</small>
</h1>
</div>
<div class="card-body text-lg-start text-center pt-0{if $_element.foobar.highlight} text-white{/if}">
<div class="text-center my-4 icon">
<i class="{value var="icon" type="value" default="fas fa-paint-brush"}" style="{value var="color" type="value"}"></i>
</div>
{value var="content" type="content" title="Argumente"}
{capture assign="class"}btn btn-icon{if $_element.foobar.highlight} bg-gradient-primary{else} bg-gradient-dark{/if} d-lg-block mt-3 mb-0{/capture}
{value var="link" type="link" title="Link" attr.class=$class}
</div>
</div>
</div>
Und erzeugt folgende Ausgabe:
Weiter kann natürlich jede weitere Eigenschaft des attach Typen genutzt werden (wie z.B. max).
Der Einsatz von dynamischen Blöcken ermöglicht eine einfache und intuitiv zu bedienende Alternative zu erweiterbaren Block Elementen über die Block Einstellungen und wird als bevorzugte Lösung angesehen.