Tipps und Tricks
Bei diesen Tipps & Tricks wird davon ausgegangen, dass ein eigenes Child-Template angelegt wurde. Dies stellt unter anderem sicher, dass das entsprechende (Parent-)Template weiterhin updatefähig bleibt.
Note
Die JTL-Templates des Shops basieren auf leicht unterschiedlichen Technologien zur Seitendarstellung: Das NOVA-Template nutzt hierfür Sass (SCSS).
Sass/SCSS sind Erweiterungen der herkömmlichen CSS-Syntax und schaffen hauptsächlich die Möglichkeit, CSS ähnlich komfortabel zu schreiben wie Programm-Code. Diese Technologien setzen einen Pre-Prozessor voraus, um die jeweilige Style-Sprache in CSS zu übersetzen. Je nach Template und Shop-Version gibt es hierfür unterschiedliche Werkzeuge (siehe Abschnitt "Theme editieren").
SCSS
Mithilfe von SCSS können Sie verschiedene Werte für Farben, Schriften, Abstände und Rahmen als Variablen definieren, die dann in allen oder auch nur einigen Templates benutzt werden können. Um nun schnell und einfach das Aussehen von JTL-Shop zu verändern, bietet es sich an, diese SCSS-Variablen des Templates in einem Child-Template zu überschreiben.
Einen guten Anfang für ein neues NOVA-Child-Theme bietet das von JTL zur Verfügung gestellte NOVAChild-Template, welches alle nötigen Dateien mitbringt und bereits ein eigenes Theme anlegt ("my-nova"). Dieses Theme ändert jedoch noch nicht das Aussehen des Shops.
Javascript in Templatedateien
Jede Templatedatei (*.tpl
) wird von der Template-Engine Smarty
gelesen und interpretiert. Hierbei nutzt Smarty
für die Auszeichnungen von Variablen- und Code-Ersetzungen geschweifte Klammern ({
, }
). Geschweifte Klammern sind
aber ebenso in Javascript ein Sprachelement um beispielsweise Code-Blöcke zu umschließen.
Damit sich diese beiden unterschiedlichen Auszeichnungsarten nicht überschneiden, ist es möglich, Javascript-Code von
der Bearbeitung durch Smarty
auszuschließen. Hierfür existieren zwei unterschiedliche Ansätze.
Für kleinere Javascript-Codefragmente ist es möglich, alle öffnenden und schließenden geschweiften Klammern durch
zwei Smarty
-Funktionen zu ersetzen - {ldelim}
für {
und {rdelim}
für }
- und sie anschließend von Smarty
wieder als echte Klammern ausgeben zu lassen.
Beispiel:
Dies ist eine smarty.tpl Datei,<br>
die ein Javascript enthält.<br>
<script>
function helloWorld() {ldelim}
alert('Hello World');
{rdelim}
</script>
(Siehe auch: Smarty Docs ldelim,rdelim)
Für umfangreicheren Code empfehlen wir allerdings die übersichtlichere Variante mit den zwei Smarty-Tags {literal}
und {/literal}
. Mit diesen beiden Tags läßt sich ein größerer Javascript-Block ganz einfach umschließen und von der
Verarbeitung durch Smarty
ausschließen.
Beispiel:
Dies ist eine smarty.tpl Datei,<br>
die ein Javascript enthält.<br>
{literal}
<script>
function helloWorld() {
alert('Hello World');
}
</script>
{/literal}
(Siehe auch: Smarty Docs literal)
Möchten Sie in Ihrem Javascript weiterhin Variablen durch Smarty
ersetzen lassen, kann der literal
-Block auch vor
der Smarty
-Variable beendet und nach ihr wieder begonnen werden.
Beispiel:
Dies ist eine smarty.tpl Datei,<br>
die ein Javascript enthält.<br>
{literal}
<script>
function helloWorld() {
alert({/literal}'{$HelloWorldText}'{literal});
}
</script>
{/literal}
In diesem Fall hätten Sie zwei getrennte literal
-Blöcke, die Smarty
nicht interpretiert. Die Variable in der
Mitte wird dann wie gewohnt von Smarty
ersetzt.
Um Javascript automatisiert nachladen zu lassen und so den Pagespeed der Seite zu verbessern, bietet der Shop
ausserdem die Möglichkeit den Smarty-Block inline-script
zu verwenden.
Beispiel:
Dies ist eine smarty.tpl Datei,<br>
die ein Javascript enthält. Es wird automatisch beim Seitenaufruf nachgeladen (defer).<br>
{inline-script}
<script>
function helloWorld() {
alert('Hello World');
}
</script>
{/inline-script}
Theme-Variablen
Diese Variablen sind, soweit möglich, in einigen wenigen Dateien zusammengefasst.
Im NOVA-Template liegen sie im Ordner <Shop-Root>templates/NOVA/themes/<Theme>/sass/_variables.scss
.
Hint
Alle themerelevanten Variablen finden Sie in der _variables.scss
.
Sehen Sie sich diese Datei(en) an und probieren Sie es aus, einige Werte zu ändern.
Zum Teil werden auch aus dem zugrundeliegenden Bootstrap Regeln übernommen.
Merkmale abfragen
Merkmale dienen, auf der Artikeldetailseite, der Auflistung bestimmter Artikeleigenschaften wie z. B. der Farbe des Produktes. Merkmale werden in JTL-Wawi, pro Sprache, definiert.
Template-Code
im NOVA-Template: templates/NOVA/productdetails/attributes.tpl
:
{block name='productdetails-attributes-shop-attributes'}
{foreach $Artikel->Attribute as $Attribut}
<tr class="attr-custom">
<td class="h6">{$Attribut->cName}: </td>
<td class="attr-value">{$Attribut->cWert}</td>
</tr>
{/foreach}
{/block}
Der Zugriff ist auch über ein assoziatives Array möglich:
{assign var="attrname" value="Name des Funktionsattributes hier eintragen"}
{$Artikel->AttributeAssoc.$attrname}
Funktionsattribute
In JTL-Wawi können Sie in den Artikeldetails im Reiter "Attribute/Merkmale" sogenannte Funktionsattribute im Artikel hinterlegen. Anders als Artikelattribute (siehe vorheriger Abschnitt "Merkmale") werden Funktionsattribute nicht mehrsprachig definiert, da sie Funktionalitäten und Aktionen im Shop auslösen bzw. das Template steuern können. (Siehe auch: Beispielartikel mit Funktionsattributen im JTL-Demoshop)
Funktionsattribute am Artikel stehen templateseitig in den Artikeldetails als Variable zur Verfügung und können artikelbezogen im Frontend abgefragt werden.
Funktionsattribute können im Template per {$Artikel->FunktionsAttribute['funktionsattributname']}
ausgelesen werden.
("funktionsattributname" reflektiert hier den Namen des Funktionsattributes, wie es in JTL-Wawi definiert wurde)
Natürlich können Sie auch eigene Funktionsattribute in JTL-Wawi anlegen und diese im Shop-Template nutzen.
Attention
Schreiben Sie Funktionsattributnamen auch dann in Kleinbuchstaben, wenn deren Namen in JTL-Wawi Großbuchstaben enthalten.
Beispiel:
Sie möchten ein Funktionsattribut highlightclass
neu erstellen und abfragen sowie abhängig davon den Hintergrund
der Kurzbeschreibung auf der Artikeldetailseite in Gelb erscheinen lassen, quasi "highlighted".
Wir gehen hier wieder von einem eigenen Child-Template aus (siehe Eigenes Template). Definieren Sie
die CSS-Klasse in einer eigenen custom.css
Datei. Geladen wird diese CSS-Klasse via template.xml
, Tag
<Minify><CSS Name="clear.css">...</CSS>
für das jeweilige Theme. In NOVA ist es das Theme "clear".
/* custom.css */
.highlightclass {
background-color: yellow;
}
Das neue Funktionsattribut soll den Name highlightclass
tragen und muss natürlich noch in JTL-Wawi angelegt
werden. Rufen Sie dazu in JTL-Wawi die Artikelstammdaten des Zielartikels auf und wechseln Sie in den Reiter
"Attribute/Merkmale". Diese zweigeteilte Maske beinhaltet im oberen Bereich "Artikelattribute" die Attribute, die
wir anreichern wollen. Klicken Sie rechts auf :guilabel:Attribute verwalten
und wählen Sie in der folgenden
Maske unter "Attribut anlegen" den Unterpunkt "neues Funktionsattribut" aus. Vergeben Sie einen Namen und legen
Sie den Onlineshop fest, an den dieses Attribut gesendet werden soll.
Ändern Sie nun in der Template-Datei templates/NOVA/productdetails/details.tpl
den folgenden Code-Block so ab,
dass Sie den Wert des Funktionsattributes einfügen können, wenn er gesetzt ist:
/* productdetails/details.tpl */
{block name='productdetails-details-info-description'}
{include file='snippets/opc_mount_point.tpl' id='opc_before_short_desc'}
<div class="{if !empty($Artikel->FunktionsAttribute['highlightclass']}{$Artikel->FunktionsAttribute['highlightclass']} {/if}shortdesc mb-2 d-none d-md-block" itemprop="description">
{$Artikel->cKurzBeschreibung}
</div>
{/block}
Sonderfall: "Sonderzeichen im Funktionsattributnamen"
Bei Sonderzeichen im Namen des Funktionsattributes können Sie wie folgt darauf zugegreifen:
{assign var="fktattrname" value="größe"}
{$Artikel->FunktionsAttribute[$fktattrname]}
Kategorieattribute abfragen
Ähnlich den Funktionsattributen eines Artikels lassen sich in der JTL-Wawi, in den Kategoriedetails, auch Kategorieattribute definieren. Diese werden beim Synchronisieren zum Onlineshop übertragen und können dort Steuerungsaufgaben übernehmen können.
Es werden Kategorie-Funktionsattribute und Kategorieattribute unterschieden. Kategorie-Funktionsattribute
(categoryFunctionAttributes
) sind key/value-Paare die zur Aufnahme der Funktionsattribute dienen, während
Kategorieattribute in Form von "array of objects" lokalisierte Kategorieattribute aufnehmen. Funktionsattribute
dienen der Steuerung von Aktionen im Onlineshop selbst nur im Template, während Kategorieattribute lokalisierte
Werte - passend zur eingestellten Shop-Sprache - enthalten können.
Diese Kategorieattribute können im Template wie folgt abgefragt werden:
PHP-Code für Funktionsattribut
(Einbindung in Plugins oder in die php/functions.php des Templates):
$Kategorien = new KategorieListe();
$Kategorien->getAllCategoriesOnLevel( 0 );
foreach ($Kategorien->elemente as $Kategorie) {
$funktionsWert = $Kategorie->getCategoryFunctionAttribute('meinkategoriefunktionsattribut');
}
PHP-Code für lokalisiertes Attribut
(Einbindung als Plugin oder in die php/functions.php des Templates):
$Kategorien = new KategorieListe();
$Kategorien->getAllCategoriesOnLevel( 0 );
foreach ($Kategorien->elemente as $Kategorie) {
$attributWert = $Kategorie->getCategoryAttributeValue('meinkategorieattribut');
}
Template-Code
zur Steuerung mittels Kategorie-Funktionsattributen in der Kategorieansicht (am besten mit der Smarty Debug-Konsole nach dem eigenen Kategorieattribut suchen):
{if $oNavigationsinfo->getCategory()->getCategoryFunctionAttribute('meinkategoriefunktionsattribut') === 'machedies'}
<span>MacheDies</span>
{else}
<span>MacheDas</span>
{/if}
Template-Code
zur Ausgabe eines lokalisierten Kategorieattributs in Kategorieansicht (am besten mit der Smarty Debug-Konsole nach dem eigenen Kategorieattribut suchen):
<span>{$oNavigationsinfo->getCategory()->getCategoryAttributeValue('meinkategorieattribut')}</span>
Eigene Sprachvariablen verwenden
Um eigene Sprachvariablen zu erstellen, öffnen Sie im Backend von JTL-Shop die "Sprachverwaltung"
(Einstellungen -> Sprachverwaltung) und klicken Sie auf die Schaltfläche :guilabel:Variable hinzufügen
. Per
Smarty-Funktion {lang}
und den Parametern key
und section
können Sie diese Variablen im Template verwenden.
Beispiel:
Fügen Sie über die Sprachverwaltung folgende Sprachvariable hinzu:
- Sprachsektion: custom
- Variable: "safetyBoxTitle"
- Wert Deutsch: "SSL-Verschlüsselung"
- Wert Englisch: "SSL-Encryption"
Template-Code:
{lang key="safetyBoxTitle" section="custom"}
PHP-Code (z. B. in Plugins, wobei hier im Beispiel der Plugin-Kontext gegeben ist; zu erkennen am $this->
):
$langVar = $this->getLocalization()->getTranslation('safetyBoxTitle');
Sprachvariable als Smarty-Variable speichern und abfragen:
Template-Code:
{* Sprachvariable einfügen *}
{lang key="safetyBoxTitle" section="custom"}
{* Variable mit assign zuweisen *}
{lang assign="testVariableSafetyBoxTitle" key="safetyBoxTitle" section="custom"}
{* die zuvor zugewiesene Variable kann nun normal aufgerufen oder abgefragt werden *}
{if $testVariableSafetyBoxTitle eq "SSL-Verschlüsselung"}<span class="de">{$testVariableSafetyBoxTitle}</span>
{else}<span>{$testVariableSafetyBoxTitle}</span>{/if}
Erstellen eigener Smarty-Funktionen
Um eigene Smarty-Funktionen zu registrieren, gibt es template-abhängig diesen Weg.
NOVA-Template
Wenn Sie ein Child-Template des NOVA-Templates verwenden, erstellen Sie, sofern nicht bereits vorhanden, im
Wurzelverzeichnis Ihres Child-Templates eine PHP-Klasse namens Bootstrap.php
mit folgendem Inhalt:
<?php declare(strict_types=1);
namespace Template\[NOVA-child-name];
/**
* Class Bootstrap
* @package Template\[NOVA-child-name]
*/
class Bootstrap extends \Template\NOVA\Bootstrap
{
// eigene Methoden
}
Hint
Die PHP-Datei, wie auch die PHP-Klasse, wird beim Start automatisch geladen und ermöglicht das Registrieren von Smarty-Plugins. Danach können Sie Ihre eigenen Smarty-Funktionen implementieren und in Smarty registrieren.
Funktionen im NOVA-Child registrieren
Im nachfolgenden Beispiel wird eine Methode zur Berechnung der Kreiszahl PI in die Bootstrap
-Klasse eingebunden
und in Smarty registriert:
<?php declare(strict_types=1);
namespace Template\[NOVA-child-name];
use Smarty;
/**
* Class Bootstrap
* @package Template\[NOVA-child-name]
*/
class Bootstrap extends \Template\NOVA\Bootstrap
{
public function boot(): void
{
parent::boot();
try {
$this->getSmarty()->registerPlugin(Smarty::PLUGIN_FUNCTION, 'getPI', [$this, 'getPI']);
} catch (\SmartyException $e) {
throw new \RuntimeException('Problems during smarty instantiation: ' . $e->getMessage());
}
}
public function getPI($args)
{
$precision = $args['precision'];
$iterator = 1;
$factor = -1;
$nenner = 3;
for ($i = 0; $i < $precision; $i++) {
$iterator = $iterator + $factor / $nenner;
$factor *= -1;
$nenner += 2;
}
return $iterator * 4;
}
}
Funktionen nutzen
Die Funktion getPI()
kann dann im Template z. B. mit {getPI precision=12}
verwendet werden.
Überschreiben bestehender Funktionen
Das Überschreiben von Funktionalitäten ist ebenfalls möglich.
Funktionen im NOVA-Child überschreiben
In Ihrem NOVA-Child überschreiben sie Funktionen, indem Sie die entsprechende Basisklasse des NOVA-Templates
templates/NOVA/Plugins.php
mit einer eigenen Klasse in Ihrem NOVA-Child templates/[NOVA-child-name]/Plugins.php
erweitern.
Im nachfolgenden Beispiel wird die Funktion getTranslation()
des NOVA-Templates dahingehend erweitert, dass bei
nicht vorhandener Übersetzung der Text "-no translation-" ausgegeben wird.
<?php declare(strict_types=1);
namespace Template\[NOVA-child-name];
use JTL\Shop;
/**
* Class Bootstrap
* @package Template\[NOVA-child-name]
*/
class Plugins extends \Template\NOVA\Plugins
{
public function getTranslation($mixed, $to = null): ?string
{
$to = $to ?: Shop::getLanguageCode();
if ($this->hasTranslation($mixed, $to)) {
return \is_string($mixed) ? $mixed : $mixed[$to];
}
return '-no translation-';
}
}
Um ihre Variante der Funktion getTranslation()
nutzen zu können, müssen sie erst die alte Variante aus dem System
entfernen ("unregister") und die neue definieren. Dies geschieht in templates/NOVA/Bootstrap.php
wie folgt:
<?php declare(strict_types=1);
namespace Template\NOVAChild;
use Smarty;
/**
* Class Bootstrap
* @package Template\NOVAChild
*/
class Bootstrap extends \Template\NOVA\Bootstrap
{
/**
* @inheritdoc
*/
public function boot(): void
{
parent::boot();
// whatever you do, always call parent::boot() or delete this method!
}
protected function registerPlugins(): void
{
parent::registerPlugins();
$plugins = new Plugins($this->getDB(), $this->getCache());
$smarty = parent::getSmarty();
$smarty->unregisterPlugin(Smarty::PLUGIN_FUNCTION,'getTranslation');
$smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'getTranslation', [$plugins, 'getTranslation']);
// whatever you do, always call parent::registerPlugins() or delete this method!
}
}
Unabhängige Artikellisten erzeugen
Ab JTL-Shop Version 3.10, bis einschließlich 5.0, ist es möglich, eigene Artikel-Arrays über eine Smarty-Funktion
{get_product_list}
zu erzeugen. Dies kann beispielsweise dazu genutzt werden, um auf bestimmte Artikel(-gruppen)
abseits von Cross-Selling gesondert aufmerksam zu machen.
Der Funktion können die folgenden Parameter übergeben werden:
Parametername | Typ | Pflichtattribut | Beschreibung |
---|---|---|---|
nLimit |
Numeric | Ja | Maximale Anzahl Artikel, welche geholt werden sollen |
cAssign |
String | Ja | Name der Smarty-Variable, in welcher das Array mit Artikeln gespeichert wird |
kKategorie |
Numeric | -- | Primärschlüssel einer Kategorie, siehe Datenbank tkategorie.kKategorie |
kHersteller |
Numeric | -- | Primärschlüssel eines Herstellers, siehe Datenbank thersteller.kHersteller |
kArtikel |
Numeric | -- | Primärschlüssel eines Artikels, siehe Datenbank tartikel.kArtikel |
kSuchanfrage |
String | -- | Primärschlüssel einer Suchanfrage, siehe Datenbank tsuchcache.kSuchCache |
kMerkmalWert |
String | -- | Primärschlüssel eines Merkmalwerts, siehe Datenbank tmerkmalwert.kMerkmalwert |
kSuchspecial |
Numeric | -- | Filterung nach Suchspecials, siehe Tabelle unten "Suchspecialschlüssel" |
kKategorieFilter |
Numeric | -- | Zusätzlicher Filter nach einer Kategorie in Kombination mit einem Hauptfilter z. B. kHersteller. |
kHerstellerFilter |
Numeric | -- | Zusätzlicher Filter nach einem Hersteller in Kombination mit einem Hauptfilter z. B. kKategorie . Primärschlüssel siehe Datenbank thersteller.kHersteller |
nBewertungSterneFilter |
Numeric | -- | Zusätzlicher Filter nach Mindest-Durschnittsbewertung in Kombination mit einem Hauptfilter, z. B. kKategorie. |
cPreisspannenFilter |
String | -- | Zusätzlicher Filter nach Preisspanne in Kombination mit einem Hauptfilter, z. B. kKategorie . Schreibweise für "von 20 € bis 40,99 €": "20_40.99" |
nSortierung |
Numeric | -- | Gibt an, nach welchem Artikelattribut sortiert werden soll. Details siehe Tabelle unten "Sortierungsschlüssel" |
cMerkmalFilter |
String | -- | Primärschlüssel der Merkmalwerte durch Semikolon getrennt, z. B. "100;101". Primärschlüsselangabe siehe Datenbank tmerkmalwert.kMerkmalwert |
cSuchFilter |
String | -- | Primärschlüssel der Suchfilter durch Semikolon getrennt, z. B. "200;201". Primärschlüsselangabe siehe Datenbank tsuchcache.kSuchCache |
cSuche |
String | -- | Suchbegriff, z. B. "zwiebel ananas baguette" |
Beispiel
Binden Sie den folgenden Code im Template ein:
<h2>Unsere Verkaufschlager aus dem Bereich Gemüse</h2>
{get_product_list kKategorie=9 nLimit=3 nSortierung=11 cAssign="myProducts"}
{if $myProducts}
<ul>
{foreach name=custom from=$myProducts item=oCustomArtikel}
<li><a href="{$oCustomArtikel->cURLFull}">{$oCustomArtikel->cName}</a></li>
{/foreach}
</ul>
{/if}
Sortierungsschlüssel
Name | Wert | Konstante |
---|---|---|
Standard | 100 | SEARCH_SORT_STANDARD |
Artikelname von A bis Z | 1 | SEARCH_SORT_NAME_ASC |
Artikelname von Z bis A | 2 | SEARCH_SORT_NAME_DESC |
Preis aufsteigend | 3 | SEARCH_SORT_PRICE_ASC |
Preis absteigend | 4 | SEARCH_SORT_PRICE_DESC |
EAN | 5 | SEARCH_SORT_EAN |
neuste zuerst | 6 | SEARCH_SORT_NEWEST_FIRST |
Artikelnummer | 7 | SEARCH_SORT_PRODUCTNO |
Verfügbarkeit | 8 | SEARCH_SORT_AVAILABILITY |
Gewicht | 9 | SEARCH_SORT_WEIGHT |
Erscheinungsdatum | 10 | SEARCH_SORT_DATEOFISSUE |
Bestseller | 11 | SEARCH_SORT_BESTSELLER |
Bewertungen | 12 | SEARCH_SORT_RATING |
Suchspecialschlüssel
Name | Wert | Konstante |
---|---|---|
Bestseller | 1 | SEARCHSPECIALS_BESTSELLER |
Sonderangebote | 2 | SEARCHSPECIALS_SPECIALOFFERS |
Neu im Sortiment | 3 | SEARCHSPECIALS_NEWPRODUCTS |
Top-Angebote | 4 | SEARCHSPECIALS_TOPOFFERS |
In Kürze verfügbar | 5 | SEARCHSPECIALS_UPCOMINGPRODUCTS |
Top bewertet | 6 | SEARCHSPECIALS_TOPREVIEWS |
Ausverkauft | 7 | SEARCHSPECIALS_OUTOFSTOCK |
Auf Lager | 8 | SEARCHSPECIALS_ONSTOCK |
Vorbestellung möglich | 9 | SEARCHSPECIALS_PREORDER |
Eigene Mount-Points einfügen
Mit dem OnPage Composer können Inhalte in vordefinierte Bereiche des Templates platziert werden. Diese Bereiche werden im Smarty Codes des Template durch sogenannte Mount Points ausgezeichnet. Falls Sie eigene Mount Points definieren wollen, nutzen Sie die folgende Smarty-Anweisung:
{opcMountPoint id='mount_point_id'}
Mit dem Parameter id
geben Sie dem Mount Point einen Identifikator, der für die Seite eindeutigen sein muss.
Optional können Sie der Smarty-Funktion noch den Parameter title
mitgeben. Dieser definiert einen im OnPage
Composer-Editor sichtbaren Anzeigenamen.
Beispiel:
{opcMountPoint id='opc_in_header' title='Im Header'}