Wozu braucht ein Unternehmen ein DAM, wenn es schon ein CMS hat?

DAM vs. CMS Headerbild

Ein Content Management System (CMS) wird mittlerweile in nahezu jedem Unternehmen eingesetzt, um den digitalen Content auf einer Plattform zu managen und von dort aus in die Marketingkanäle zu verteilen. Ein Digital Asset Management System (DAM) ist allerdings in vielen Unternehmen noch keine Selbstverständlichkeit. Schließlich verfügt auch jedes Content Management System über eine Mediendatenbank. Dort werden die verwendeten digitalen Mediendateien wie Bilder, Videos oder PDFs hochgeladen, abgelegt und in die verschiedenen Kanäle wie Corporate Website, E-Commerce-Seiten, Blogs, Social Media etc. ausgespielt. So weit, so gut.

„Wozu braucht ein Unternehmen ein DAM, wenn es schon ein CMS hat?“ weiterlesen

How to: Sitecore Content Search – Globale LINQ Filter anwenden

Sitecore Global Linq Filter

Seit der Sitecore Version 7.2. ist es möglich, für die Content Search LINQ Filter zu implementieren, die automatisch bei jedem LINQ Query angewendet werden. Dadurch können “statische” Filter wie z.B. die Einschränkung nach Kontextsprache einmalig angegeben werden und brauchen somit nicht bei jeder Abfrage berücksichtigt zu werden.

Um globale LINQ Filter einzubinden, muss die Pipeline <contentSearch.getGlobalLinqFilters> erweitert werden:

Achtung: Das folgende Beispiel ist bis einschließlich der Sitecore Version 8.1 möglich.

[xml]
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">;
<sitecore>
<pipelines>
<contentSearch.getGlobalLinqFilters>
<processor type="Comspace.Demo.GlobalLinqFilter.ContextLanguageLinqFilter, Comspace.Demo.GlobalLinqFilter"/>
</contentSearch.getGlobalLinqFilters>
</pipelines>
</sitecore>
</configuration>
[/xml]

Die Klasse ContentLanguageLinqFilter erbt von der bereitgestellten Basisklasse ApplyGlobalLinqFilters, welche zwei überschreibbare Funktionen bereitstellt:

  • Process(QueryGlobalFiltersArgs args)
  • GetQuery(QueryGlobalFiltersArgs args)

Um nun nach der aktuellen Sprache zu filtern, muss die Query angepasst werden. Hierfür wird die Funktion GetQuery überschrieben:

[csharp]
namespace Comspace.Demo.GlobalLinqFilter
{
public class ContextLanguageLinqFilter : ApplyGlobalLinqFilters
{
protected override object GetQuery(QueryGlobalFiltersArgs args)
{
var query = (IQueryable<SearchResultItem>)args.Query;
return query.Where(i => i["_language"].Equals(Sitecore.Context.Language.Name));
}
}
}
[/csharp]

In diesem Beispiel wird das Objekt args.Query in den Typen IQueryable<SearchResultItem> umgewandelt.

GlobalLinqFilter ab Sitecore Version 8.2

Mit der Sitecore Version 8.2 ändert sich die Verwendung von Queries im Sitecore, sodass ein allgemeines Casting in den Typen IQueryable<SearchResultItem> nicht mehr möglich ist. Wird ein GlobalLinqFilter wie oben beschrieben eingesetzt, wirft Sitecore bereits bei der Initialisierung bzw. beim Öffnen des Sitecore Content Editors eine Exception:

[text]
Das Objekt des Typs "Sitecore.ContentSearch.Linq.Parsing.GenericQueryable`2[Sitecore.ContentSearch.SearchTypes.SearchResultItem,Sitecore.ContentSearch.Linq.Solr.SolrCompositeQuery]" kann nicht in Typ "System.Linq.IQueryable`1[Sitecore.Social.Search.SearchItem]" umgewandelt werden.

[/text]

Und jetzt?

Zu der Verwendung von GlobalLinqFilter existiert keine nennenswerte Dokumentation. Auch Google liefert nur ein mageres Beispiel von Coveo, das aber nicht für Sitecore ab Version 8.2 geeignet ist.

Der daher konsultierte Sitecore Support stellt folgende Lösung zur Verfügung:

[csharp]
public override void Process(QueryGlobalFiltersArgs args)
{
if ((args != null) && (args.Query != null))
{
Type queryElementType = args.QueryElementType;
if (queryElementType == typeof(SearchResultItem))
{
args.Query = this.GetQuery&lt;SearchResultItem&gt;(args);
}
}
}

protected object GetQuery<T>(QueryGlobalFiltersArgs args) where T : IObjectIndexers
{
var query = (IQueryable<T>)args.Query;

return query.Where(i => i["_language"].Equals(Sitecore.Context.Language.Name));
}
[/csharp]

In diesem Beispiel wird nicht mehr die überschreibbare Funktion GetQuery verwendet, sondern eine eigene, generische Funktion implementiert. Ziel ist es, die Query, die im GlobalLinqFilter als Typ object übergeben wird, in den Zieltypen umzuwandeln. Hierfür liefern die QueryGlobalFiltersArgs auch die QueryElementType-Eigenschaft mit.

Problem: Ein Objekt lässt sich nicht mithilfe einer Variablen typisieren.

Lösung: Um GlobalLinqFilter trotzdem anwenden zu können, muss nun also die Process Methode überschrieben werden. Darin wird der übergebene Typ geprüft und anschließend mit einer expliziten Typisierung die GetQuery<T> Funktion aufgerufen.

Vorteil:

  • Es werden nur solche Queries eingeschränkt, die auch erwünscht sind, da die Abfrage explizit in der Process Methode angegeben muss.

Nachteil:

  • Werden mehrere spezielle Typen von SearchResultItem implementiert, z.B. ExtendedSearchResultItem, DateSearchResultItem, etc. muss für jeden dieser Typen eine Abfrage im GlobalLinqFilter eingerichtet werden.

Der Nachteil äußert sich in der Implementierung dann folgendermaßen:

[csharp]
public override void Process(QueryGlobalFiltersArgs args)
{
if ((args != null) && (args.Query != null))
{
Type queryElementType = args.QueryElementType;
if (queryElementType == typeof(SearchResultItem))
{
args.Query = this.GetQuery<SearchResultItem>(args);
}
if (queryElementType == typeof(ExtendedSearchResultItem))
{
args.Query = this.GetQuery<ExtendedSearchResultItem>(args);
}
}
}
[/csharp]

Zusammenfassung

GlobalLinqFilter sind ein probates Mittel, um Queries standardmäßig nach bestimmten Kriterien zu filtern. Kriterien können neben der hier gezeigten Sprache auch Sicherheitskriterien, Templates oder Sites sein. Wenn nicht exzessiv spezielle SearchResultItem Typen implementiert wurden und somit der oben beschriebene Nachteil eher überwiegt, ist die Nutzung von GlobalLinqFilter zu empfehlen.

Übrigens: Wen das Thema Sitecore Content Search interessiert, findet hier einen Einstieg in das Thema Sitecore Solr Content Search – Facettensuche richtig anwenden.

 

Sitecore Solr Content Search – Facettensuche richtig anwenden

Sitecore Solr Content Search

Eine Facettensuche eignet sich insbesondere für folgende Anwendungsfälle:

  • Ermittlung von Kategorien
  • Implementierung einer Sortierungsfunktion
  • Implementierung eines Filterelements auf einer Suchseite

Wie eine Facettensuche implementiert wird, ist in der Sitecore Dokumentation zu finden. Darin wird folgendes Beispiel gegeben:

[csharp]
var results = queryable.FacetOn(d => d.Name);
var facets = results.GetFacets();
foreach (var category in facets.Categories)
{
Console.WriteLine(category.Name);
   foreach (var facetValue in category.Values) {
       Console.WriteLine("{0}: {1}", facetValue.Name, facetValue.Aggregate);
   }
}
[/csharp]

Als Ergebnis erhält man eine Auflistung einer Kategorie (category.Name) aller zugewiesenen Werte des Feldes „Name“ (d.Name).

Beispiel: Produkte nach Serien filtern

Ein Beispiel: Es existiert ein Index mit Produkten. Diese Produkte sind einer Serie zugeordnet. Als Feature möchte man nun alle Produkte einer bestimmten Serie filtern können. Um einen Filter zu implementieren, kann eine Facettensuche wie im oben zu sehenden Beispiel verwendet werden. Es ist lediglich eine Änderung erforderlich:

[csharp]
var results = queryable.FacetOn(d => d[“Serie”]);
[/csharp]

Die Suche ermittelt somit alle Inhalte, die an indizierten Produkten im Feld “Serie” enthalten sind. Das Ergebnis kann anschließend in ein Benutzersteuerelement eingefügt werden.

Facettensuche mit Solr

Wenn eine Facettensuche auf einem Objekt vom Typ Queryable angewendet wird, die zuvor bereits einen Filter enthält, z.B.

[csharp]
queryable.Where(d => d.Language.Equals("en")
[/csharp]

funktioniert die Facettensuche mit Solr nicht mit dem oben angegebenen Beispiel (anders als bei einer Facettensuche mit Lucene), da hier als Ergebnis immer alle Facetten zurückgegeben werden, unabhängig von der Einschränkung durch den Filter.

Solr Hint: Facet.mincount Parameter

Der Grund: Standardmäßig werden bei einer Solr Facettensuche alle Facetten zurückgegeben. Verantwortlich ist hierfür der Facet.mincount Parameter, der als defaultValue “0” zurückgibt. Somit werden auch Facetten zurückgegeben, zu denen der Filter keine Ergebnisse zurückgibt.

Um dieselbe Funktionalität wie bei einer Facettensuche mit Lucene herzustellen, muss der Facet.mincount Parameter überschrieben werden, wie im folgenden Beispiel zu sehen ist:

[csharp]
var results = queryable.FacetOn(d => d[“Serie”], 1);
[/csharp]

Der zweite Parameter der FacetOn() Methode gibt den minimumResultCount an, welcher dem Facet.mincount Parameter entspricht. Gibt man hier beispielsweise den Wert “1” an, wird bei einer Facettensuche nur ein Ergebnis zurückgegeben, dessen Elemente mindestens einmal in einer Suche mit entsprechenden Filtern vorkommen. Im vorherigen Beispiel werden somit nur Elemente aufgelistet, die in der Sprache “en” vorliegen.

Trivia

Der für diesen Anwendungsfall konsultierte Sitecore Support hat das unterschiedliche Verhalten der Facettensuche mit Lucene bzw. Solr als Bug in der Sitecore Version 8.2. rev. 161115 (Update 1) eingestuft und unter der Public reference number 95560 eingeordnet. Als Hotfix wird die Angabe des minimumResultCount wie zuvor beschrieben empfohlen.

Wenn Sie neben der Facettensuche auch noch Ihre LINQ Abfragen verschlanken möchten, finden Sie hier einen weiteren Tipp: How to: Sitecore Content Search – Globale LINQ Filter anwenden

Servus! aus München von der Sitecore Usergroup

Auch das neue Jahr startet wieder mit einem herausragenden Sitecore Usergroup Treffen, das erste Mal im Süden Deutschlands, in München. Dank der Firma CELUM durften wir dieses Mal Gäste in den wunderschönen Design Offices im Arnulfpark München sein.

Eingang zum DesignOffice

Die Agenda

Die Agenda versprach auch dieses Mal wieder hochinteressante Themen:

    • Gerd Laski & Michael Sahlender, CELUM: Besser, schneller, effektiver – Wie Sie mit Digital Asset Management Ihre Geschäftsprozesse optimieren
    • Friederike Heinze, comspace: CELUM Connector und das Sitecore Data Exchange Framework
    • Maksym Ponomarenko, netzkern AG: Sitecore und Salesforce
    • Christian Handel, ecx.io – an IBM company: Getting Started with Unicorn Item Synchronization
    • Mark Cassidy, CassidyConsult: An awesome presentation about the Rules Engine
    • Chris Wojciech, netzkern AG: Build a very simple Website Demo with Sitecore Experience Accelerator (SxA)
    • Get Together im Augustiner-Keller zu München

Kurzvorstellung CELUM – Das Digital Asset Management

Im ersten Beitrag des Tages stellten sich die Gastgeber von CELUM, der Geschäftsführer Deutschland Michael Sahlender und der Director Partner Management Gerd Laski vor und erläuterten, was ihr Produkt CELUM DAM für Vorteile und Nutzen bietet. So können über das DAM die Rechte an digitalen Medien zentral verwaltet und gesteuert werden. Außerdem kann verfolgt werden, welche Inhalte in welche Kanäle publiziert wurden. Zusätzlich bietet das CELUM DAM viele Schnittstellen zu anderen Systemen, sei es ERP/PIM, Ecommerce oder andere Umgebungen. Weitere Informationen zum CELUM DAM gibt es hier.

Präsentation CELUM

CELUM Connector und das Sitecore Data Exchange Framework

Die Vorstellung von CELUM bot eine gute Überleitung zum eigentlich Sitecore Thema – Ein Celum Connector, der mithilfe des Sitecore Data Exchange Framework umgesetzt wurde. In der kurzweiligen Präsentation (Wenn die Hardware nicht so mitmacht wie geplant, muss man eben improvisieren…;-)) konnte Friederike Heinze (@ilovesitecore) allen Interessierten aufzeigen, wie einfach die Contentpflege mit direkt synchronisierten Inhalten aus dem CELUM DAM ist.

CELUM Connector
CELUM Connector – Hardware Herausforderung

Und was steckt dahinter?

Für den CELUM Connector bzw. die Synchronisation zwischen DAM und CMS wird das Sitecore Data Exchange Framework verwendet. Was genau dahinter steckt, beschreibt Friederike in einem eigenen Blogbeitrag.

Leadgenerierung mit Sitecore und Salesforce

Wie auf einfache Art und Weise Leads im CRM System Salesforce generiert werden können, hat Maksym Ponomarenko mit dem Salesforce Connect Module demonstriert. So können beispielsweise im Zusammenspiel mit dem Web Forms for Marketers Modul einfache Save Actions implementiert werden, die bei einer Newsletter-Anmeldung oder einer Kontaktanfrage Formularinhalte direkt ins CRM aufnehmen.

Salesforce CRM Modul

Unicorn Item Synchronization

Jeder, der sich schon einmal mit dem Sitecore Habitat auseinandergesetzt hat, wird zumindest auch schon etwas über das Serialisierungstool Unicorn gehört haben, mit dem Sitecore Items in verschiedenen Umgebungen synchronisiert werden können. Im Gegensatz zu Team Development for Sitecore (TDS), das als kommerzielles Produkt von Hedgehog vertrieben wird (die Kollegen von Hedgehog durften wir bei der letzten SUG als Gäste begrüßen), ist Unicorn als OpenSource im Git verfügbar. Somit kann es frei und vor allem einfach per NuGet Package installiert werden:

PM> Install-Package Unicorn

Christian Handel hat in seinem Beitrag veranschaulicht, wie Unicorn eingerichtet werden muss und wie es grundsätzlich funktioniert. Als rein dateibasierte Synchronisation werden Änderungen live übernommen und können mit bewährten Versionierungstools wie Git, TFS oder SVN verteilt werden. Die YAML-basierte Item Serialisierung ermöglicht dabei auch bei Versionskonflikten eine einfache, weil lesbare Konfliktbehebung.

Insgesamt konnten dabei Vor- und Nachteile gegeneinander abgewogen werden. Unter den Zuhörern zeigte sich jedoch, dass Unicorn zumindest in der deutschen Community noch kein festes Standbein besitzt. Auf Nachfrage, welches Synchronisationstool verwendet wird, meldeten sich die meisten für TDS.

Unicorn

Sitecore Rules Engine – Mark zaubert

Mark Cassidy von Cassidy Consult, mittlerweile gefühlt Stammgast bei der SUG, hat auf beeindruckende Art und Weise demonstriert, wie man mit wenigen Handgriffen mit Sitecore Rules das Verhalten von Interaktionen im Sitecore beeinflussen kann. Als Beispiel diente der Anwendungsfall, Items hinzuzufügen. Die Präsentation sowie alle gezeigten Codebeispiele wurden von Mark auf GitHub veröffentlicht.

Build a very simple SxA website

Schon wieder ein neues Sitecore Modul

Als letzten Beitrag konnte dieses Mal Chris Wojciech mit seiner Demonstration des SxA (Sitecore Experience Accelerator) überzeugen. Mit dem typischen Beispiel “Build a very simple website” (quasi “Hello World!”) hat er in rund 15 Minuten eine Seite aufgebaut, ohne dafür eine Zeile selbst programmieren zu müssen.

Der SxA liefert dafür die gängigen Module und Konfigurationen out-of-the-box. Insbesondere für die Konzeptions- und Designphase geeignet, ist es als besonderes Feature möglich, mit dem SxA erstellte Wireframes zu exportieren. Der Html-Export kann dann von Frontendentwicklern gestylt werden und anschließend wieder nach Sitecore in das SxA Modul importiert werden. Das fertige Design ist dann direkt nutzbar. Weitere Informationen zum Modul können direkt bei Sitecore bezogen werden: Sitecore Experience Accelerator.

Get Together! Ab in den Keller!

Wo sonst sollte man in der bayerischen Hauptstadt ein Get Together veranstalten, wenn nicht in einem bayrischen Wirtshaus, in dem Bier ausgeschenkt wird. Daher ging es in den Augustiner-Keller – und zwar wörtlich. Um in den Lagerkeller zu gelangen, musste zuerst eine gefühlt 15m lange Wendeltreppe bewältigt werden. Unten angelangt, bot sich jedem ein uriges Bild, was man sogar auf Google Maps begutachten kann. Neben “Brezn” und traditionellen Gerichten kam schnell die bewährte Get Together-Stimmung auf.

Der Schneeballeffekt

Auf dem mittlerweile achten Sitecore User Group Treffen hat sich gezeigt, dass die Community immer größer wird. Mit offiziell über 50 TeilnehmerInnen waren so viele dabei wie an keinem anderen Treffen zuvor. Falls ihr noch nicht dabei wart, aber beim nächsten Mal gerne mitmachen möchtet, schaut doch mal in der XING Gruppe Sitecore User Group Deutschland vorbei. Das nächste Treffen findet voraussichtlich im April in Bremen statt. Seid gespannt! Ich freue mich drauf!

 

Sitecore Data Exchange Framework?

Sitecore Data Exchange Framework

In den letzten Wochen habe ich intensiv an der Implementierung eines Sitecore Celum Connectors gearbeitet. Celum ist ein Digital Asset Management System, als solches verwaltet es alle Assets zentral und liefert diese an diverse Kanäle aus – online oder auch für den Druck.
Da wir uns entschlossen haben, Bilder welche auf der Webseite zum Einsatz kommen, auch in Sitecore vorzuhalten, ist ein großer Part der Integration die Synchronisation der Bilder zwischen beiden Systemen. Beim Stichwort “Synchronisation” kam mir sofort  das im August von Sitecore veröffentlichte
Data Exchange Framework in den Sinn. Da ich damit bisher noch gar nicht gearbeitet habe, musste ich mich zunächst mal in den Umfang und die zugrunde liegende Philosophie dieses Frameworks einarbeiten. Die ersten theoretischen Ergebnisse möchte ich hier und jetzt mit euch teilen. In einem späteren Beitrag werde ich dann über meine ersten Erfahrungen aus der Praxis berichten.

Kurzdefinition

Das Data Exchange Framework dient der Verknüpfung zweier System welche Daten miteinander austauschen, es ist ein sog.  ETL-Tool.  In der Regel ist Sitecore eines der Systeme welches sich mit einem Drittsystem verbindet, das muss aber nicht so sein.

Einsatzmöglichkeiten

Zahlreiche Einsatzmöglichkeiten für das Data Exchange Framework sind denkbar. So kann das neue Framework etwa

  • Produkte > Sitecore Items
  • Externe Bilder > Sitecore Items
  • Kontakte > xDB Contacts
  • u.v.m.

verbinden. Der Einsatz kommt einfach immer dann in Frage, wenn Daten aus einem Drittsystem auch in Sitecore vorgehalten werden müssen.

Warum so ein Framework?

Noch ein Framework? Es gibt doch schon so viele Integrationen… Aber jeder Partner und jedes Modul findet seine eigene Lösungen.

Sitecore geht es mit dem Framework um eine einheitliche Anbindung, um Einfachheit, Stabilität und Wartbarkeit zu erreichen. Außerdem werden die Einstellungen, die sonst meist durch Entwickler in den entsprechenden Konfigurationsdateien vorgenommen werden (Tasks, Pipelines, Pipeline Steps), dann zukünftig als Sitecore Items konfiguriert.

Und das Beste, wie ich finde: auch das Attributmapping kann mit dem neuen Framework vollständig über die Oberfläche konfiguriert werden.

Sitecore Data Exchange Framework

Sitecore hat sich mit dem Framework folgende Ziele gesetzt:

  1. Einheitliches Modell zum lesen, schreiben und verknüpfen von Daten
  2. Flexibilität derzeitiger Ansätze beibehalten (aber nicht nur für Entwickler)
  3. Entwicklung eines Providers nicht nur für langjährige Sitecore-Experten ermöglichen.

Sitecore selbst hat auch schon erste Provider für Data Exchange Framework implementiert: Dynamics CRM Connect (Contacts, Entities), Dynamics AX (Product Catalog).

Genau solche Provider werden wir als Sitecore Partner dann zukünftig gegen die APIs der Drittsysteme unserer Kunden entwickeln. Das Mapping der Daten übernimmt dann das Sitecore Data Exchange Framework für uns.

Und was ist eigentlich das xConnect?

Sitecore hat auf dem Symposium 2016 in New Orleans das xConnect Framework für Anfang nächsten Jahres angekündigt. Beim xConnect Framework geht es um die Integration von Daten aus Drittsystemen in die Sitecore xDB. xConnect beinhaltet nicht das Attributmapping selbst, dafür ist wiederum das Data Exchange Framework zuständig.

Neugierig geworden?

Dann möchte ich euch folgende Links ans Herz legen:

  • Webinar mit Adam Conn (Director of Technical Product Management): Intro to Data Exchange Framework
  • Dokumentation Data Exchange Framework inkl. Schritt für Schritt Anleitung für die Implementierung eines eigenen Data Providers.
  • Und eine Beispielimplementierung eines File System Providers (CSV) bei GitHub .

So das war’s erstmal von mir. Jetzt tauche ich in die Umsetzung eines eigenen Data Providers ab. Ich bin gespannt…

Das war das Sitecore Usergroup Treffen im September 2016 in Berlin

Metro Systems - Upgrade auf Sitecore 8.1

Letzte Woche fand das mittlerweile sechste, und in diesem Jahr letzte, Sitecore Usergroup Deutschland Treffen statt, dieses Mal in der Hauptstadt Berlin im Aufbauhaus, mitten in Kreuzberg. Um 13:30 fanden wir uns im TAK (Theater im Aufbauhaus) ein, welches sich selbst “als ein Ort der Begegnung, offen für Ideen, kühne Visionen, Austausch und Kontroversen” versteht.

Aufbauhaus Berlin
Aufbauhaus Berlin

Auch bei diesem Treffen gab es wieder spannende Vorträge zu hören:

  • Sebastian Winter von Metro Systems: Ein Lehrstück. Major Updates und das wahre Leben
  • Georgi Bilyukov von Hedgehog: Continuous Integration and Continuous Delivery
  • Lars Schilling von Namics: NitroNet – Was ist das?
  • Christopher Hümmer von Init: Multisite-Kompatibilität von Sitecore
  • Friederike Heinze von Comspace: Recap des Sitecore Symposiums in New Orleans
SUG Deutschland Treffen im Aufbauhaus Berlin
SUG Deutschland Treffen im Aufbauhaus Berlin

Begrüßung und das Lehrstück

Der gewohnt herzlichen Begrüßung, diesmal von Jana Wichmann (ecx.io) und Christopher Wojciech (netzkern) folgte direkt der erste Beitrag. Sebastian Winter, der im Rahmen des Metro Systems Relaunches das Upgrade von Version 7.2 auf 8.1 verantwortet, berichtete über verschiedene Strategien, ein solches Upgrade bis hin zur Entscheidung durchzuführen. Unter anderem standen dabei folgende Optionen zur Auswahl:

  • Parallele Upgrade-Instanz per Vanilla Sitecore Installation (out-of-the-box)
  • Paralleles Upgrade mit aktuellem Datenbankbestand mit schrittweiser Durchführung bis auf Sitecore 8.1
  • Schrittweise Upgrades im laufenden Betrieb

Letztlich ist die Entscheidung für Option zwei gefallen, da durch die einzelnen Upgradeschritte etwaig auftretende Fehler direkt nachvollzogen und behoben werden konnten. Aus unserer Erfahrung ist diese Option die beste und auf jeden Fall der letzten Variante vorzuziehen, wenn Option eins aus kostentechnischen Gründen ausscheidet.

Upgrade auf Sitecore 8.1 - ein Lehrstück von Metro Systems
Upgrade auf Sitecore 8.1 – ein Lehrstück von Sebastian Winter, Metro Systems

Hedgehog stellt RAZL vor

Der Beitrag von Hedgehog umfasste neben der Vorstellung des bereits von uns eingesetzten Tools TDS (Team Development for Sitecore) auch das Tool RAZL, ein Comparing und Merge Tool für Sitecore Datenbanken. Ganz besonders spannend ist die Eigenschaft, dass Datenbanken im laufenden Betrieb abgeglichen und aktualisiert werden können. Wir werden dieses Tool weiter im Auge behalten.

Und was genau ist NitroNet?

Namics bot in seinem Beitrag eine Vorstellung des selbst entwickelten Frameworks NitroNet for Sitecore. NitroNet for Sitecore ist eine Erweiterung der ASP.NET MVC View Engine “NitroNet”, welche die Eigenschaften von Sitecore, z.B. Platzhalter oder Experience Editor Tauglichkeit, vollumfänglich einbindet. Details hierzu und zur Vision findet ihr auf der Nitronet-Website oder im Namics Blog.

Namics-Vortrag zu NitroNet
NitroNet von Lars Schilling, Namics

Multisite-Kompatibilität. Ja, da war was…

Das Thema “Multisite-Kompatibilität” bot einen kurzen Einblick in die Do’s und Don’ts der Multisite-Konfiguration, präsentiert von der ]Init[ AG. So soll z.B. je Site ein eigener Bereich in der Media Library existieren und ein eigener Bereich für Konfigurationen bestehen. Grundsätzlich ist die Trennung je Site sinnvoll um den Überblick zu bewahren. Gemeinsam genutzte Module / Features können jedoch der Site übergeordnet platziert und verwendet werden. Insbesondere die Sprachen und Workflows sind bei Multisite-Lösungen problematisch, da diese nicht out-of-the-box Site-spezifisch konfiguriert werden können. Hierfür sind eigene Erweiterungen nötig.

Zwischen den Beiträgen gab es immer wieder Zeit für interessante Gespräche zwischen bekannten und unbekannten Gesichtern, ganz im Sinne des TAK. Welche Komplexität beispielsweise das Upgrade bei Metro Systems umfasste, “was bringt mir RAZL konkret” oder “welche sitecorespezifischen Probleme rauben mir gerade den letzten Verstand” waren nur einige Fragen der rund vierzig Personen großen Usergroup, die untereinander erörtert wurden.

Multisite-Kompatibilität von Christopher Hümmer, Init
Multisite-Kompatibilität von Christopher Hümmer, Init

Finale furioso – Recap des Sitecore Symposiums und Get Together

Zum Abschluss gab unsere Kollegin Friederike Heinze ein tolles und umfassendes Recap des Sitecore Symposiums 2016 in New Orleans, Louisiana, mit vielen Fotos und spannenden Themen, über den sie auch in einem eigenen Blogbeitrag ausführlich berichtet.

comspace - Rückblick auf das Sitecore Symposium New Orleans
Recap vom Sitecore Symposium New Orleans von Friederike Heinze, comspace

Nach den Vorträgen ging es direkt weiter ins Alt-Berliner Wirtshaus “Max und Moritz”, in dem in der Bibliothek neben gutem Essen und leckerer “Kreuzberger Molle” (auch Pils genannt) weiter munter über verschiedenste Themen geplaudert wurde.

Wirtshaus Max und Moritz
Wirtshaus Max und Moritz

 

Für uns als Team Nibbler war es ein sehr erfolgreicher Tag mit vielen Gesprächen, neuen Bekanntschaften und viel wertvollem Input zu neuen und auch bekannten Themen. Wir freuen uns bereits auf das nächste Sitecore Usergroup Treffen im Januar 2017, dann in München.

Get Together im Wirtshaus Max und Moritz
Get Together im Wirtshaus Max und Moritz

Tipp – Sitecore Slack Chat

Abschließend auch hier noch einmal die Empfehlung, die Christopher Wojciech an Sitecore Entwickler gab: dem internationalen Sitecore Slack Chat kann und soll gerne beigetreten werden. Dort ergibt sich die Chance, sich mit Sitecore Entwicklern und Sitecore MVPs direkt auszutauschen. Wie man dem Sitecore Slack Channel beitritt, beschreibt Akshay Sura (einer der Gründer) in seinem Blogpost How to join Sitecore Slack Community Chat. Alternativ oder auch zusätzlich steht die Reddit Sitecore Community zur Verfügung.

 

Kürzlich in New Orleans – Rückblick Sitecore Symposium 2016

Sitecore Symposium 2016 New Orleans

Ich hatte das Glück und durfte dieses Jahr zum Sitecore Symposium nach New Orleans reisen. Mit allen, die nicht dabei sein konnten, möchte ich hier meine Highlights teilen.
Es war wieder mal ein Spitzen Event – und Sitecore ein großartiger Gastgeber. Zunächst zur Location: was für eine tolle Stadt, so lebendig, offen und musisch. Insbesondere das French Quarter ist faszinierend.

French Quarter in New Orleans beim Sitecore Symposium 2016
French Quarter in New Orleans

Diese Atmosphäre hat uns durch das ganze Event begleitet. 2000 Menschen aus aller Welt waren da, eine tolle Gelegenheit die Sitecore Community kennenzulernen und sich mit anderen Experten auszutauschen. Inhaltlich war für alle Zielgruppen etwas dabei, es gab Sessions mit den Schwerpunkten Marketing, Business, Development und diesmal auch eine für Sitecore-Neulinge. Die Entscheidung für eine Session war manchmal schwer, für Entwickler gab es bis zu 4 gleichzeitige Sessions.

Pre-Seminar:  “Habitat Masterclass”

Bevor es mit dem offiziellen Symposium losging, hat Sitecore dieses Jahr zum ersten Mal (zumindest in Europa), einige Intensivworkshops angeboten. Ich habe mich für einen eintägiges Seminar bei Thomas Eldblom von Sitecore zu Habitat entschieden. Es ging im Wesentlichen darum, die Architektur hinter Habitat und damit Helix zu verstehen:

“Helix is the official Guidelines and Recommended Practices for Sitecore development.”

Anders Laub hat einen guten Artikel für den schnellen Einstieg in modulare Architekturen geschrieben. Wenn ihr gleich selbst mal ein Habitat Modul entwickeln wollt, dann findet ihr hier die Schritt-für-Schritt Anleitung von Thomas.

Die Aussage war ganz klar: Sitecore sieht Habitat nicht als Framework oder Starterkit, es ist ein Demo-Projekt, umgesetzt nach Sitecore Best-Practices.

Anschließend gab es das Willkommensgetränk im Partner-Pavillon mit Musik aus der Preservation Hall. Die Stimmung stimmte, ein toller Einstieg in die Konferenz.

Mein Symposium Recap

Opening Keynote

Sitecore Symposium 2016 Opening Keynote Michael Seifert

Die Eröffnungskeynote wurde von Michael Seifert persönlich gehalten. Auf Experience (Experience, Experience) folgt DEMAND MORE

  • from Commerce
  • from Mobile
  • from Automation
  • from Context
  • from Engagement

Die Themen, welche uns dann natürlich auch durch das Symposium begleitet haben, waren: Embedded Commerce, Sitecore Experience Accelerator, New Path Analyzer Features, Azure.

Innovation & Technology

In der anschließenden Guest Keynote ging es um Technology & Innovation aus Sicht des Futuristen Jason Silva. Es war beeindruckend und inspirierend, ICH kann es nicht mit Worten beschreiben. Daher hier ein paar Zitate:

“Nature and the technology are one
in the same”
“The next Billionaire will be the one who affects a billion people in a positive way.”
“We have a responsibility to awe.”

Neugierig geworden? Dann schaut euch doch mal bei YouTube um.

Developer Keynote

Lars Fløe Nielsen hat einige Features der 8.2 vorgestellt:

  • Support Dependency Injection (einen guten Artikel von Kam Figy, Sitecore MVP, findet ihr hier)
  • Sitecore NuGet
  • Express Migration Tool (zunächst von 7.2 auf 8.2)
  • Helix Guidelines

Er hat die Wichtigkeit der Sitecore Entwickler (also uns) hervorgehoben.

Sein Schwerpunkt: Die Sitecore Community und das Feedback ist für Sitecore und die Produktentwicklung enorm wichtig. Ein Auszug:

xConnect

Zum Thema Sitecore xConnect gab es unterschiedliche Sessions. Was ist xConnect? Laut Todd Mitchell von Sitecore:

“Single, unified API that allows you to collect and act on any individual and their behavior”

Letztlich können mit dieser API Daten aus der xDB gelesen und in die xDB geschrieben werden, mit dem Ziel, ein Experience Profile über alle Channel, aber auch aus der On- und Offline-Welt, erstellen zu können. Ein gern herangezogenes Beispiel ist hier das Tracking des Besuchs eines Ladengeschäfts mittels iBeacon. Die Persistierung am xProfile erfolgt dann zukünftig mittels xConnect API. Sitecore xConnect kommt mit Sitecore 8.3.

Commerce vNext

Das ist mein persönliches Highlight:

Sitecore Symposium 2016 Commerce vNext

Sitecore hat eine eigene Commerce Engine basierend auf .NET Core von Microsoft entwickelt. Das Modul ist nahtlos in Sitecore integriert und es ist flexibel erweiterbar. Das initiale Release umfasst: Customer Management, Order Management und Dynamic Pricing.

Die gute Nachricht: Das im letzten Jahr veröffentlichte Sitecore Commerce Connect Modul als Layer zwischen Sitecore und einem externen Shop bleibt bestehen.

Das Modul wird mit Sitecore 8.3 veröffentlicht – ich bin wirklich gespannt.

House of Blues

Zwischen den Tagen gab es eine stilechte Symposium-Party im House of Blues. Dieses liegt mitten im French Quarter, niemals hätte ich dahinter eine Location für so viele Menschen vermutet. Es gab einen Shuttlebus, lecker Essen & Trinken, chillige Ecken, aber auch mehrere Bühnen mit Livemusik. Und wir haben gerockt!

Sitecore Symposium Afterparty House Of Blues
House of Blues – New Orleans

Schön, dass es am nächsten Morgen erst um 9 Uhr losging 😉

Why Games Make Us Better

Spieleentwicklerin Jane McGonigal hat uns den Start in den Tag 2 leicht gemacht. Am Beispiel Pokémon Go hat sie uns gezeigt, was ein gutes Spiel ausmacht, aber auch vorgeführt wie viel wir spielen: 1,75 Millarden Minuten pro Tag wird Candy Crush gespielt, das sind 3,5 Millionen Vollzeit-Stellen…
Außerdem sie hat uns ein Alibi gegeben:

Jane McGonigal - Why Games Make Us Better

Und wenn wir alle ein bisschen wie Uber denken, ist spielen dann unsere Zukunft?

Und sonst?

Unit Testing

Sitecore MVP Dan Solovay hat seine Begeisterung für Test Driven Development mit uns geteilt. Sitecore 8.2 macht es uns durch abstrakte Klassen, virtuelle Methoden und integrierter Dependency Injection in der Entwicklung viel leichter automatisiert zu testen. Er hat uns seine Tools vorgestellt und in Teilen live angewendet. xUnit, NSubstitute und NCrunch sind jedenfalls auf meiner Merkliste gelandet.

Multisites

Liz Spranzani und Trevor Campbell haben die seit Sitecore 8.1 in Sitecore integrierten Language-Fallback-Möglichkeiten vorgestellt, inkl. Stolpersteine und Best-Practices. Vor allem aber haben sie Anhaltspunkte und Fragenkataloge als Entscheidungsgrundlage für eine Multilanguage Strategie in Sitecore mitgebracht.

Turbocharged Publishing

Steven Pope hat in seiner Session anschaulich erläutert, warum Publizierung in Sitecore so teuer ist: Wenn 1 Item in 3 Sprachen mit 2 Publizierungszielen publiziert wird, mussten bisher 8753 Items angefasst werden (ich sage nur: Publishing Restrictions, Fields, Base Templates, Workflows, Languages, Publishing Targets, Related Items, Ancestors etc.)

Mit Sitecore 8.2 hat Sitecore die Publizierung auf Basis .NET Core reimplementiert. Damit dauert die Republizierung einer Webseite, die vorher mehr als 1 Tag gedauert hat, nur noch knapp 20 Minuten.

Aktuell ist die Verwendung des neuen Publishing Service optional konfigurierbar.

Mit der 8.3 kommen weitere UX Verbesserungen: Es gibt einen Publishing Manager in welchem die Redakteure OOTB die aktuellen Publizierungen einsehen können. Die für Redakteure nur irreführenden unterschiedlichen Publishing Modi wird es nicht mehr geben (sondern nur noch einen stablien und performanten) und “Publish Site” wird es nur noch für Admins geben.

Die Präsentation hatte echt Unterhaltungswert!

Closing Keynote

Es gab ein Schauspiel zum Thema xConnect in Perfektion. Vom Handy auf dem Sofa, über den Webshop zur persönlichen Ansprache im Ladengeschäft.

Außerdem hat Lars Fløe Nielsen einen Einblick in die Vision des Sitecore “Labors” gegeben: Redakteure bewegen sich in Sitecore ohne bewussten Applikationswechsel, es öffnet sich was gebraucht wird, dort wo es gebraucht wird, Bedienung in einem Fluss.

Das war der offizielle Teil. Für den Abend sind wir einem Tipp gefolgt und sind in kleiner Runde in die Frenchman Street, haben erst lokale Küche genossen und anschließend den Abend in einer Bluesbar ausklingen lassen. Das war ein wunderbarer Abschluss. Ich danke euch.

Ach ja, das nächste Symposium ist 2017 in Las Vegas. Ich freu mich auf euch 🙂

SUGCON 2016 in Kopenhagen – Rückblick auf Tag 2

Über den ersten Tag der SUGCON habe ich hier bereits berichtet. Am zweiten Tag ging es mit den Sessions genau so intensiv weiter.

Active Commerce: How we use SIM, PowerShell, Octopus Deploy, and Azure to automate product builds

Nick Wesselman hat zunächst kurz das Active Commerce E-Commerce System bzw. das darunterliegende Framework, basierend auf dem Sitecore E-Commerce Service (SES) vorgestellt. Das SES wird nicht mehr von Sitecore supported, ist aber Open Source und wurde auf GitHub veröffentlicht.

Anschließend hat Nick die intern etablierten Build- und Deployment-Prozesse und Tools vorgestellt. Meine Erkenntnis: PowerShell, PowerShell, PowerShell 🙂

BuildAndDeploymentProcess

Deep Dive – You, me and Sitecore MVC

Kern Herskind Nightingale hat mit Begeisterung einen Einstieg in MVC gegeben. Ist aber auch auf sehr konkrete Probleme und Lösungsansätze eingegangen:

WebForms sind Vergangenheit, MVC ist die Zukunft. Sein klarer Wunsch: Annäherung von Sitecore MVC an ASP.NET MVC.

Hedgehog Development – Sponsor Technical Highlights

Hedgehog als Sponsor hat kurz das TDS vorgestellt, was natürlich mehr kann als nur Items zu synchronisieren 😉

Wenn ihr interesssiert seid, findet ihr in diesem Blog-Beitrag von mir mehr Infos zum TDS.

Super Charge your Continuous Integration Deployments

Nikola Gotsev hat über CI-Prozesse im Allgemeinen und Best Practises zum Thema Branches, Frontend-Integration, Testing und den dafür erforderlichen verschiedenen Tools im Speziellen gesprochen.

Seine Tipps für Continuous Deployment:

  1. So wenig Content wie möglich in Source Control Systemen.
  2. Keinen Content in höhere Umgebungen ausliefern, dafür sind Packages zu verwenden.
  3. Vor der Auslieferung Datenbank Backup machen (Es gibt kein Undo).

Und so sieht dann sein perfekter Deploy-Prozess aus:

Perfect Scenario

Practical Habitat: Embrace the Architecture

Anders Laub hat weniger über Habitad gesprochen, sondern eher über Softwarearchitektur im Allgemeinen. Die Softwarearchitektur bildet die Grundlage und ist der langlebigste Aspekt eines Entwicklungsprojektes. Anders hat das wie folgt skizziert.

ArchitectureMethodsTools

Er war mit viel Herz und Verstand dabei und hat zum Nachdenken und Diskussionen angeregt. Ein paar Twitter-Zitate:

Ladies and Gentlemen, Start your Testing!

Alistair Deneys hat über Unit Tests in der Sitecore Entwicklung gesprochen. Klar gibt es Herausforderungen, die zu meistern sind: die Items in Sitecore, die Konfigurationsdateien, veraltete/ nicht “mockable” API…

Alistair hat dies gleich auf mehreren Wegen live demonstriert und gesteigert:

  1. Sitecore als Application installieren und die Tests als Page Test Runner laufen lassen
  2. Echte NUnit-Tests, indem Sitecore .configs und .dlls in das Test-Projekt kopiert werden.
  3. Mocken von Sitecore Items mittels Sitecore.FakeDb.

Schlussendlich hat er dann noch gezeigt, wie mittels Sitecore.LiveTesting eine Sitecore Infrastruktur außerhalb des IIS simuliert werden und Tests dagegen gefahren werden können.

Es gab auch schon eine kleine Vorschau auf das was kommt. Alles wird besser 😉 Statisches fliegt raus und es wird viele abstrakte Basisklassen geben.

Mein Mitbringsel für Euer Bücherregal 😉

UniTesting

I refactored doc.sitecore.net and all I got was this experience

Der letzte Vortrag der Konferenz kam von Martina Welander: Ein lebendiger und interessanter Vortrag über den Werdegang des Refactorings von doc.sitecore.net. Nicht immer auf dem direkten Weg, aber sehr reflektiert und selbstkritisch.

Und so hat sie den Prozess selbst dargestellt: https://twitter.com/mhwelander/status/725307365273288704

Irgendwie ein sprechendes Bild für Softwareentwicklung 😉

Auf Wiedersehen

Es war ein rundum gelungenes Event. Ich komme bestimmt nächstes Jahr wieder. Vorher sehen wir uns vielleicht auf einem der nächsten Usergroup Treffen in Deutschland? Ich würde mich freuen.

Highlights der SUGCON 2016 in Kopenhagen

Letzte Woche war ich zum ersten Mal auf der europäischen Sitecore User Group Conference, diesmal zu Gast in Kopenhagen. Die SUGCON ist eine Konferenz der Sitecore Community, von Entwicklern für Entwickler. Mir hat es richtig gut gefallen, die Vorträge waren Spitze. Ich habe Neues gehört, Wissen vertieft, Denkanstöße bekommen und mit vielen tollen Leuten gesprochen.

Tag 1

Am ersten Tag ging es um 12 Uhr mit einem gemeinsamen Lunch los. Es war lecker und ein guter Auftakt, auch um zu sehen, wer alles so da ist: Entwickler aus aller Welt.

Die Keynote haben sich Michael Seifert und Lars Fløe Nielsen geteilt. Das fing mit einer Vorschau auf die nächsten Sitecore Versionen schon spannend an.

Sitecore 8.2 legt den Fokus auf die UX des Experience Editors (Pre-Release!):

Preview ExperienceEditor

In 8.3 liegt der Schwerpunkt auf der Verbesserung der Marketing-Werkzeuge (Pre-Release!):

Preview Experience Editor AutomationPlans

Zukünftig sind deutlich weniger Applikationssprünge nötig. Beispielsweise werden Formulare und Engagement Pläne direkt im Experience Editor gepflegt.

Und sonst:

  • Es wird ein Express Upgrade Tool geben. Perspektivisch ist dann keine Migration mehr von Version zu Version erforderlich, sondern größere Sprünge können einfach durchgeführt werden.
  • Enterprise Publizierung: Es wird eine triggerbasierte Publizierung geben und die Performance im Allgemeinen wird verbessert.
  • ASP.NET WebForms werden nicht mehr weiter entwickelt. Vorerst natürlich aber weiter supported.
  • Das Silverlight Plugin wird zukünftig nicht mehr benötigt. Schade 😉
  • Und mein Highlight: WFFM wird abgelöst (kann man auch in obigem Screen schon sehen)

Es folgten viele weitere Sessions. Teilweise fanden drei parallel statt und es war nicht immer einfach sich zu entscheiden. Ein Auszug meiner Agenda des ersten Tages habe ich hier mal zusammengefasst:

Serialize all the things with Unicorn

Kam Figy selbst hat Unicorn vorgestellt. Unicorn ist ein Tool für den Austausch von Items zwischen unterschiedlichen Sitecore Umgebungen. Hervorzuheben ist, dass die serialisierten Items für Entwickler gut lesbar und damit auch Merge-Konflikte einfacher zu handhaben sind (als die serialisierten Items von Sitecore selbst). Neu ist: Mit der Version 3.2 können auch Benutzer und Rollen synchronisiert werden.

Commerce Nerdvada for Sitecore with uCommerce

Anschließend hat Søren Spelling Lund die Architektur von uCommerce vorgestellt – modular und erweiterbar, nach dem SOLID Prinzip.

SOLID

uCommerce ist ein .NET basiertes E-Commerce System, für welches es bereits einen Sitecore Commerce Connector gibt. Interesse geweckt? Es gibt Online-Trainings. Das nächste beginnt am 23. Mai.

Sitecore Pathfinder – Another look at the developer experience

Dmitry Kostenko von Sitecore hat den Sitecore.Pathfinder als „Experimental open-source toolchain for Sitecore that looks end feels like a compiler“ vorgestellt. Die Idee / das Ziel:

  • Alle Bestandteile der Sitecore Entwicklung (Templating, Items, Design, Quellcode) an einer Stelle verortet
  • Entwicklung in einer beliebigen IDE
  • Einfaches Deployment (ein Shortcut für Build und Deploy)
  • CI: Lokal und auf den Servern die gleichen Tools verwenden

Templating könnte dann in Zukunft so aussehen:

Templating

Mir hat die Idee zu denken gegeben. Ich bin neugierig geworden und ich werde es mir bestimmt näher ansehen.

Sitecore might be secure, but your site isn’t

In Bas Lijten’s Vortrag ging es weniger um Sitecore als um die Absicherung von Webseiten im Allgemeinen. Er hat potentielle Sicherheitslücken anschaulich demonstriert und Lösungen aufgezeigt. Seine Folien findet ihr bereits auf Slideshare.

Sitecore and NuGet: Sitecore development done right

Sean Holmesby hat uns in seiner Session gezeigt, wie NuGet effektiv in der Sitecore- Entwicklung und im Build-Prozess eingesetzt werden kann, um die „DLL-Hell“ zu umgehen. Außerdem hat er mögliche Standards / Konventionen aufgezeigt. Den gesamten Vortrag könnt ihr bei YouTube sehen. Seine Tools und Ideen in Kürze findet ihr hier in der Sitecore Communiy.

GetTogether

Um 18 Uhr waren dann die Sessions durch. Bei einem geselligen Getränk wurden die Sitecore MVP’s 2016 gekürt. Herzlichen Glückwunsch an die Gewinner. Später gab es noch eine Vorstellung des Gewinners des diesjährigen Hackaton. Zum zweiten Mal ist es das Team Uniques von Unic geworden. Wow.

Und zuletzt gab es noch ein lustiges Quiz für alle, in dem historisches Sitecore-Wissen gefragt war. Hättet ihr gewusst, welche der folgenden Datenbanken nie von Sitecore supported wurde: MS SQL, MySQL, MongoDB oder Tamino?

Dinner

Gegen 21 Uhr war das offizielle GetTogether durch, wir aber noch lange nicht 😉

Weiter mit Tag 2 der SUGCON 2016

Sitecore Commerce Connect – Teil 5: Warenkorb verwalten

Bisher ging es in dieser Serie um die Verwaltung und Darstellung von Produkten und Preisen aus Hybris. Das Ziel dieses Artikels ist es auch erste Prozesse rund um den Warenkorb mittels Sitecore Commerce Connect abbilden zu können.

Warenkorb

Die zentrale Überlegung am Anfang eines Projektes ist, welches System zu welcher Zeit die Zuständigkeit für den Warenkorb hat. Wird der Warenkorb immer auf beiden Seiten synchron gehalten, das heißt jede Änderung am Warenkorb wird unmittelbar an das externe Shopsystem (kurz ECS) gemeldet, oder wird der Warenkorb im ECS nur zu definierten Zeitpunkten synchronisiert, also z.B. beim Checkout? Letzteres bedingt weniger Requests an das ECS, aber Sitecore-seitig ist dann z.B. eine Warenkorbwertermittlung erforderlich, die im schlechtesten Fall nicht mit der im ECS synchron ist.

Warenkorb-Verwaltung

Im Rahmen unserer Evaluierung ist das ECS für den Warenkorb zuständig und Sitecore meldet alle Änderungen unmittelbar an das ECS. Für die Darstellung auf der Webseite werden die Daten rund um den Warenkorb wiederum immer online vom ECS abgefragt.
Außerdem haben wir uns entschieden, den mitgelieferten Engagement Plan ‘Abandoned Carts’ gleich mit zu nutzen, zumal dafür scheinbar keine weitere Implementierung erforderlich ist.

Warenkorb anlegen/ abfragen

Für alle Funktionen rund um den Warenkorb ist der Service Provider ‚CartServiceProvider‘ des Cart Service Layers zuständig.

Beispiel Verwendung CartServiceProvider.CreateOrResumeCart

[csharp]
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Comspace.Sitecore.CommerceConnect.Services.Prices;
using Sitecore;
using Sitecore.Analytics;
using Sitecore.Commerce.Entities.Carts;
using Sitecore.Commerce.Services.Carts;
using Sitecore.Commerce.Services.Prices;
using Sitecore.Data;

namespace Comspace.Sitecore.CommerceConnect.Services.Carts
{
/// <summary>
/// Sitecore.Commerce.Carts.config
/// </summary>
public class CartManager
{
public const string TrackerAttachmentKeyCart = "Comspace.Sitecore.CommerceConnect_Cart";

public static Cart GetCart()
{
if (!Tracker.Current.Contact.Attachments.ContainsKey(TrackerAttachmentKeyCart))
{
//create cart
var createOrResumeCartRequest = new CreateOrResumeCartRequest(
"Website",
Context.User.Profile.Email,
"Default",
Context.User.Profile.Email); //NOTE FindCartInEaState: c.CustomerId == request.CustomerId
var cart = new CartServiceProvider().CreateOrResumeCart(createOrResumeCartRequest).Cart;

//persist cart
Tracker.Current.Contact.Attachments[TrackerAttachmentKeyCart] = cart;
}
return Tracker.Current.Contact.Attachments[TrackerAttachmentKeyCart] as Cart;
}
}

//…
}
[/csharp]

Pipeline loadCart

Die Anbindung des ECS erfolgt mittels Erweiterung der Pipeline ‚loadCart‘ der Sitecore.Commerce.Carts.config.
.config

[xml]
<!– LOAD CART
Gets the cart object that matches the specified criteria.
This pipeline is responsible for reading data for a specific cart that is managed by the commerce system.
This pipeline reads the cart data from the commerce system and converts that data into the Commerce format.
–>
<commerce.carts.loadCart>
<processor type="Comspace.Sitecore.CommerceConnect.Hybris.Pipelines.Carts.LoadCart, Comspace.Sitecore.CommerceConnect.Hybris" patch:after="processor[@type=’Sitecore.Commerce.Pipelines.Carts.LoadCart.LoadCartFromEaState, Sitecore.Commerce‘]"/>
</commerce.carts.loadCart>
[/xml]

Processor LoadCart

[csharp]
using Comspace.Sitecore.CommerceConnect.Hybris.Connector;
using Comspace.Sitecore.CommerceConnect.Hybris.Connector.Model.Cart;
using Comspace.Sitecore.CommerceConnect.Services.Carts;
using Sitecore.Commerce.Entities.Carts;
using Sitecore.Commerce.Pipelines;
using Sitecore.Commerce.Pipelines.Carts.Common;
using Sitecore.Commerce.Services.Carts;

namespace Comspace.Sitecore.CommerceConnect.Hybris.Pipelines.Carts
{
/// <summary>
/// commerce.carts.loadCart
/// </summary>
public class LoadCart : CartPipelineProcessor
{
public override void Process(ServicePipelineArgs args)
{
var loadCartRequest = args.Request as LoadCartRequest;

//get from ECS
ExternalCart externalCart = CartConnector.Load(global::Sitecore.Context.Language.Name, loadCartRequest.UserId);

//convert to commerce connect cart
Cart cart = new Cart();
cart.ExternalId = externalCart.Code;
cart.ShopName = loadCartRequest.ShopName;
cart.UserId = loadCartRequest.UserId;

//init totals
cart = CartManager.UpdateCartTotals(cart); //NOTE prevent multiple request

//persist for next processor
((CartResult) args.Result).Cart = cart;
}
}
}
[/csharp]

Produkt zum Warenkorb hinzufügen

Beispiel Verwendung CartServiceProvider.AddCartLines

[csharp]
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Comspace.Sitecore.CommerceConnect.Services.Prices;
using Sitecore;
using Sitecore.Analytics;
using Sitecore.Commerce.Entities.Carts;
using Sitecore.Commerce.Services.Carts;
using Sitecore.Commerce.Services.Prices;
using Sitecore.Data;

namespace Comspace.Sitecore.CommerceConnect.Services.Carts
{
/// <summary>
/// Sitecore.Commerce.Carts.config
/// </summary>
public class CartManager
{
//…

public static Cart AddLine(string externalId, string sitecoreItemId, uint quantitiy)
{
Cart cart = GetCart();

//create cartlines
List<CartLine> lines = new List<CartLine>
{
new CartLine
{
Product = new CartProduct
{
ProductId = externalId,
SitecoreProductItemId = new ID(sitecoreItemId),
Price = PriceManager.GetPrice(externalId, Context.Language)
},
Quantity = quantitiy,
LineNumber = (uint) (cart.Lines.Count + 1)
}
};

//add cart lines
AddCartLinesRequest addCartLinerequest = new AddCartLinesRequest(cart, new ReadOnlyCollection<CartLine>(lines));
CartResult cartResult = new CartServiceProvider().AddCartLines(addCartLinerequest);

return cartResult.Cart; //result contains the updated cart
}
}
}
[/csharp]

Pipeline addCartLines

.config

[xml]
<!– ADD CART LINES
This pipeline is responsible for adding a new line to the shopping cart and recording a corresponding page event in DMS.
This happens when a product is added to the cart.
–>
<commerce.carts.addCartLines>
<processor type="Comspace.Sitecore.CommerceConnect.Hybris.Pipelines.Carts.AddLineToCart, Comspace.Sitecore.CommerceConnect.Hybris" patch:after="processor[@type=’Sitecore.Commerce.Pipelines.Carts.AddCartLines.AddLinesToCart, Sitecore.Commerce‘]"/>
</commerce.carts.addCartLines>
[/xml]

Processor AddCartLines

[csharp]
using System.Linq;
using Comspace.Sitecore.CommerceConnect.Hybris.Connector;
using Sitecore.Commerce.Entities.Carts;
using Sitecore.Commerce.Pipelines;
using Sitecore.Commerce.Services.Carts;

namespace Comspace.Sitecore.CommerceConnect.Hybris.Pipelines.Carts
{
/// <summary>
/// commerce.carts.addCartLines
/// </summary>
public class AddLineToCart : PipelineProcessor<ServicePipelineArgs>
{
public override void Process(ServicePipelineArgs args)
{
var cartLinesRequest = args.Request as CartLinesRequest;

//add to ECS
Cart cart = cartLinesRequest.Cart;
CartLine cartline = cartLinesRequest.Lines.First();
CartConnector.AddLineToCard(global::Sitecore.Context.Language.Name, cart, cartline);
}
}
}
[/csharp]

Warenkorb Summen

Damit die Summen im Warenkorb immer korrekt sind und keine Sitecore-seitige Berechnung stattfinden muss, werden auch die Warenkorb Summen immer online aus dem ECS geholt. Dafür muss die Pipeline ‘saveCart’ erweitert werden:

Pipeline saveCart

.config

[xml]
<!– SAVE CART
Saves the cart object to the external system and in Sitecore EA state.
–>
<commerce.carts.saveCart>
<processor type="Comspace.Sitecore.CommerceConnect.Pipelines.Carts.UpdateCartTotals, Comspace.Sitecore.CommerceConnect" patch:after="processor[@type=’Sitecore.Commerce.Pipelines.Carts.Common.SaveCartToEaState, Sitecore.Commerce‘]"/>
</commerce.carts.saveCart>
[/xml]

Processor UpdateCartTotals

[csharp]
using Comspace.Sitecore.CommerceConnect.Services.Carts;
using Sitecore.Commerce.Entities.Carts;
using Sitecore.Commerce.Pipelines;
using Sitecore.Commerce.Services.Carts;

namespace Comspace.Sitecore.CommerceConnect.Pipelines.Carts
{
/// <summary>
/// commerce.carts.saveCart
/// </summary>
public class UpdateCartTotals : PipelineProcessor<ServicePipelineArgs>
{
public override void Process(ServicePipelineArgs args)
{
var cartRequest = (CartRequestWithCart) args.Request;

//get from ECS
Cart cart = CartManager.UpdateCartTotals(cartRequest.Cart);

//persist for next processor
((CartResult) args.Result).Cart = cart;
}
}
}
[/csharp]

Beispiel Verwendung PricingServiceProvider.GetCartTotal

[csharp]
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Comspace.Sitecore.CommerceConnect.Services.Prices;
using Sitecore;
using Sitecore.Analytics;
using Sitecore.Commerce.Entities.Carts;
using Sitecore.Commerce.Services.Carts;
using Sitecore.Commerce.Services.Prices;
using Sitecore.Data;

namespace Comspace.Sitecore.CommerceConnect.Services.Carts
{
/// <summary>
/// Sitecore.Commerce.Carts.config
/// </summary>
public class CartManager
{
//…

public static Cart UpdateCartTotals(Cart cart)
{
var request = new GetCartTotalRequest();
request.Cart = cart;

//get from ECS
var cartTotalResult = new PricingServiceProvider().GetCartTotal(request); //result contains the updated cart

Tracker.Current.Contact.Attachments[TrackerAttachmentKeyCart] = cartTotalResult.Cart; //refresh cache
return cartTotalResult.Cart;
}
}
}
[/csharp]

Stolpersteine

Der Processor ‘FindCartInEaState’ benötigt eine CustomerId, damit der Contact ermittelt werden kann. Dafür muss die eigentlich optionale CustomerId mit an den ‘CreateOrResumeCartRequest’ übergeben werden (siehe oben). Anderenfalls wird immer wieder ein neuer Warenkorb angelegt, obwohl für den Contact bereits einer existiert.

Resumé

Und auch diesen letzten Beitrag möchte ich mit ein paar Eindrücken und Erkenntnissen abschließen:

  • Der Cart Sercice Layer ist sehr umfangreich und im Rahmen der Evaluierung konnte nur ein sehr kleiner Ausschnitt evaluiert werden.
  • Eine Herausforderung in einem echten Projekt sind die Zuständigkeit und Synchronisation zwischen dem Sitecore Shop und dem ECS. Was wird wo zwischengespeichert und wann an wen gemeldet?
  • Wie auch schon unter Stolpersteine beschrieben, war der Zugriff auf die Contacts im Engangement Plan (automatisch im Hintergrund) immer wieder holprig. Eine der Ursachen war sicherlich die Entwicklungsumgebung: wechselnde Browser, plötzliche Neustarts etc.  Hier müsste in einem echten Projekt eine kritische Analyse erfolgen.
  • Auch dem Umgang mit Fehlern in der Verarbeitung muss in einem echten Projekt eine hohe Aufmerksamkeit gewidmet werden – Stichwort Transaktionssicherheit.

So, das war’s erstmal von meiner Seite zum Thema Commerce Connect. Ich freue mich über euer Feedback 🙂

Alle voran gegangenen Artikel dieser Serie findet ihr hier:
Teil 1: Ein Überblick
Teil 2: Produkte synchronisieren
Teil 3: Klassifizierungen synchronisieren
Teil 4: Preise darstellen