Clerk (JTL-Shop 5)

Clerk (JTL-Shop 5)

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

Bereich

Option

Bedeutung

Allgemein

Cookieless Tracking nutzen

Tracking ohne Cookie Nutzung

 

Warenkorb Tracking nutzen?

Informiert Clerk über Änderungen am Warenkorb (allg. Tracking des Warenkorbs)

 

Kindartikel im Warenkorb Tracking berücksichtigen?

Wenn diese Option aktiviert ist, werden bei Variationskombinationen Kindartikel anstatt der Vaterartikel im Warenkorb Tracking genutzt.

Benötigt Plugin Version 1.0.7

 

E-Mails anonymisieren

E-Mail Adressen werden anonymisiert (als Hash) an Clerk übertragen

 

Clerk JS Name

Falls gesetzt wird das Clerk Javascript nicht von https://cdn.clerk.io/clerk.js geladen sondern von https://custom.clerk.io/{name}.js wobei {name} der eingestellte Name ist.

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

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

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

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.

Ab Plugin Version 1.05 wird dieser nicht mehr benötigt und kann leer gelassen. Falls Sie diesen Key doch benötigen, weist Sie Clerk.io darauf hin.

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

Option

Bedeutung

Option

Bedeutung

Produktauswahl für Feed

Welche Produkte sollen im Feed enthalten sein?

  • Alle Produkte,

  • Nur Vaterprodukte,

  • Nur Kindprodukte

Benötigt Plugin Version 1.0.7

Möglichkeiten der Daten Feed Erstellung

Es gibt 3 Möglichkeiten die Generierung der Cron-Jobs anzustoßen:

  1. CLI → Bei CLI wird der Cronjob über den Shop CLI Befehl php cli s360_clerk_shop5:cron aufgerufen

  2. Wawi Abgleich → Cronjob wird beim Wawi Abgleich mit ausgeführt

  3. 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

  1. Feed im Shop Backend einstellen (Plugins → Installierte Plugins → S360 Clerk → klick auf Zahnrad (siehe Bild))

  2. Nach den Einstellungen, den Feed erstellen (Plugins → Installierte Plugins → S360 Clerk → klick auf Doppelpfeil)

  3. Nach erfolgreichem erstellen muss der Feed im Clerk.io Backend hinterlegt werden:

Feed erfolgreich erstellt (siehe Status und ID) und die URL ist vorhanden (siehe grüner Kasten)

 

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:

  1. Öffnen des Clerk.io Backends

  2. Design erstellen

  3. Content hinzufügen

  4. 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">&nbsp;</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">&nbsp;</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)

Warenkorb (NOVA) mit Design und Produktlogik “Best Sellers” in Clerk.io

 

Die nun folgende Seite beinhaltet 4 wichtige Abschnitte:

  1. Name your content → Hier wird der Name festgelegt

  2. Choose product logic → Hier kann die Produktlogik ausgewählt werden, unter anderem “Best Sellers” / “Hot Products” und vieles mehr

  3. 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)

  4. 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

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.

Backend Clerk.io
Plugin Backend

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:

#clerk-template-live-search { background: var(--white); padding: 1rem; box-shadow: 0 0 1.5rem rgba(0, 0, 0, 0.2); } #clerk-template-live-search .product { margin-bottom: 1rem; } .clerk-live-search-container .clerk-live-search-others a { text-decoration: none; display: block; margin-bottom: 0.3125rem; } .clerk-live-search-others-wrapper .clerk-category { display: flex; flex-wrap: wrap; }

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

Facetten ID nach Erstellung
Facetten ID im Plugin

 

Vorlage Design Nova:

<div class="row"> <aside class="sidepanel-left d-print-none col-12 dropdown-full-width"> <div class="box box-normal"> <div id="clerk-facets-headline-count" class="productlist-filter-headline d-none d-md-flex"> Filter und Sortierung&nbsp;<span class="value"></span> </div> <!-- Reset Filter Button --> {% assign isActive = 0 %} {% for facet_group in facets %} {% for facet in facet_group.facets %} {% if facet.selected %} {% assign isActive = 1 %} {% endif %} {% endfor %} {% endfor %} {% if isActive %} <div title="Alle Filter zurücksetzen" class="snippets-filter-item-all btn btn-danger btn-sm"> <span class="et-active-filter-name">Alle Filter zurücksetzen</span><i class="fas fa-times snippets-filter-item-icon-left"></i> </div> {% endif %} </div> <!-- Sorting --> <div class="box box-filter word-break"> <div class="nav-panel"> <ul class="nav flex-column"> <li class="nav-item dropdown facet-sort"> <span class="nav-link dropdown-toggle" role="button" data-toggle="collapse" data-target="#facet-group-sort" aria-expanded="false"> Sortierung </span> <div class="collapse snippets-categories-collapse " id="facet-group-sort"> <div id="clerk-sort"> <div class="link-discreet filter-item js-clerk-sort" data-sort="asc_price" title="Preis aufsteigend"> <span class="et-filter-option-name filter-item-value">Preis aufsteigend</span> </div> <div class="link-discreet filter-item js-clerk-sort" data-sort="desc_price" title="Preis absteigend"> <span class="et-filter-option-name filter-item-value">Preis absteigend</span> </div> <div class="link-discreet filter-item js-clerk-sort" data-sort="asc_age" title="Neueste zuerst"> <span class="et-filter-option-name filter-item-value">Neueste zuerst</span> </div> <div class="link-discreet filter-item js-clerk-sort" data-sort="asc_name" title="Artikelname von A bis Z"> <span class="et-filter-option-name filter-item-value">Artikelname von A bis Z</span> </div> <div class="link-discreet filter-item js-clerk-sort" data-sort="desc_name" title="Artikelname von Z bis A"> <span class="et-filter-option-name filter-item-value">Artikelname von Z bis A</span> </div> </div> </div> </li> </ul> </div> <hr class="box-filter-hr"> </div> <!-- Facet Groups --> {% for facet_group in facets %} <div class="box box-filter word-break"> <div class="nav-panel"> <ul class="nav flex-column"> {% assign activeGroup = 0 %} {% for facet in facet_group.facets %} {% if facet.selected %} {% assign activeGroup = 1 %} {% endif %} {% endfor %} <!-- Facet Group --> <li class="nav-item dropdown facet-{{ facet_group.group }}"> <span class="nav-link dropdown-toggle" role="button" data-toggle="collapse" data-target="#facet-group-{{ facet_group.title }}" aria-expanded="{% if activeGroup == 1}true{% else %}false{% endif %}"> {{ facet_group.title }} </span> <!-- Facets --> <div class="snippets-categories-collapse {% if activeGroup == 1}collapsed show{% else %}collapse{% endif %}" id="facet-group-{{ facet_group.title }}"> {% if facet_group.type == "range" %} <div class="filter-item clerk-range stagio_range" data-group="{{ facet_group.group}}" data-min="{{ facet_group.min }}" data-max="{{ facet_group.max }}" data-start="{{ facet_group.start }}" data-end="{{ facet_group.end }}" data-step="auto"> </div> {% endif %} {% for facet in facet_group.facets %} <div class="filter-item clerk-facet {% if facet.selected %} active clerk-facet-selected {% endif %}" data-facet="{{ facet_group.group }}" data-value="{{ facet.value }}" data-min="{{ facet.min }}" data-max="{{ facet.max }}" title="{{ facet.name }}" > <div class="box-link-wrapper"> {% if facet.selected %} <i class="far fa-check-square snippets-filter-item-icon-right"></i> {% else %} <i class="far fa-square snippets-filter-item-icon-right"></i> {% endif %} <span class="word-break">{{ facet.name }}</span> <span class="badge badge-outline-secondary">{{ facet.count }}</span> </div> </div> {% endfor %} </div> </li> </ul> </div> <hr class="box-filter-hr"> </div> {% endfor %} </aside> </div> <script> if (!window.s360_clerk) { window.s360_clerk = {}; } Clerk('on', 'rendered', '#clerk-search', function(content, data) { window.s360_clerk.query = data.query; // add product count to facet headline $("#clerk-facets-headline-count .value").html(data.count); // register sort layers $("#clerk-sort .js-clerk-sort").on('click', function() { let val = $(this).data('sort'); let or = (val.split('_')[0] == 'null') ? eval(val.split('_')[0]) : val.split('_')[0]; let orb = (val.split('_')[1] == 'null') ? eval(val.split('_')[1]) : val.split('_')[1]; window.s360_clerk.sort = val; Clerk('content', '[data-target][data-query][data-template][data-clerk-content-id]', 'param', { orderby: orb, order: or }); }); // function for remove all filter button $('.snippets-filter-item-all').on('click', function (e) { e.preventDefault(); window.location.href = window.location.href.split('?')[0] + "?query=" + window.s360_clerk.query; }); // set sort layer active if (window.s360_clerk.sort) { let sortActive = $('#clerk-sort .js-clerk-sort[data-sort=' + window.s360_clerk.sort + ']'); if (sortActive.hasClass("active") === false) { sortActive.addClass("active"); sortActive.append('<i class="fas fa-check ml-auto pl-1"></i>'); sortActive.data("sort", "null_null"); } } }); </script>

Vorlage Design EasyTemplate:

<div class="row"> <div class="col-12 et-product-list-filter-wrapper"> <div class="et-product-list-filter-top-wrapper"> <div class="bg-gray-lighter et-pt-10 et-pt-md-30 et-pb-15 et-mb-30"> <div class="headline-style h2 d-none d-md-block"> Filter und Sortierung </div> <div class="d-flex flex-wrap justify-content-center justify-content-md-start et-product-list-filter-top et-filters-active" data-more-filters-limit="{&quot;xs&quot;:0,&quot;sm&quot;:0,&quot;md&quot;:0,&quot;lg&quot;:0,&quot;xl&quot;:0}"> <div class="col-6 col-sm-auto d-lg-none et-product-list-filter-mobile text-right"> <div id="et-product-list-filter-collapse-trigger-mobile" class="et-product-list-filter-collapse-trigger-mobile et-collapse btn btn-filter" data-toggle="collapse" aria-expanded="true" data-target="#et-product-list-filter-collapse-content-mobile" aria-controls="et-product-list-filter-collapse-content-mobile"> <i class="fas fa-filter"></i> Filtern </div> </div> <div id="et-product-list-filter-collapse-content-mobile" class="col-12 et-product-list-filter-collapse-content-mobile collapse"> <div class="row"> <div class="col w-100 et-product-list-filter-filters"> <div class="row row-cols-1 row-cols-sm-2 row-cols-md-4 row-cols-lg-4 row-cols-xl-6"> <!-- Sorting --> <div class="col et-product-list-filter-item"> <div class="dropdown et-product-list-filter-sort"> <button class="btn btn-filter dropdown-toggle et-dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-display="static"> Sortieren <i class="fas fa-angle-up et-dropdown-open"></i> <i class="fas fa-angle-down et-dropdown-closed"></i> </button> <div class="dropdown-menu" id="clerk-sort"> <div class="link-discreet dropdown-item js-clerk-sort" data-sort="asc_price" title="Preis aufsteigend"> <span class="et-filter-option-name filter-item-value">Preis aufsteigend</span> </div> <div class="link-discreet dropdown-item js-clerk-sort" data-sort="desc_price" title="Preis absteigend"> <span class="et-filter-option-name filter-item-value">Preis absteigend</span> </div> <div class="link-discreet dropdown-item js-clerk-sort" data-sort="asc_age" title="Neueste zuerst"> <span class="et-filter-option-name filter-item-value">Neueste zuerst</span> </div> <div class="link-discreet dropdown-item js-clerk-sort" data-sort="asc_name" title="Artikelname von A bis Z"> <span class="et-filter-option-name filter-item-value">Artikelname von A bis Z</span> </div> <div class="link-discreet dropdown-item js-clerk-sort" data-sort="desc_name" title="Artikelname von Z bis A"> <span class="et-filter-option-name filter-item-value">Artikelname von Z bis A</span> </div> </div> </div> </div> <!-- Facet Groups --> {% for facet_group in facets %} {% assign activeGroup = '' %} {% for facet in facet_group.facets %} {% if facet.selected %} {% assign activeGroup = ' active ' %} {% endif %} {% endfor %} <div class="col et-product-list-filter-item"> <div class="dropdown et-product-list-filter-{{ facet_group.group }}"> <button class="btn btn-filter dropdown-toggle et-dropdown-toggle{{ activeGroup }}" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-display="static"> <span class="text-truncate">{{ facet_group.title }}</span> <i class="fas fa-angle-up et-dropdown-open"></i> <i class="fas fa-angle-down et-dropdown-closed"></i> </button> <div class="dropdown-menu"> {% if facet_group.type == "range" %} <div class="clerk-range stagio_range" data-group="{{ facet_group.group}}" data-min="{{ facet_group.min }}" data-max="{{ facet_group.max }}" data-start="{{ facet_group.start }}" data-end="{{ facet_group.end }}" data-step="auto"></div> {% endif %} {% for facet in facet_group.facets %} <div class="clerk-facet {% if facet.selected %} clerk-facet-selected {% endif %} nav-link filter-item d-flex align-items-center" data-facet="{{ facet_group.group }}" data-value="{{ facet.value }}" data-min="{{ facet.min }}" data-max="{{ facet.max }}" title="{{ facet.name }}" rel="nofollow"> <i class="far fa{% if facet.selected %}-check{% endif %}-square snippets-filter-item-icon-right"></i> <span class="et-filter-option-name filter-item-value">{{ facet.name }}</span> <span class="badge badge-outline-secondary">{{ facet.count }}</span> </div> {% endfor %} </div> </div> </div> {% endfor %} </div> </div> <!-- Active Filters --> {% assign isActive = 0 %} {% for facet_group in facets %} {% for facet in facet_group.facets %} {% if facet.selected %} {% assign isActive = 1 %} {% endif %} {% endfor %} {% endfor %} {% if isActive %} <div class="col-12 et-product-list-filter-actions"> <div id="active-filters" class="active-filters"> {% for facet_group in facets %} {% for facet in facet_group.facets %} {% if facet.selected %} <div class="clerk-facet clerk-facet-selected filter-type-{{ facet_group.group }} snippets-filter-item et-active-filter btn btn-xs btn-secondary" data-facet="{{ facet_group.group }}" data-value="{{ facet.value }}" data-min="{{ facet.min }}" data-max="{{ facet.max }}" title="Diesen Filter entfernen" rel="nofollow"> <span class="et-active-filter-value">{{ facet.name }}</span> <i class="fas fa-times snippets-filter-item-icon-left"></i> </div> {% endif %} {% endfor %} {% endfor %} <div title="Alle Filter zurücksetzen" class="snippets-filter-item-all et-active-filter-clear btn btn-danger btn-xs"> <span class="et-active-filter-name">Alle Filter zurücksetzen</span><i class="fas fa-times snippets-filter-item-icon-left"></i> </div> </div> </div> {% endif %} </div> </div> </div> </div> </div> <div class="et-product-list-filter-total" id="clerk-facets-headline-count" > <span class="value"></span> Artikel </div> </div> </div> <script> if (!window.s360_clerk) { window.s360_clerk = {}; } Clerk('on', 'rendered', '#clerk-search', function(content, data) { window.s360_clerk.query = data.query; // add product count to facet headline $("#clerk-facets-headline-count .value").html(data.count); // register sort layers $("#clerk-sort .js-clerk-sort").on('click', function() { let val = $(this).data('sort'); let or = (val.split('_')[0] == 'null') ? eval(val.split('_')[0]) : val.split('_')[0]; let orb = (val.split('_')[1] == 'null') ? eval(val.split('_')[1]) : val.split('_')[1]; window.s360_clerk.sort = val; Clerk('content', '[data-target][data-query][data-template][data-clerk-content-id]', 'param', { orderby: orb, order: or }); }); // function for remove all filter button $('.snippets-filter-item-all').on('click', function (e) { e.preventDefault(); window.location.href = window.location.href.split('?')[0] + "?query=" + window.s360_clerk.query; }); // set sort layer active if (window.s360_clerk.sort) { let sortActive = $('#clerk-sort .js-clerk-sort[data-sort=' + window.s360_clerk.sort + ']'); if (sortActive.hasClass("active") === false) { sortActive.addClass("active"); sortActive.append('<i class="fas fa-check ml-auto pl-1"></i>'); sortActive.data("sort", "null_null"); } } }); </script>

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.