Clerk (JTL-Shop 5)
- 1 Einleitung
- 2 Installation und Update
- 3 Konfiguration (Shop)
- 4 Konfiguration Shop bei Clerk.io (Allgemein)
- 5 Hinzufügen der Live-Suche
- 5.1 Design:
- 5.1.1 HTML Datei:
- 5.1.2 CSS Datei:
- 5.2 Content:
- 5.1 Design:
- 6 Hinzufügen der Facetten
- 7 Hinzufügen der Suchergebnisse
- 8 Eigene zusätzliche Slider hinzufügen
- 8.1 EasyTemplate
- 8.2 OnPage Composer
- 9 PHP Events
- 10 Individualisierung
- 11 Formatierungen
- 12 Troubleshooting
- 12.1 Logs prüfen
- 12.1.1 Browser-Log
- 12.1.2 Shop-Log
- 12.1.3 Webserver-Log
- 12.1 Logs prüfen
- 13 FAQ
- 14 Changelog
- 15 Support und Kontakt
Einleitung
Dieses Plugin integriert den Clerk.io Service in Ihren JTL-Shop.
Somit sind personalisierte Produktempfehlungen, eine erweiterte Suche, individualisierte Slider und vieles weitere möglich.
Installation und Update
Systemvoraussetzungen
JTL-Shop 5.1+ (und die beinhalteten Bibliotheken)
JTL-Wawi 1.5
MySQL 5.7
Linux mit Apache 2 / Litespeed (andere Konstellationen sind möglich, aber nicht per se unterstützt)
PHP Version 8.0
Benötigte folgende PHP Erweiterungen:
cURL
GD
ImageMagick
JSON-Support
mbstring
MySQLi
Socket-Support
SPL
eingesetztes Template
NOVA
easyTemplate
andere Templates müssen ggf. mit Servicepartner geprüft werden
Weitere Voraussetzungen
Sie müssen bei Clerk.io registriert sein, um einen API Schlüssel zu erhalten.
Plugin-Installation
Die Installation des Plugins erfolgt im Standardverfahren für JTL-Shop 5, wie es hier beschrieben ist.
Plugin-Update
Für ein Update laden Sie das Plugin wie bei einer Installation in der neuesten Version hoch (und überschreiben ggf. alle vorhandenen Plugin Dateien) oder folgen Sie den Hinweisen des Extension Stores.
Gehen Sie dann in die Plugin Verwaltung und betätigen Sie den Update-Button.
Konfiguration (Shop)
Einstellungen des Plugins
Die Einstellungen des Plugins erreichen Sie über Plugins → Installierte Plugins → S360 Clerk → Einstellung
Bereich | Option | Bedeutung |
---|---|---|
Allgemein | Cookieless Tracking nutzen | Tracking ohne Cookie Nutzung |
| Warenkorb Tracking nutzen? | Informiert Clerk über Änderungen am Warenkorb (allg. Tracking des Warenkorbs) |
| E-Mails anonymisieren | E-Mail Adressen werden anonymisiert (als Hash) an Clerk übertragen |
| Clerk JS Name | Falls gesetzt wird das Clerk Javascript nicht von Benötigt Plugin Version 1.0.6 |
|
|
|
Omni-Suche Benötigt Plugin Version 1.0.6 |
|
|
| In Webseite einfügen | Gibt an, ob die Omni-Suche über das Plugin eingebunden werden soll oder ob sie direkt über Clerk.js eingebunden werden soll. In letzterem Fall haben die Plugin-Einstellungen für die Omni-Suche keine Auswirkung → die Einstellungen müssen in diesem Fall im Clerk Backend vorgenommen werden! |
| Omni-Suche aktivieren | Falls deaktiviert wird im Frontend die Clerk Omni-Suche nicht ausgespielt. Falls aktiviert, haben die Einstellungen der Live-Suche und Suche (Ergebnisseite) keine Auswirkungen! |
| Selektor Omni-Suche | Selektor für die Omni-Suche unabhängig von Clerk |
| Clerk templateName Omni-Suche | Template für die Omni-Suche (Clerk Backend → Search → Content → Omnisuche → Insert into website → Im Code den Wert aus “data-template=”@WERT'“) |
|
|
|
Live Suche (Header) | Live Suche aktivieren? | Falls deaktiviert wird im Frontend die Clerk Live Suche nicht ausgespielt. |
| Selektor Livesuche | Selektor für die Live-Suche unabhängig von Clerk |
| Clerk TemplateName Livesuche | Template für die Live-Suche (Clerk Backend → Search → Content → Livesuche → Insert into website → Im Code den Wert aus “data-template=”@WERT'“) |
| Anzahl Suchvorschläge in der Livesuche | Anzahl der Suchvorschläge die angezeigt werden soll |
| Anzahl Kategorievorschläge | Anzahl der Kategorie Vorschläge die angezeigt werden soll |
| Anzahl Seitenvorschläge | Anzahl der Seitenvorschläge die angezeigt werden soll |
| Position | Position des Live-Suche Ergebnisses in Bezug auf den Selektor |
|
|
|
Suche (Ergebnisseite) | Ergebnisseite aktivieren? | Falls deaktiviert wird im Frontend die Clerk Ergebnisseite nicht ausgespielt. |
| Clerk TemplateName Suche | Template für die Live-Suche (Clerk Backend → Search → Content → Suche → Insert into website → Im Code den Wert aus “data-template=”@WERT'“) |
| Position Facetten | Position der Facetten |
| Facetten in URL anzeigen | Facetten in URL anzeigen |
| Clerk Facetten Attribute | Kommagetrennte Liste der verfügbaren Facetten (JTL Merkmale) |
| Clerk Facetten Attribute Multiple Werte | Kommagetrennte Liste der verfügbaren Facetten mit multiplen Werten (JTL Merkmale für ODER Filterung) |
Bereich | Option | Bedeutung |
---|---|---|
Data Feed | Cronverarbeitung | Art und Weise wie der Cron zur Generierung des Daten Feeds angestoßen werden soll (Im Abschnitt Möglichkeiten der Daten Feed Erstellung genauer erklärt) |
| Stapelgröße | Stapelgröße der Produkte des Feeds (Im Abschnitt Stapelgröße genauer erklärt) |
|
|
|
Produkt Seite | Produktseiten Slider aktivieren? | Falls deaktiviert wird im Frontend der Slider auf der Produktseite nicht ausgespielt. |
| Artikel Selektor Slider | Selektor für den Artikel Slider unabhängig von Clerk |
| Clerk TemplateName Artikel | Namen der Slider Templates die ausgegeben werden sollen. Mehrere Template Namen können als komma-separierte Liste angegeben werden. |
| Slider | Einfügemethode, wie der Slider zum Selektor hinzugefügt werden soll (After, Append, Before, Prepand, ReplaceWith) |
| Duplikate filtern | Verhindert, dass nachfolgende Slider Produkte aus vorherigen Slidern enthalten (Standard: Ja) |
|
|
|
Warenkorb Seite | Warenkorb Slider aktivieren? | Falls deaktiviert wird im Frontend der Slider auf der Warenkorbseite nicht ausgespielt. |
| Warenkorb Selektor Slider | Selektor für den Warenkorb Slider unabhängig von Clerk |
| Clerk TemplateName Warenkorb | Namen der Slider Templates die ausgegeben werden sollen. Mehrere Template Namen können als komma-separierte Liste angegeben werden. |
| Slider | Einfügemethode, wie der Slider zum Selektor hinzugefügt werden soll (After, Append, Before, Prepand, ReplaceWith) |
| Duplikate filtern | Verhindert, dass nachfolgende Slider Produkte aus vorherigen Slidern enthalten (Standard: Ja) |
|
|
|
Powerstep | Powerstep Slider aktivieren? | Falls deaktiviert wird im Frontend der Slider im Powerstep nicht ausgespielt. |
| Powerstep Selektor | Selektor für den Powerstep Slider unabhängig von Clerk |
| Clerk TemplateName Powerstep | Namen der Slider Templates die ausgegeben werden sollen. Mehrere Template Namen können als komma-separierte Liste angegeben werden. |
| Powerstep Einfügemethode | Einfügemethode, wie der Slider zum Selektor hinzugefügt werden soll (After, Append, Before, Prepand, ReplaceWith) |
| Duplikate filtern | Verhindert, dass nachfolgende Slider Produkte aus vorherigen Slidern enthalten (Standard: Ja) |
Bereich | Option | Bedeutung |
---|---|---|
Kategorie Seite | Kategorieseiten Slider aktivieren? | Falls deaktiviert wird im Frontend der Slider auf der Kategorieseite nicht ausgespielt. |
| Kategorie Selektor Slider | Selektor für den Kategorie Slider unabhängig von Clerk |
| Clerk TemplateName Warenkorb | Namen der Slider Templates die ausgegeben werden sollen. Mehrere Template Namen können als komma-separierte Liste angegeben werden. |
| Slider | Einfügemethode, wie der Slider zum Selektor hinzugefügt werden soll (After, Append, Before, Prepand, ReplaceWith) |
| Duplikate filtern | Verhindert, dass nachfolgende Slider Produkte aus vorherigen Slidern enthalten (Standard: Ja) |
|
|
|
Exit Intent (Ausstiegsabsicht) | Exit Intent Slider aktivieren? | Falls deaktiviert wird im Frontend der Exit Intent nicht ausgespielt. |
| Clerk TemplateName Exit Intent | Template für den Exit Intent |
Erstellung von Datenfeeds
Einstellungen:
Die Einstellungen des Datenfeeds erreichen Sie über Plugins → Installierte Plugins → S360 Clerk → klick auf Zahnrad (siehe Bild)
Hier kann genau ausgewählt werden, welche Daten dem Feed hinzugefügt werden bzw. welche für Sie relevant sind.
Option | Bedeutung |
---|---|
API Key | Ihr von Clerk erhaltener API Schlüssel |
Private Key | Ihr von Clerk bereitgestellter Legacy private API Key. Wird für die Zugriffsbeschränkung auf den Daten-Feed benötigt. |
Sprache | Sprache des Daten Feeds |
Kundengruppe | Preise für die Kundengruppe |
Währung | Währung im Daten Feed |
Facetten Design | Design der Facetten |
Weitere Informationen sind aus der jeweiligen Reihe zu entnehmen (i-Icon).
Weitere Daten Feed Einstellungen
Möglichkeiten der Daten Feed Erstellung
Es gibt 3 Möglichkeiten die Generierung der Cron-Jobs anzustoßen:
CLI → Bei CLI wird der Cronjob über den Shop CLI Befehl php cli s360_clerk_shop5:cron aufgerufen
Wawi Abgleich → Cronjob wird beim Wawi Abgleich mit ausgeführt
Aufgabenplaner → Der Cronjob wird zusammen mit anderen Cronjobs z.B Exporte über den Aufruf der cron_inc.php angestoßen. (Standard JTL Cron → JTL5-Shop Backend -> System-> Cron)
Gesamtablauf zur Erstellung des Feeds
Feed im Shop Backend einstellen (Plugins → Installierte Plugins → S360 Clerk → klick auf Zahnrad (siehe Bild))
Nach den Einstellungen, den Feed erstellen (Plugins → Installierte Plugins → S360 Clerk → klick auf Doppelpfeil)
Nach erfolgreichem erstellen muss der Feed im Clerk.io Backend hinterlegt werden:
Stapelgröße
Anstatt alle Produkte auf einmal aus der Datenbank auszulesen, wird immer nur ein Stapel von Produkten auf einmal ausgelesen .
Bei einer großen Anzahl an Produkten, kann so der Speicherverbrauch stark reduziert werden., erhöht dabei allerdings die Laufzeit.
Ist der Wert auf 0 gesetzt, werden ALLE Produkte ausgegeben.
Konfiguration Shop bei Clerk.io (Allgemein)
Das Standardisierte Vorgehen zum hinzufügen neuer Elemente ist:
Öffnen des Clerk.io Backends
Design erstellen
Content hinzufügen
Einstellungen im Plugin Backend
Hinzufügen des Warenkorb-Sliders
Neue Slider können via Clerk Backend erzeugt und hinzugefügt werden.
Anlegen des Design erfolgt im Clerk.io Backend unter Recommendations → Designs.
Hier kann via HTML und CSS das Grund-Design angepasst werden.
Wichtig: Lieferstatus wird momentan nur vom EasyTemplate Slider unterstützt.
Vorlage Design Nova:
{% if products.length != 0 %}
<div class="slick-slider-other is-not-opc">
<div class="hr-sect h2">
{{ headline }}
</div>
<div id="slick-slider-{{ snippets.settings.slider.id }}" class="carousel-arrows-inside carousel slick-smooth-loading slider-no-preview slick-type-product slick-lazy" data-slick-type="product-slider">
{% for product in products %}
<div class="product-wrapper col">
<div id="result-wrapper_buy_form_{{ product.id }}" data-wrapper="true" class="productbox productbox-column">
<div class="productbox-inner">
<div class="row">
<div class="col col-12">
<div class="productbox-image">
<div class="productbox-images">
<a href="{{ product.url }}" title="{{ product.name }}">
<div class="productbox-image square square-image">
<div class="inner">
<picture>
<img src="{{ product.image }}" class="img-fluid" loading="lazy" alt="{{ product.name }}" />
</picture>
</div>
</div>
{% if product.top_article and product.top_article != false %}
<div class="ribbon ribbon-4 productbox-ribbon">
{{ snippets.ribbons.4 }}
</div>
{% endif %}
{% if product.on_sale and product.on_sale != false %}
<div class="ribbon ribbon-2 productbox-ribbon">
{{ snippets.ribbons.2 }}
</div>
{% endif %}
{% if product.in_stock and product.in_stock != false %}
<div class="ribbon ribbon-8 productbox-ribbon">
{{ snippets.ribbons.8 }}
</div>
{% endif %}
{% if product.in_stock and product.in_stock <= 0 %}
<div class="ribbon ribbon-7 productbox-ribbon">
{{ snippets.ribbons.7 }}
</div>
{% endif %}
{% if product.age and product.age <= snippets.settings.newProductmaxDays %}
<div class="ribbon ribbon-3 productbox-ribbon">
{{ snippets.ribbons.3 }}
</div>
{% endif %}
{% if product.average_rating and product.average_rating <= snippets.settings.topProductMinStars %}
<div class="ribbon ribbon-6 productbox-ribbon">
{{ snippets.ribbons.6 }}
</div>
{% endif %}
{% if product.age and product.age < 0 %}
<div class="ribbon ribbon-5 productbox-ribbon">
{{ snippets.ribbons.5 }}
</div>
{% endif %}
{% if product.vorbestellbardate and product.vorbestellbardate > 0 %}
<div class="ribbon ribbon-9 productbox-ribbon">
{{ snippets.ribbons.9 }}
</div>
{% endif %}
{% if product.age and product.age > 0 and product.stock <= 0 %}
<div class="ribbon ribbon-5 productbox-ribbon">
{{ snippets.ribbons.5 }}
</div>
{% endif %}
</a>
</div>
</div>
</div>
<div class="col col-12">
<div class="productbox-title">
<a href="{{ product.url }}" title="{{ product.name }}" class="text-clamp-2">
{{ product.name }}
</a>
</div>
{% if product.reviews_avg > 0 %}
<a class="rating" href="{{ product.url }}#tab-votes" title="{{ snippets.productRating }}: {{ product.reviews_avg }}/5">
{% if product.reviews_avg >= 5 %}
<i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i>
{% else %}
{% if product.reviews_avg >= 4 %}
<i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i>{% if product.reviews_avg > 4 %}<i class="{{ snippets.icons.ratingHalf }}"></i>{% else %}<i class="{{ snippets.icons.ratingEmpty }}"></i>{% endif %}
{% else %}
{% if product.reviews_avg >= 3 %}
<i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i>{% if product.reviews_avg > 3 %}<i class="{{ snippets.icons.ratingHalf }}"></i>{% else %}<i class="{{ snippets.icons.ratingEmpty }}"></i>{% endif %}<i class="{{ snippets.icons.ratingEmpty }}"></i>
{% else %}
{% if product.reviews_avg >= 2 %}
<i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i>{% if product.reviews_avg > 2 %}<i class="{{ snippets.icons.ratingHalf }}"></i>{% else %}<i class="{{ snippets.icons.ratingEmpty }}"></i>{% endif %}<i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i>
{% else %}
{% if product.reviews_avg >= 1 %}
<i class="{{ snippets.icons.rating }}"></i>{% if product.reviews_avg > 1 %}<i class="{{ snippets.icons.ratingHalf }}"></i>{% else %}<i class="{{ snippets.icons.ratingEmpty }}"></i>{% endif %}<i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i>
{% else %}
{% if product.reviews_avg > 0 %}
<i class="{{ snippets.icons.ratingHalf }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i>
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
</a>
{% else %}
<div class="rating productbox-rating-empty"></div>
{% endif %}
<div>
<div class="price_wrapper">
{% if product.has_variations or product.bulk_prices != 0 %}
<span class="price_label pricestarting">
{{ snippets.priceStarting }}
</span>
{% endif %}
<div class="price productbox-price {% if product.on_sale %} special-price{% endif %}">
<span>{{ product.price | money_eu }} {{ globals.currency_symbol }} <span class="footnote-reference">*</span></span>
</div>
{% if product.on_sale %}
<div class="price-note">
<div class="instead-of old-price">
<small class="text-muted-util">
<del class="value">{{ product.original_price | money_eu }} {{ globals.currency_symbol }}</del>
</small>
</div>
</div>
{% endif %}
{% if product.base_price > 0 %}
<div class="price-note">
<span class="value">{{ product.base_price | money_eu }} {{ globals.currency_symbol }} {{ snippets.vpePer }} {{ product.base_price_unit }}</span>
</div>
{% else %}
<div class="price-note"> </div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<script>
$(function() {
$.evo.generateSlickSlider();
$.evo.popover();
});
</script>
{% endif %}
Vorlage Design EasyTemplate:
{% if products.length != 0 %}
<div class="et-widget-clerkslider-headline">
<div class="et-product-slider-headline">
<div class="et-textfield text-align-default et-widget-headline h2">{{ headline }}</div>
</div>
</div>
<div class="et-product-slider-wrapper row">
<div class="col p-0">
<div class="slick-slider-other is-not-opc">
<div id="et-clerk-slider-{{ snippets.settings.slider.id }}" class="et-product-slider-slider et-slider carousel slick-smooth-loading slider-no-preview slick-type-product">
{% for product in products %}
<div class="product-wrapper col">
<div id="result-wrapper_buy_form_{{ product.id }}" data-wrapper="true" class="productbox productbox-show-variations et-item-box productbox-column">
<div class="productbox-inner">
<div class="row">
<div class="col col-12">
<div class="productbox-image">
{% if product.top_article and product.top_article != false %}
<div class="ribbon ribbon-4 productbox-ribbon">
{{ snippets.ribbons.4 }}
</div>
{% endif %}
{% if product.on_sale and product.on_sale != false %}
<div class="ribbon ribbon-2 productbox-ribbon">
{{ snippets.ribbons.2 }}
</div>
{% endif %}
{% if product.in_stock and product.in_stock != false %}
<div class="ribbon ribbon-8 productbox-ribbon">
{{ snippets.ribbons.8 }}
</div>
{% endif %}
{% if product.in_stock and product.in_stock <= 0 %}
<div class="ribbon ribbon-7 productbox-ribbon">
{{ snippets.ribbons.7 }}
</div>
{% endif %}
{% if product.age and product.age <= snippets.settings.newProductmaxDays %}
<div class="ribbon ribbon-3 productbox-ribbon">
{{ snippets.ribbons.3 }}
</div>
{% endif %}
{% if product.average_rating and product.average_rating <= snippets.settings.topProductMinStars %}
<div class="ribbon ribbon-6 productbox-ribbon">
{{ snippets.ribbons.6 }}
</div>
{% endif %}
{% if product.age and product.age < 0 %}
<div class="ribbon ribbon-5 productbox-ribbon">
{{ snippets.ribbons.5 }}
</div>
{% endif %}
{% if product.vorbestellbardate and product.vorbestellbardate > 0 %}
<div class="ribbon ribbon-9 productbox-ribbon">
{{ snippets.ribbons.9 }}
</div>
{% endif %}
{% if product.age and product.age > 0 and product.stock <= 0 %}
<div class="ribbon ribbon-5 productbox-ribbon">
{{ snippets.ribbons.5 }}
</div>
{% endif %}
<div class="productbox-images list-gallery">
<a href="{{ product.url }}" title="{{ product.name }}">
<div class="productbox-image square square-image">
<div class="inner">
<picture>
<img src="{{ product.image }}" class="img-fluid" loading="lazy" alt="{{ product.name }}" />
</picture>
</div>
</div>
</a>
</div>
</div>
</div>
<div class="col col-12">
<div class="productbox-caption">
<div class="et-item-box-manufacturer productbox-manufacturer">
<span>{% if snippets.settings.showBrand %}{{ product.brand }}{% endif %}</span>
</div>
<div class="et-item-box-title productbox-title">
<a href="{{ product.url }}" class="text-clamp-2 link-discreet">
{{ product.name }}
</a>
</div>
<div class="et-item-box-rating productbox-rating">
{% if product.average_rating > 0 %}
<a class="rating" href="{{ product.url }}#tab-votes" title="{{ snippets.productRating }}: {{ product.average_rating }}/5">
{% if product.average_rating >= 5 %}
<i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i>
{% else %}
{% if product.average_rating >= 4 %}
<i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i>{% if product.average_rating > 4 %}<i class="{{ snippets.icons.ratingHalf }}"></i>{% else %}<i class="{{ snippets.icons.ratingEmpty }}"></i>{% endif %}
{% else %}
{% if product.average_rating >= 3 %}
<i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i>{% if product.average_rating > 3 %}<i class="{{ snippets.icons.ratingHalf }}"></i>{% else %}<i class="{{ snippets.icons.ratingEmpty }}"></i>{% endif %}<i class="{{ snippets.icons.ratingEmpty }}"></i>
{% else %}
{% if product.average_rating >= 2 %}
<i class="{{ snippets.icons.rating }}"></i><i class="{{ snippets.icons.rating }}"></i>{% if product.average_rating > 2 %}<i class="{{ snippets.icons.ratingHalf }}"></i>{% else %}<i class="{{ snippets.icons.ratingEmpty }}"></i>{% endif %}<i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i>
{% else %}
{% if product.average_rating >= 1 %}
<i class="{{ snippets.icons.rating }}"></i>{% if product.average_rating > 1 %}<i class="{{ snippets.icons.ratingHalf }}"></i>{% else %}<i class="{{ snippets.icons.ratingEmpty }}"></i>{% endif %}<i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i>
{% else %}
{% if product.average_rating > 0 %}
<i class="{{ snippets.icons.ratingHalf }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i><i class="{{ snippets.icons.ratingEmpty }}"></i>
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
</a>
{% endif %}
</div>
{% if product.in_stock %}
{% if product.stock >= snippets.settings.storageLightsGreen%}
<div class="delivery-status">
<ul class="list-unstyled">
<li>
<span class="status status-2">
<span class="{{snippets.settings.storageLightIcon}} status-icon"> </span>
<span class="status-text">{{snippets.settings.storageLightTextGreen}}</span>
</span>
</li>
</ul>
</div>
{% endif %}
{% if product.stock > snippets.settings.storageLightsRed and product.stock < snippets.settings.storageLightsGreen %}
<div class="delivery-status">
<ul class="list-unstyled">
<li>
<span class="status status-1">
<span class="{{snippets.settings.storageLightIcon}} status-icon"> </span>
<span class="status-text">{{snippets.settings.storageLightTextYellow}}</span>
</span>
</li>
</ul>
</div>
{% endif %}
{% if product.stock == snippets.settings.storageLightsRed%}
<div class="delivery-status">
<ul class="list-unstyled">
<li>
<span class="status status-0">
<span class="{{snippets.settings.storageLightIcon}} status-icon"> </span>
<span class="status-text">{{snippets.settings.storageLightTextRed}}</span>
</span>
</li>
</ul>
</div>
{% endif %}
{% endif %}
<div class="et-item-box-price">
<div class="price_wrapper">
{% if product.has_variations or product.bulk_prices != 0 %}
<span class="price_label pricestarting">
{{ snippets.priceStarting }}
</span>
{% endif %}
<div class="price productbox-price {% if product.on_sale %} special-price{% endif %}">
<span>{{ product.price | money }} {{ globals.currency_symbol }} <span class="footnote-reference">*</span></span>
</div>
{% if product.on_sale %}
<div class="price-note et-old-price">
<div class="instead-of old-price">
<small class="text-muted-util">
<del class="value">{{ product.original_price | money }} {{ globals.currency_symbol }}</del>
</small>
</div>
</div>
{% endif %}
{% if product.base_price > 0 %}
<div class="price-note">
<span class="value">{{ product.base_price | money }} {{ globals.currency_symbol }} {{ snippets.vpePer }} {{ product.base_price_unit }}</span>
</div>
{% else %}
<div class="price-note"> </div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
<div class="et-slider-nav" id="clerk-slider-nav-{{ snippets.settings.slider.id }}">
<div class="et-slider-nav-prev enabled slick-arrow slick-hidden" id="clerk-slider-prev-{{ snippets.settings.slider.id }}">
<i class="{{ snippets.icons.sliderPrevious }}"></i>
</div>
<div class="et-slider-nav-next enabled slick-arrow slick-hidden" id="clerk-slider-next-{{ snippets.settings.slider.id }}">
<i class="{{ snippets.icons.sliderNext }}"></i>
</div>
</div>
</div>
</div>
</div>
<script>
$(function() {
$("#et-clerk-slider-{{ snippets.settings.slider.id }}").slick({{ snippets.settings.slider.settings }});
$.evo.popover();
});
</script>
{% endif %}
Content hinzufügen
Unter Clerk.io → Recommendations → Content , kann der Content für den neuen Warenkorb-Slider erzeugt werden (Button New Content)
Die nun folgende Seite beinhaltet 4 wichtige Abschnitte:
Name your content → Hier wird der Name festgelegt
Choose product logic → Hier kann die Produktlogik ausgewählt werden, unter anderem “Best Sellers” / “Hot Products” und vieles mehr
Select design → Welches Design soll verwendet werden / wie soll die Überschrift lauten und wie viele Produkte sollen angezeigt werden (Wichtig: wird durch das Plugin festgelegt, auch wenn hier eine “Anzahl” hinterlegt werden kann)
Insert into website → Hier wird der Name ausgegeben, den wir in unserem JTL5-Shop Backend unter Clerk TemplateName Warenkorb eingeben müssen
Nachdem alles eingestellt und befüllt wurde, muss nun ins JTL5-Shop Backend gewechselt werden und dort wird nun der Name der Komponente (aus Insert into website) hinterlegt.
Einstellung Plugin Backend
Hinzufügen des Artikel Sliders
Das Hinzufügen des Artikel Sliders verläuft äquivalent zum Warenkorb Slider.
Es werden im Standardfall, die selben Design Dateien verwendet (Slider NOVA / Slider ET), lediglich der Name/Produktlogik im Clerk.io Backend wird verändert und im Plugin Backend wird ein anderer Selektor gewählt.
Hinzufügen der Live-Suche
Verläuft äquivalent zu den Slidern:
Design erstellen
Content hinzufügen
Einstellungen im Plugin Backend
Anlegen des Design erfolgt im Clerk.io Backend unter Search → Designs.
Unterschiede zu den Slidern:
Hier wird auch der CSS Abschnitt befüllt.
Kein Unterschied zwischen Nova und EasyTemplate Design
Design:
HTML Datei:
<div id="clerk-template-live-search" style="background: white">
<div class="clerk-live-search">
<div class="row">
<div class="col-12 col-sm-8 clerk-live-search-products">
{% if products.length != 0 %}
<div class="h4 headline-style">{{ snippets.headlineProducts }}</div>
{% for product in products %}
<div class="product clerk-instant-search-key-selectable">
<a href="{{ product.url }}" class="d-block product-link link-discreet">
<div class="row align-items-center">
<div class="col-2 text-center product-image-wrapper">
<img src="{{ product.image }}" class="product-image img-fluid" />
</div>
<div class="col-7">
<div class="product-name productbox-title et-mb-0">{{ product.name }}</div>
</div>
<div class="col-3">
<div class="price_wrapper text-right">
{% if product.has_variations or product.bulk_prices != 0 %}
<span class="price_label pricestarting">
{{ snippets.priceStarting }}
</span>
{% endif %}
{% if product.on_sale %}
<span class="instead-of old-price">
<small class="text-muted-util">
<del class="value">{{ product.original_price | money_eu }} {{ globals.currency_symbol }}</del>
</small>
</span>
{% endif %}
<span class="price productbox-price {% if product.on_sale %} special-price{% endif %}">
<span>{{ product.price | money_eu }} {{ globals.currency_symbol }} <span class="footnote-reference">*</span></span>
</span>
{% if product.base_price > 0 %}
<div class="price-note">
<span class="value">{{ product.base_price | money_eu }} {{ globals.currency_symbol }} {{ snippets.vpePer }} {{ product.base_price_unit }}</span>
</div>
{% endif %}
</div>
</div>
</div>
</a>
</div>
{% endfor %}
<div class="text-center">
<a href="{{ snippets.searchUrl }}?query={{ query }}" class="btn btn-secondary btn-lg">
{{ snippets.showAllResults }}
</a>
</div>
{% else %}
<div class="text-center">
{{ snippets.textNoResults | replace '###QUERY###' query | highlight query 'clerk-live-search-highlight' }}
</div>
{% endif %}
</div>
<div class="col col-sm-4 clerk-live-search-others">
{% if suggestions.length != 0 %}
<div class="h4 headline-style">{{ snippets.headlineSuggestions }}</div>
<div class="clerk-live-search-others-wrapper clerk-suggestion">
{% for suggestion in suggestions %}
<a href="{{ snippets.searchUrl }}?query={{ suggestion }}">
{{ suggestion }}
</a>
{% endfor %}
</div>
{% endif %}
{% if categories.length != 0 %}
<div class="h4 headline-style">{{ snippets.headlineCategories }}</div>
<div class="clerk-live-search-others-wrapper clerk-category">
{% for category in categories %}
<a href="{{ category.url }}">
{{ category.name }}
</a>
{% endfor %}
</div>
{% endif %}
{% if pages.length != 0 %}
<div class="h4 headline-style">{{ snippets.headlinePages }}</div>
<div class="clerk-live-search-others-wrapper clerk-pages">
{% for page in pages %}
<a href="{{ page.url }}">
{{ page.title }}
</a>
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
</div>
CSS Datei:
Content:
Hinzufügen der Facetten
Design erstellen in Clerk (Clerk.io Backend unter Search → Designs)
Nach der Erstellung wird eine ID, diese muss im Plugin Backend(Plugins → Installierte Plugins → S360 Clerk → klick auf Zahnrad → Einstellungen → Facetten Design) hinterlegt werden
Vorlage Design Nova:
Vorlage Design EasyTemplate:
Hinzufügen der Suchergebnisse
Verläuft äquivalent zu den Slidern:
Design erstellen
Content hinzufügen
Einstellungen im Plugin Backend
Anlegen des Design erfolgt im Clerk.io Backend unter Search → Designs.
Vorlage Design Nova:
Vorlage Design EasyTemplate:
Eigene zusätzliche Slider hinzufügen
EasyTemplate
Im EasyTemplate können eigene Slider leicht mit folgenden Schritte integriert werden:
Erstellung des Design im Clerk.io Backend (es können auch bereits vorhandene Designs verwendet werden)
2. Erstellung des Contents mit dem jeweiligen Fokus in Clerk.io , kopieren des nötigen Span Elements
3. Hinzufügen eines HTML Widgets im EasyTemplate
4. Einfügen des Element in einen HTML Widget im EasyTemplate.
Wichtig dabei ist die Zeile data-snippets='{json_encode($s360_clerk_snippets->get())}'
zu dem Clerk HTML Schnipsel aus Schritt 2 hinzuzufügen, damit die Sprachvariablen korrekt an Clerk übergeben werden! Außerdem muss der Haken bei “Smarty evaluieren gesetzt werden”
OnPage Composer
Im OnPage Composer können eigene Slider mit folgenden Schritte integriert werden:
1. Erstellung des Design im Clerk.io Backend (es können auch bereits vorhandene Designs verwendet werden)
2. Erstellung des Contents mit dem jeweiligen Fokus in Clerk.io , kopieren des nötigen Span Elements
3. Öffnen des OnPage Composer
4. Neuer Entwurf im OnPage Composer
5. Rich Text Element per Drag&Drop im Onpage Composer auf die gewünschte ziehen → Quellcode im Menü auswählen und das kopierte Span Elemente hier hinzufügen
6. Speichern → Veröffentlichen mit Zeitraum auswählen
Anmerkung: Je nach Position des “eigenen Sliders”, müssen auch weitere CSS Eigenschaften/Klassen ergänzt werden, wenn nicht das Standard Template verwendet wird.
PHP Events
Das Plugin bietet JTL5_shop Hooks an (https://jtl-devguide.readthedocs.io/projects/jtl-shop/de/latest/shop_plugins/hook_list.html ).
Name | Parameter | Beschreibung |
---|---|---|
| string \Plugin\s360_clerk_shop5\src\Export\InitialOrderFeedBuilder |
|
| array \Plugin\s360_clerk_shop5\src\Export\InitialOrderFeedBuilder |
|
| string \Plugin\s360_clerk_shop5\src\Export\PageFeedBuilder |
|
| array \Plugin\s360_clerk_shop5\src\Export\PageFeedBuilder |
|
| string \Plugin\s360_clerk_shop5\src\Export\BlogFeedBuilder |
|
| array \Plugin\s360_clerk_shop5\src\Export\BlogFeedBuilder |
|
| string \Plugin\s360_clerk_shop5\src\Export\CustomerFeedBuilder |
|
| array \Plugin\s360_clerk_shop5\src\Export\CustomerFeedBuilder |
|
| string \Plugin\s360_clerk_shop5\src\Export\CategoryFeedBuilder |
|
| array \Plugin\s360_clerk_shop5\src\Export\CategoryFeedBuilder |
|
| string \Plugin\s360_clerk_shop5\src\Export\ProductFeedBuilder |
|
| array \Plugin\s360_clerk_shop5\src\Export\ProductFeedBuilder |
|
| \Plugin\s360_clerk_shop5\src\Export\ProductFeedBuilder |
|
| array \Plugin\s360_clerk_shop5\src\Export\ProductFeedBuilder |
|
| \Plugin\s360_clerk_shop5\src\Export\AbstractFeedBuilder |
|
Individualisierung
Die Individualisierung erfolgt über Dateiname_custom, somit kann die jeweilige .tpl Datei erweitert werden (Bsp.: clerk_article_custom.tpl)
Pfad im Plugin | Verwendungszweck |
---|---|
frontend/template/clerk_article.tpl | Enthält das Template und API Parameter um die Produkt darzustellen. |
frontend/template/clerk_category.tpl | Enthält das Template und API Parameter um die Kategorie Slider darzustellen. |
frontend/template/clerk_live_search.tpl | Enthält die wichtigsten Parameter und JS um die Live-Suche darzustellen. |
frontend/template/clerk_config.tpl | Enthält die nötigen JS und Clerk Konfigurationen inklusive Cookieless Tracking / API-Key |
frontend/template/clerk_sales_tracking.tpl | Enthält das Template um den Verkaufsverlauf darzustellen. |
frontend/template/clerk_searchresults.tpl | Enthält die Wichtigsten JS Sachen und API-Parameter um die Suchergebnisse darstellen zu können. |
frontend/template/clerk_shopping_cart.tpl | Enthält das Template + API Parameter für den Warenkorb. |
Formatierungen
Standardformatierung money_eu
:
Formatiert eine Dezimalzahl als Währung unter Verwendung der EU-Formatierungsregeln
Auch möglich money
:
Formatiert eine Dezimalzahl als Währung unter Verwendung der US-Formatierungsregeln
Zusätzlich sind auch eigene Formatierungen möglich:
In my.clerk.io unter Settings > Formatters
Troubleshooting
Sollten Sie Probleme mit dem Plugin beobachten, prüfen Sie zunächst die Logs und wenden Sie sich ggf. an unseren Support oder Ihren Service-Partner, wenn Sie das Problem nicht selbständig lösen können.
Je mehr Informationen Sie dem Support bei einem Problem geben können, desto eher sind wir in der Lage, Ihnen zu helfen. Nicht reproduzierbare Probleme sind dagegen auch nur schwer zu analysieren.
Logs prüfen
Um herauszufinden, wo ein Problem liegt, helfen Ihnen und uns die Logs. Je nach Fehlerbild ist eines der folgenden 3 Logs dafür mehr oder weniger relevant.
Browser-Log
Das Browser-Log ist meist relevant, wenn irgendwas im Frontend des Shops sich merkwürdig verhält oder nicht reagiert. (Beispiel: Sie klicken einen Button und augenscheinlich passiert gar nichts.)
Das Browser-Log sehen Sie, wenn Sie im Browser F12 drücken und dort dann auf Konsole (oder Console) wechseln.
Shop-Log
Das Shop-Log ist immer dann interessant, wenn im Frontend unerwartete Fehlermeldungen ausgegeben werden oder das Plugin zwar auf Eingaben im Frontend reagiert, aber nicht das Ergebnis liefert, was erwartet wurde. Manchmal ergibt sich auch durch das Browser-Log, dass die Informationen eher im Shop-Log zu suchen sind.
Das Shop-Log finden Sie im JTL-Adminbereich unter Administration→ Fehlerbehebung → Logbuch.
Webserver-Log
Das Webserver-Log wird dann relevant, wenn Sie irgendwo auf einen Error 500 (= weiße Seite) stoßen.
Das Webserver-Log kann Ihnen Ihr Hoster zur Verfügung stellen.
FAQ
Ein Slider wurde hinzugefügt, wird aber nicht angezeigt?
Der Selektor wurde falsch gewählt → Lösung: Ein andere Selektor zum einbinden des Plugins/Elements sollte gewählt werden.
Das Slider Einfügemethode ist falsch → Lösung: Meist reicht hier schon die Einfügemethode selbst zu verändern im JTL5-Shop Backend
Der Exporter funktioniert nicht, was tun?
Der Exporter braucht Schreibrechte, da dieser ohne sonst nicht agieren kann.
Die Suche zeigt keine/falsche Ergebnisse?
Prüfen. ob ein Api-Key hinterlegt wurde
Bei mehreren Shops prüfen, ob der richtige Api-Key hinterlegt wurde.
Clerk Import schlägt fehl mit: Server responded with error code 404
Falls der Clerk Import mit der Meldung Server responded with error code 404 fehlschlägt, überprüfen sie folgendes:
Ist der API Schlüssel korrekt eingetragen
Ist der Status des Feed im Plugin “Erfolgreich”
Können Sie den Feed direkt aufrufen? Evtl. vorher die Zugriffbeschränkung testweise deaktivieren
Falls dies nicht hilft, testen Sie statt https://example.com/plugins/s360_clerk_shop5/frontend/feed/{ID_DES_FEED} die URL https://example.com/plugins/s360_clerk_shop5/frontend/feed.php?id={ID_DES_FEED}
Changelog
v1.0.6 (UNRELEASED, T.B.D)
Fix: Kundengruppenrabatt auf Preis entfernen, wenn Produkt Sonderpreis hat
Fix: Sonderpreise für die aktuelle Kundengruppe exportieren
Fix: Falsches Error Logging
Fix: Probleme mit Bild-URL wenn das Hauptbild nicht die Sortiernummer 1 hat
Fix: Falscher Grundpreis bei Sonderpreisen
Added: JTL 5.4 Kompatibilität
Added: Neue Option “Clerk JS Name” um potenzielle Adblocker zu umgehen.
Added: Omni-Suche (Omnisearch)
v1.0.5 (April 2024)
Added: Integration neue Authentifizierungslogik des Produktfeeds gegen Clerk
Added: Artikelnummern von Kindartikeln kumuliert am Vaterartikel
Added: Preis Netto
Changed: Prüfung “Artikel hat Preis ungleich 0” auf Preis > 0.0001 geändert
Fix: Probleme bei Slider Initialisierung nach Variationskombinationswechsel
v1.0.4 (November 2023)
Added: Einstellungen um einzelne Bereiche im Frontend zu aktivieren/deaktivieren hinzugefügt
Added: Einstellungen um Slider auf der Kategorie-Seite anzuzeigen
Changed: Export der Bestellungen nimmt jetzt ALLE Bestellungen in den Feed auf und nicht nur die letzten 1000
Fix: Kategorie-Rabatte werden jetzt im Export mit berücksichtigt
v1.0.3 (Oktober 2023)
Fix: Nutzen der Standard JTL Bildpfad-Logik im Export-Feed
v1.0.2 (September 2023)
Fix: Leere PQ Selektoren verursachen Fehlerlogs
Fix: MySQL GROUP_CONCAT kann bei großen Abfragen zu abgeschnittenen Ergebnissen führen
Removed: Template Kopien aus der Clerk Plugin-Dokumentation entfernt
v1.0.1 (September 2023)
Fix: Leere Produkt-IDs im Order Feed führen zu einem Fehler im Clerk Sync, stattdessen wird nun als ID -1 genutzt
Fix: Facetten mit Umlauten funktionieren nicht
Change: Benutzen von cBestellNr anstatt kBestellung als ID im Order Feed
v1.0.0 (August 2023)
Added: Berücksichtigung der Shop Einstellung "Kategorieanzeige" (ID 115) = "Leere Kategorien ausblenden"
Fix: Sonderpreis wird angezeigt obwohl Sonderpreis nicht aktiv
Fix: "has_variations" Attribut im Produkt-Export ist immer false
Support und Kontakt
siehe Support und Kontakt