Sitecore XC – Finally price card snapshots also have an end date

Sitecore XC – Finally price card snapshots also have an end date

In this blog post I would like to present you an implementation for an issue we all might have suffered from. But let us start in the beginning and shortly discuss how pricing works in Sitecore XC in general.

How does pricing work in Sitecore XC?

The most basic way to set a price in Sitecore XC is, that we just set a price on the sellable item directly as List Price. This price can be of course set per currency like seen in the example below.

2019-11-13 07_54_17-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

Because such a price setting is quiet inflexible Sitecore has build some piece of logic on top of that. The core principle of that mechanism is so define a price based on currency, date, and quantity, which is far more flexible, than just set one single price per sellable item.

This can be edited by an editor under the Pricing Application in the Business Tools of Sitecore XC.

2019-11-13 09_41_17-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung.png

Once you entered this application you are able to define a so called Pricebook.

2019-11-13 07_55_15-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

Such a Pricebook can be linked to one or more catalogs and is itself just a container for more specific price settings, the so called Pricecards.

2019-11-13 09_05_38-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

Such a Pricecard then be directly applied on a sellable item to a sellable item via the Pricing field.

2019-11-13 10_18_36-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

Now the interesting part starts, where real price settings come into play. Pricecards themselves are again just containers for so called Snapshots.

2019-11-13 09_09_08-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

A snapshot itself then contains the information of a start date, when this specific snapshot should be applied, a tiered price per currency, which means you can define how much one single sellable item costs, in case a customer has X items in cart. And last but not least, you are able to tag the snapshot to define to which sellable items this specific snapshot should be applied.

2019-11-13 09_09_44-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

Therefore you see, that this pricing mechanism is far more flexible and powerful, than just adding a simple list price to a sellable item directly.

2019-11-13 09_10_05-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

Known limitations of snapshots

This overall pricing mechanism is really great and powerful. But when talking to clients and collecting all their wishes and requirements, one feature was wished very often, which is currently not possible to fulfill with the OOTB capabilities. The client always asks exactly the following question

How can I set an end date for the snapshots?

Right now the behavior of snapshots is very rough described like this:

  • Once a Pricecard is linked correctly to a product, Sitecore grabs all the snapshots and checks if the start dates of the snapshots are greater than the current date time.
  • Then Sitecore sorts all the snapshots descending
  • Finally Sitecore just grabs the first element from that list and evaluates its pricing information

This means, than if the start date of multiple snapshots have been reached and therefore multiple snapshots would be valid, Sitecore takes the latest one to ensure, that at a specific time just one single snapshot is valid.

So for a content author this means, he has to create a snapshot to determine a specific pricing. Once he wants to change that pricing for a specific period of time, e.g. to offer a special price on a special day or a special time span, he would have to create a new snapshot with the new pricing information and and the proper start date. So now the issue starts. Because the author cannot set a specific end date, this price would be valid “forever”. And because we do not want to have that price forever, the author now has to create another snapshot with the old pricing again and the proper start date. This start date has then to be the date, when the special pricing should end. So instead of just creating two snapshots with proper start and end date, the author has to workaround that and create a third helper snapshot to restore old pricing again.

Of course this works, but to be honest is quiet unwieldy. We also asked Sitecore about the possiblity to set an end date on snapshots. The answer was, that they know about that missing feature, and that they are working on implementing that for a later version. But when exactly that feature is implemented by Sitecore themselves is not officially known.

The recommendation of Sitecore then was to implement such a feature on our own.

tenor

How to get rid of this limitation?

The solution is as simple as it might sound. We just implement the possibility to set and end date on snapshots, save that properly and then extend the snapshot evaluation while retrieving pricing information. Sounds easy, right? And yes it is, if you know where to hook in. Let’s have a rough overview of all todos:

  1. Extend the form to enter an end date in addition to the start date
  2. Extend the snapshot to also hold information about end date
  3. Extend the action, which saves the start date to the snapshot to also save the end date to the snapshot
  4. Extend the view to display also the end date in addition to the start date
  5. Extend sellable item and variation sell price calculation to respect the new end date field

Let us start with the task to extend to input form, where an editor can specify the Begin Date. Of course now we would like the user also to be able to specify an End Date the same way.

How do we achieve that?

Quiet simple! I knew this piece of code I need should be in the Pricing Plugin provided by Sitecore. Therefore I simply reflectored that dll to find something close to edit / show snapshot details. After searching a while, I also found the right class GetPriceSnapshotDetailsViewBlock, which you can see below.

2019-11-14 09_43_34-JetBrains dotPeek

So I just took that piece of code and added the new field End Date in the same way Start Date was added. You will see, that I slightly modified the OOTB code a bit also for the standard fields. The reasons for that were, that I wanted to change the date time format a bit when displaying the fields and that I wanted to include another field just in edit mode. But more details later on.

After adding all the stuff properly the new output of the dialog was the following.

2019-11-13 07_40_57-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

So next step is of course, that once an editor sets a proper End Date, we also want this date to be stored somehow on the Snapshot.

To do this, we have to implement a custom DoAction block, which is responsible for taking the properties entered in edit mode and saving them to the entities or components. Again I crawled in the dll and found the proper class DoActionAddPriceSnapshotBlock.

2019-11-14 09_56_12-JetBrains dotPeek.png

So again, I created my own version of that class and added piece of logic to also extract the End Date. The only problem, which now came up was, the issue, how the values were stored on the price card snapshot. Sitecore used a custom command for that. Unfortunately the parameter of that command did not really fit to the new situation of having now also an end date. As you can see, it just accepted a begin date. Of course there were also other overloads of that call, but more or less, they did not fit as well or would lead to a long rat tail I would have to handle. Therefore I decided to just create my own command, based on the given one, and extend also this piece of code to handle End Date properly. The basic implementation can be seen below.

2019-11-14 10_00_09-JetBrains dotPeek.png

My custom implementation is really nothing more, than a command with another endpoint also accepting the parameter End Date and a piece of logic to include the End Date into the snapshot.

2019-11-14 10_02_03-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung.png

Because we are in a an environment, where we prefer composition over inheritance, I had to create a new component, which in the end holds the End Date property.

2019-11-14 10_08_46-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

If Sitecore implements that feature on their own, I am pretty sure, they will just add another property directly in the Snapshot component, like it was done with Start Date. But in the end it does not matter if the End Date property is located directly in the Snapshot component or in another child component. You just have to know where it is for later usage. But that’s already all the magic to set the End Date Property from the point the editor enters it to the point it is part of the Snapshot. Below you can now the the result, after saving.

Note: Here you can already see, that I changed the output date format also a bit to also display time and not only date, which makes it much easier for editors to set Start and End Date minute-by-minute.

2019-11-13 07_43_46-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

Now let’s come to the more interesting part of the implementation. After we have successfully set the End Date we of course also have to evaluate it properly. To do that, I had to find out, where the Snapshots are evaluated at all to also hook in there.

After some time crawling through the dll, I found exactly, what I needed. CalculateSellableItemSellPriceBlock for sellable items sell price calculation and CalculateVariationsSellPriceBlock for variants of sellable items sell price calculation. Within these classes you can see, that the calculation included functions like ResolveSnapshotByCard and ResolveSnapshotByTags, which in the end use functions like FilterPriceSnapshotsByDate and FilterPriceSnapshotsByTags.

2019-11-14 10_16_22-JetBrains dotPeek

2019-11-14 10_16_41-JetBrains dotPeek

In the screenshots above I highlighted exact the location in code, where the snapshot is evaluated. The only thing now we have to do is, that we have to also include the new End Date in that calculation. For demonstration reason I chose the approach to create new classes, one for sellable item sell price calculation and one for variations, the inherited from the existing once and just overwrite the virtual functions to include our new evaluation.

In the End the functions in the new class look like this.

2019-11-14 10_20_56-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

2019-11-14 10_22_41-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

Just a simple evaluation if the End Date has not been reached.

Note: You can see here already an extension I made for End Date evaluation, which I describe in the end in more Detail

Now let’s see all that in action. I created a Pricecard called Demo and attached it to my demo product.

2019-11-13 11_16_20-Rechner

Then I created two snapshots on it. One snapshot should be valid from now to some date far in the future (or has no End Date). And one snapshot should only be valid for just a small time span, in this case just a few minutes. After that, the price of the snapshot before, should automatically take over again, without the need to create a third snapshot. The two snapshots can be seen below.

2019-11-13 11_21_48-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

2019-11-13 11_25_07-Rechner

2019-11-13 11_25_13-Rechner

Now let’s put that sellable item into the cart and see what happens over the time.

We start with a time after the start date of the “normal” price and before the start date of the “special” price.

2019-11-13 11_24_26-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung.png

The result is exactly, what we wanted to have. Because the first snapshot is valid and the second not, Sitecore uses the price from the first snapshot to calculate sell price.

Now let’s call the cart a bit later. The time now falls into the start date of the first AND the second snapshot and also is located within the first and second snapshot end date. From Sitecore OOTB logic, it now should take the snapshot, which start date is closer to the current date time.

2019-11-13 11_41_34-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung.png

And this is also the case, like seen in the screen above. Sitecore uses now our special price instead of the normal price, when we call the cart again.

Last but not least we now want to test the really interesting case. What happens now if we call the cart at a time, where both snapshot start dates are matching, but the end date has expired. We would expect now, that because the end date of the special price snapshot has expired, Sitecore automatically chooses the normal price snapshot again according to the new implementation.

2019-11-13 12_05_58-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung.png

I know the sceeen above looks a bit wild, but displays exactly what happens. When we call the cart again at a time after the end time of the special price, Sitecore really takes the normal price again. As you can see the start and end date of the normal price match. And the start date of the special price matches. But because the end date, displayed in red, does not match, Sitecore does not use that snapshot, like it would do in standard implementation, but uses the first snapshot and uses its price as a valid sell price.

Note: Of course we could come into the situation, where no snapshot is valid, because all the end dates would be reached. But that is also no problem. In such scenarios, Sitecore’s own fallback takes over and uses as fallback to the price card logic simply the list price directly set on sellable item. But of course, if this price would not exist you are screwed and the sellable item would not be sellable anymore and would lead to an error, if trying to add to cart.

Now let me finally show you one little extension I already made, while implementing End Date handling. I believe, that there are scenarios, where some basic price really should have just a start date and no end date. Because the OOTB Date Time field always needs a value to be set, I worked around that and created in addition a small checkbox to let the editor decide, whether the really wants to set an end date. In case he want, he just checks the checkbox and everything is like described above.

2019-11-13 12_16_15-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

In case he does not check the checkbox, the DoAction block I created just ignores, what was transmitted in End Date field and simply writes DatetimeOffset.MinValue into the End Date property. This then can later on be checked and treated e.g. like an non existing value in display, like seen below.

2019-11-13 12_16_59-ALNATURA-DEV - 51.141.30.11_3389 - Remotedesktopverbindung

And as seen before in the sell price calculation we can also react on that specific value to avoid End Date evaluation. This way, in case you do not set an End Date for a snapshot it acts exactly as it did OOTB before.

Conclusion

Within this blog post I showed you easy it can be in general to implemented some missing feature in Sitecore XC. I showed how to start, where to look any how to hook in correctly at the specific locations, which need to be changed.

Within this special change we created a feature, which allows the editor to set additionally to the start date also an end date for price card snapshots to be even more flexible in creating complex pricing scenarios.

As always the full demo code can be found in a repository on my github and as always this code is not production ready and should be used used as an entry point or for demonstration reason.

https://github.com/Chris1415/Plugin.Sample.Pricing.Pricecards

Erfahrungen mit dem Sitecore Experience Accelerator

Nun gibt es den Sitecore Experience Accelerator (kurz SxA) schon eine Weile.  Allerdings gibt es nur relativ wenige Entwickler, die sich wirklich einmal bislang damit auseinander gesetzt haben. Da ich die Idee hinter dem SxA wirklich gut finde, war es nun auch für mich Zeit sich einmal detaillierter damit auseinander zu setzen. Den besten Rahmen hierfür bot der diesjährige Sitecore Hackathon, da eine der dort gestellten Aufgaben die Entwicklung eines neuen SxA Modules war. Bei diesem habe ich zusammen mit Sascha Heyer. und Marina Gluzberg. als Team “Sitecore Triumvirate” teilgenommen. In diesem kleinen Artikel stelle ich den Weg von der Ideenfindung über die Implementierung bis hin zum Ergebnis einmal dar und zeige, wie gut das Entwickeln mit dem SxA in der Praxis funktioniert.

Was ist der SxA

Für alle, die noch nicht wissen, was genau der SxA eigentluch ist. Der SxA dient in erster Linie dazu, die time to market also die sogenannte Phase 1 zu minimieren, umso Ressourcen, Zeit und Kosten zu sparen, damit diese in die wichtigen Anforderungen für bspw. Personalisierung, also eine Phase 2 investiert werden können. Weiterführende Details hierzu kann man bei Sitecore selbst oder diversen Blogbeiträgen, wie Initial thoughts on Sitecore Experience Accelerator (SXA) oder Sitecore Experience Accelerator – What It Is And Why It Matters nachlesen, da ich hier nicht speziell mehr darauf eingehen werde.

Ideenfindung

Kommen wir aber direkt einmal zum interessanten Teil, der praktischen Arbeit mit dem SxA. Das erste was hier anstand, war natürlich das Entwickeln einer Idee. Hier sind wir allerdings sehr schnell, nachdem wir uns die bestehenden Feature angeschaut haben, bei Forms ausgekommen. Wenn man den Bereich Forms aufklappt, erkennt man dort nur eine “Web forms for Marketers” (kurz: WFFM) integration.

2017-03-19 18_01_31-.png
Abb. 1 SxA Features im Bereich Forms

Da wir einerseits bereits in der Vergangenheit so unsere Schwierigkeiten mit WFFM hatten und wir hier klares Optimierungspotential sahen, hatten wir uns dazu entschieden ein neues Formularmodul für den SxA zu bauen. Der Leitgedanke dabei sollte sein das Pflegen von Formularen intiuitiver und einfacher zu gestalten.

Architektur

Da Sitecore selbst es als Best Practice ansieht, aber auch weil der SxA selbst diese Architektur nutzt, haben wir uns bei der Implementierung des neuen Features strikt nach der Helix Architektur gehalten. Das heißt einerseits die Strukturierung der Solution in die Bereiche Foundation, Feature und Project, anderseits, dass alle Bestandteile bspw. eines Featurs innerhalb des Featureprojekts liegt und keine Abhängigkeiten zu anderen Featuren existieren, sondern nur in die darunter liegende Foundationschicht. Abb. 2 veranschaulicht die angelegte Solution.

2017-03-19 18_07_50-Hackathon.Sitecore.Triumvirate - Microsoft Visual Studio
Abb 2. Aufbau der Solution

Hinsichtlich der konrekten Architektur des neuen Formularmoduls hatten wurde überlegt, inwieweit man eine einfache und intuitive Pflegbarkeit erzielen kann. Die Idee war nun, dass ein Redakteur zu Beginn eine Art Formularcontainer, ähnlich wie beim bestehenden Formmodul, auf die Seite zieht. Somit würde der Rahmen des neuen Formulars bestimmt werden. Ab hier soll sich nun das neue Modul vom bestehenden Abheben und weiterhin vollständig über die Toolbox des SxA pflegbar sein. Der Redakteur kann nun weiterhin entweder Formularmodule, wie einfache Eingabefelder, Checkboxen, Datepicker oder sogar den Sendenbutton in den Container plazieren. Andererseits allerdings auch alle anderen bestehenden SxA Module, wie Image-Text- , Slider-  oder Textmodule. Das besondere ist, dass sogar die gelieferten Splitter innerhalb des Formulars plaziert werden können, um so sogar innerhalb des Formuals Aufteilungen in Zeilen und Spalten zu untersützen. Dies ermöglicht es dem Redakteur vollständig individuelle Formulare mithilfe des Drag & Drops Features der Toolbox zu erstellen, was ein klares Alleinstellungsmerkmal gegenüber der bestehenden WFFM Integration darstellt.

Hürden bei der Implementierung

Da bei der Implementierung von SxA Featuren doch einiges zu beachten ist, stellte mich die Entwicklung neuer Module zu Beginn vor gewisse Herausforderungen. Allerdings muss ich direkt anmerken, dass mir die Anleitung “Walkthrough: Building a new rendering” hierbei sehr geholfen hat. Anhand dieser Dokumetnation war es gut nachvollziehbar, warum man genau, wann welche Komponenten benötigte.

An dieser Stelle würde ich gerne lediglich auf die beobachteten Probleme mit der Arbeit im SxA eingehen und an welchen Stellen es einige Zeit brauchte um das gewünschte Verhalten zu erzielen.

Die Implementierung der ersten Controller, Views und Rendering verlief noch vergleichsweise problemlos. Als wir jedoch das erste mal versuchten unsere neuen Renderings in der Toolbox auswählbar zu machen, trat das erste Problem auf. Wir haben im besten Erwarten einfach innerhalb von  “/sitecore/layout/Renderings/Feature/Experience Accelerator/” einen neuen Ordner mit dem Namen “Hackathon” angelegt, wo wir all unsere neuen Renderings abgelegt hatten. Diese hatten wir auch unter “/sitecore/content/Theme/Theme Theme/Presentation/Available Renderings” analog angelegt und hinzugefügt. Allerdings hat sich in der Toolbox nichts getan. Zum Vergleich hatten wir unsere Renderings in einen bestehenenden Ordner, wie Page Content abgelegt. Und natürlich wuden Sie direkt im Experience Editor in der Toolbox an der Stelle Page Content angezeigt. Es galt also unseren neuen Bereich “Hackathon” irgendwo zu “registrieren”, damit die Toolbox dies auch ausspielen kann. Da der Weg dorthin, doch recht umständlich ist, allerdings viele betreffen wurd, würde ich ihn gerne einmal hier beschreiben.

  1. Füge unter /settings/Feature einen Ordner mit dem Namen des neuen Moduls an
  2. Lege dort ein Site Setup Item vom Typ Site Setup Root an
  3. Füge ein Add Available Rendeirngs Item vom Type AddItem hinzu (Abb. 3)

    2017-03-21 10_43_12-Content Editor
    Abb. 3 Einstellungen am Hackathon Site Setup Item
  4. Füge unter /templates/Branches/Feature einen Ordner mit dem Namen des neuen Moduls an
  5. Lege darunter ein neues Branch Template an mit der Basis Available Rendering an
  6. Wähle nun in diesem Available Rendering Item mit dem Namen $name alle Renderings aus, die in der Toolbox auswählbar sein sollen. (Abb. 4 und 5)

Nach der Ausführung all dieser Steps kann beim Anlegen eines neuen Tenant das neue Feature asugewählt werden (Abb. 6) und es werden direkt in der Toolbox alle Renderings korrekt angezeigt (Abb. 7)

Das zweite große Problem trat auf, als wir anfingen, nach den ersten Rendering auch Themes zu customizen. Das Konzept, wie man Themes bearbeiten ist in der offiziellen Anleitung sehr gut und nachvollziehbar dokumentiert.

Allerdings ist der Prozess ein Theme zu exportieren, zu entpacken, die Dateien zu bearbeiten, das ganze wieder zu packen und dann wieder zu imporieren auf dauer sehr zeitraubend. In unserem kleinen Modul, kam es bereits vor, dass ich diesen Prozess mehrere Duzend male durchlaufen musste, insbesondere, wenn ich kleinere Syntaxfehler eingebeaut hatte, die ich erst erkannt hatte, als das Theme wieder in Sitecore integriert wurde.

Um das ganze etwas abzukürzen, habe ich einen Trick versucht, von dem ich aber in der Tat nur abraten kann. Sobald ein Theme in Sitecore angelegt wurde, liegt es innerhalb der Media Library unter “/sitecore/media library/Project” und dort unter dem Tenant Namen, wie in Abb. 8 beispielhaft erkennbar.

2017-03-21 11_02_37-Content Editor
Abb. 8 Teneantspezifische Themes in der Media Library

Innerhalb des Themes kann man dann auch sämtliche Ressourcen, wie Images, Styles und Skripte finden, wie in Abb. 9 beispielhaft erkennbar.

2017-03-21 11_04_36-Christian Handel says...
Abb. 9 Skriptresource in der Media Library

Ab diesem Punkt habe ich nun nurnoch das spezifische JS file via Download heruntergeladen, es bearbeitet und wieder hochgeladen. Dies funktionierte soweit auch wirklich gut, solange ich mich im Edit Mode bewegte. Die ernüchterung kam, als ich den Preview Mode öffnete und nichts mehr funktionierte. Das gesamte JS und CSS waren mit einem Schlag unbrauchbar geworden und es wurden JS Fehler mit dem Title: Namespace SX not found geworfen. Das einzige was noch halb, war das Theme zu löschen und komplett neu anzulegen und nach dem Schema der Anleitung zu arbeiten mit einem echten Export und Import. Hier gibt es sicherlich noch Verbesserungspotential im Umgang und der Plfege von Resourcen wie CSS und JS.

Resultat

Als Ergebnis nach 24 Stunden Arbeit während des Hackathons haben wir in der Tat eine erste Version des sogenannten “Form Composers” implementiert. Die Kernfeature des neuen Moduls sind

  • Leichtgewichtigkeit durch Reduktion auf Basisfeature und -funktionalitäten
  • Hohes Maß an Flexibilität durch Kombination von standard SxA und Formular modulen
  • Einfache Pflegbarkeit bspw. via Drag & Drop
  • Unterstützung von gängigen Standardformularfeldtypen, wie Single-Line-Text Checkbox oder Datepicker
  • Unterstützung eines Mailversands bei erfolgreichem Absenden
  • Untersützung von Pflichtfeldeingaben und Fehlerfallvalidierung bei nicht-Eingabe
  • Einfache Erweiterbarkeit mit neuen Feldtypen und Funktionalitäten

Durch den neuen Form Composer ist der Redakteur in der Lage auf einfachste Weise mittels Drag & Drop zuerst einen Container auf der Seite zu plazieren und diesen dann nach belieben mit weiteren Modulen zu befüllen. Diese Module können SxA eigene Module wie Slider oder Textmodule sein. Oder es sind die neuen Form Composer Feldtypen, wie Single Line Text, Checkbox oder Datepicker. Das besondere hier ist, dass sogar die SxA eigenen Splitter in Rows und Columns unterstützt werden, so dass der Darstellung des eigenen Formulars keine Grenzen gesetzt sind. So können bereits schnell einfache Formular zusammengeklickt werden, welche einfachste Anforderungen erfüllen, wie in Abb. 10 zu sehen.

2017-03-20 14_24_59-Sascha
Abb. 10 Pflege eines einfachen Formulars

Es können aber auch hoch-komplexe Formulare mit dem neuen Composer erstellt werden, welche in verschiedene Bereiche aufgeteilt ist, mit weiteren Modulen und weit verteilten Eingabefeldern. Ein Beispiel eines solchen Formulars ist in Abb. 11 zu sehen, wo wir zu Demonstrationszwekcen einmal eine Variation des Hackathonanmeldeformulars nachgebaut haben. Hier wurden in den Formularcontainer zuerst die verschiedensten Grids gepflegt, um eine geordnete Aufteilung zu erhalten. Innerhalb dieser Grids wurden dann sowohl standard Module, als auch eignee Formularmodule plaziert.

2017-03-20 14_24_04-Demo
Abb. 11 Pflege eines komplexen Formulars mittels des Form Composers

Das eingesendete Video zum Abschluss des Sitecore Hackathon 2017 zeigt auch noch sehr anschaulich, was alles möglich ist und welches Potential dieses Modul hat. Der gesamte Sourcecode mit Dokumentaion ist unter folgendem Repository zu finden, damit man sich auch selbst ein Bild der Implementierung machen kann.

So läasst sich sagen, dass mit diesem Ergebnis man bereits erkennen kann, dass es verglichsweise leicht ist, mittels des SxA neue Module zu bauen, oder bereits bestehende Module in Seiten wiederzuverwenden, um so individuell auf jeden Anwendungsfall oder Kundenwunsch eingehen zu können.

Fazit

Die Idee des SxA ist Webseiten schnell und einfach zu bauen. Nachdem ich nun einige Zeit damit verbracht habe die ersten eigenen Module und Seiten zu bauen, kann ich sagen, dass im SxA viel potential steckt. Mithilfe des Sets an Featuren kann man bereits viele standard Kundenanforderungen umsetzen. Mit der Zeit lässt sich dieses Set stets erweitern, so dass man diese auch für zukünftige Anforderungen nutzen kann. Theoretisch können während der Entwicklung von neuen Modulen, bereits mit dem bestehenden Set an Featuren Seiten via Wireframing gebaut werden. Mit den ersten Visual Designs kann bereits während weiterer Entwicklungen Content gepflegt werden. So erkennt man schon, dass viele Arbeiten, die früher seriell abliefen nun teils parallel stattfinden. Genau dieser Mehrwert hat in unserem kleinen Team bereits sehr gut funktioniert. Wir konnten auf bestehende Features des Sxa zurückgreifen und via Themes unseren individuellen Wünschen anpassen. Parallel zur finalen Contentpflege konnten noch weitere kleinere Implementierungen bzw. Themeanpassungen durchgeführt werden, so dass zum Schluss aus den gepflegten Wireframes, dem Content und den Themes die mit einem Klick eine fertige Seite entstanden ist.

Das praktische Arbeiten mit dem SxA zeigte an der ein oder anderen Stelle noch einige Schwächen. Es kam bspw. häufiger vor, dass der SxA bei der Pflege im Experience Editor leider noch abstürzte. Bei der Pflege bzw. dem Anpassen von Thems ist der Prozess das Theme erst herunterzuladen, zu entpacken, seine Änderungen durchzuführen, das ganze wieder zu packen und zum Schluss wieder zu importieren auf dauer sehr umständlich. In unserem Fall dieser Prozess einige dutzend mal durchgeführt werden, bis sowohl CSS als auch JS so waren wie sie sein sollten. Hier wäre es sicherlich sinnvoll dem Entwickler eine einfachere Möglichkeit zu geben Themes anzupassen.

Nichtsdestotrotz hat Sitecore mit dem SxA ein jetzt schon bemerkenswertes Modul erschaffen, welches das Potential hat die einfache Webseitenimplementierung mit Sitecore zu revolutionieren.

IT-Talents Code Competition Juni 2016

Hier möchte ich euch an der IT-Talents Code Competition aus dem letzten Monat teilhaben lassen.
Nach langer Pause, habe ich mich endlich wieder entschlossen, an einer der Code Competitions von IT-Talens mitzumachen.

In dieser Code Competition ging es grundlegend darum, zum einen zu einer bestimmten Postleitzahl zu ermitteln, welche Tankstellen in einer Umgebung, welchen Preis für Sprit angeboten haben und wo es den billigsten Sprit gibt. Zum anderen sollte auch eine Art Datenbank aufgebaut werden, mit welcher man in der Lage war, zu ermitteln, zu welcher Zeit (Tageszeit) das Tanken im schnitt am günstigsten ist. Zur Aufgabenstellung

Hier muss ich gestehen, dass mich die Thematik dieser Competition schon sehr interessiert hat.
Zum einen habe ich schon seit einigen Wochen darüber nachgedacht, so etwas in der Art zu bauen. Seitdem ich mir einen eigenen Wagen gekauft habe, achte ich doch schon sehr darauf , wo und zu welchem Preis ich tanke. Daher passt dies wirklich sehr gut.
Zum anderen ist es aber auch die technische Thematik, die mich hier gereizt hat, teilzunehmen. Man muss sich in eine externe Schnittstelle einarbeiten, diese ansprechen und die daraus resultierenden Daten auswerten. Desweiteren musste ein eingermaßen gescheiter Algorithmus zur Ermittlung der besten Tageszeit zum Tanken implementiert werden. Ebenso die denkbaren Zusatzfeature, wie eine graphische Ausgaben, der Daten waren schon sehr reizbar.

Somit war die Entscheidung ziemlich klar …. Ich nehme mal wieder an einer Code Competition teil.

Da diverse Sprachen und Frameworks zur Auswahl standen und ich mich beruflich mit C# und ASP.NET beschäftige, lag die Entscheidung nahe die Applikation in ASP.NET MVC.

Nach nun fast einem Monat entstand als Ergebnis eine Applikation, welche nun alle Hauptfeature aufwies, aber auch mit diversen geplanten Zusatzfeature ausgestattet war.
Ich könnt gerne selbst einmal reinschauen und euch ein Bild davon machen.

Zum Aufsetzen der Appliaktion einfach

  1. Repositiory bei Github runterladen – Petrolcalculator
  2. In Visual Studio öffnen
  3. In der web.config die Tankerkoening und GoogleMaps API-KEYS einsetzen

UPDATE (Okt-2016):

Nach langem Warten kam nun endlich eine Antwort von IT-Talents. Tatsächlich war meine Software so gut, dass sie Platz 3 gemacht hat.

Für die 2. Teilnahme an einer Code Competition schon einmal nicht schlecht. Wenn ihr wissen wollt, mit wlecher Software ich das schaffen konnte, ladet sie einfach runter und schaut selber rein. Ansonsten schaut gerne einmal im IT-Talens Blogeintrag hierzu rein.

Implementation of a Website Health Checker to improve Continues Delivery processes – Part 6: Website Health Checker – Interfaces and Implementation

Now I will present a few interesting parts of the implementation of the Website Health Checker. Architecturally, a strict separation between application logic and underlying business logic has been made. This can be seen in the fact that the controllers in this implementation have only one purpose. They merely accept the request from the outside, either the graphical user interface or another web request, prepare the parameters and call the business logic. The actual logic in this application has been implemented using various services, which are enclosed for easy use by a service facade. This makes the application logic very easy to use the full functionality without knowing the implementation behind this. Figures 1 and 2 show examples of two controller functions and how these pass through the request to the correct location.

2016-11-26 12_36_37-WebsiteHealthChecker - Microsoft Visual Studio (Administrator).png
Fig.1 Request handler to execute the Website Health Checker via graphical user interface
2016-11-26 12_37_52-WebsiteHealthChecker - Microsoft Visual Studio (Administrator).png
Fig. 2 Request handler to execute the Website Health Checker via an external interace call

It is easy to see here that the parameters are validated and, if validation is successful, only the service facade is called to execute the actual check. The facade itself provides at the moment exactly 2 functions that can be used for web site testing. These are shown in Fig. 3

2016-11-26 12_43_05-WebsiteHealthChecker - Microsoft Visual Studio (Administrator).png
Fig. 3 Service facade interface

The service facade itself now has a number of its own services for the actual execution of the web page check. There are services such as an availability check service, a screenshot service, a mail service and many more, each with its own small task. Such an architecture makes it very easy to exchange functionalities, without having to interfere with the code at various points. Furthermore, the application logic here, MVC with its controllers, is very interchangeable with another technology, such as Webforms or WPF, since it suffices to make the ServiceFacade accessible again.

Finally, I’ll briefly show the simple but sufficient implementation of the check itself within the AvailabilityCheck service. Figures 4 – 6 show the entire funtion. Note that the functionality is still in the phase of a PoC and has not yet been optimized.

2016-11-26 16_59_43-WebsiteHealthChecker - Microsoft Visual Studio (Administrator).png
Fig.4 Websitecheckimplmentation initialization phase
2016-11-26 16_59_58-WebsiteHealthChecker - Microsoft Visual Studio (Administrator).png
Fig. 5 Websitecheckimplmentation main logic
2016-11-26 16_39_23-WebsiteHealthChecker - Microsoft Visual Studio (Administrator).png
Fig. 6 Websitecheckimplementation error case handling

It is easy to see that the real “logic” behind the whole implication is very simple. Only the website is accessed using the supplied URL. You get directly the information about the status code and the markup. In the following, the ScreenshotService, which is specifically implemented for this purpose, is used, which essentially emulates a browser and calls the web page rendered and as a result provides a bitmap of the web page. This also takes the time to call, since it provides a more valid value than simply measuring the time for a simple WebRequest, as many other applications try to measure the call time of a web page. If errors occur during processing, these are intercepted and treated accordingly. Thus, e.g. In the case of a status code 401 or 403, an exception is thrown at the normal web request, which must then be treated separately, which can be seen in detail in Fig. 6

To conclude this post I will briefly show another essential part of the application, namely the generation of the comparison model. For this purpose, there is a small function, which builds the comparison model by means of two delivered ResultModels, the current and a previous check. This function is shown in Fig. 7

2016-11-26 13_10_52-WebsiteHealthChecker - Microsoft Visual Studio (Administrator).png
Fig.7  Function to build the comparisonmodel

At the beginning, there is again a short parameter check as always. The comparison model is then built up itself. On the one hand, it can be seen here that very simple comparison numbers are determined via simple operations, e.g. whether the status code or the browsertitle has changed. If there are more complicated key figures, like a comparison of screenshots or markup, I use extension methods, which in turn encapsulate the functionality for the required comparisons into their own implemented services.

An example of this is the “Diff” method on bitmaps. In Fig. 8 you can see the actual implementation of the diff method. Here, it should also be considered that the code is in a state of the PoC and should be further optimized for a product application.

2016-11-26-13_17_41-hach-library-microsoft-visual-studio-administrator
Fig. 8 Extension method “Diff” to get the diffrence in two Bitmaps

In this method you can directly see that the interface IImageCompareService is used internally for comparison. For the sake of simplicity, I have instantiated a specific service directly from this, also because there is currently no other. In the future, however, it should be possible to use a parameter to specify the type of comparisonservice  to be obtained via a Diff so that the correct service is then instantiated and executed, as in a service factory. The current service only compares a hash value of the bytearrays of the images at the moment and can thus determine whether they are identical or not.

Basically I could still write pages about the implementation of the website health checker, but I think the most important features and implementations are clear up to now. Anyone who has more detailed questions or just want to see further implementations can always ask and it would be a pleasure to give more information.

So much for this part of the series. In the last part of my Posts, I will briefly summarize the status quo of the application, give an outlook for optimizations and extensions, but also clearly state the current limitations.

Implementation of a Website Health Checker to improve Continues Delivery processes – Part 5: Website Health Checker – Appearance and Interaction


In this post of my blog series, I will now go to the largest and most important part, the Website Health Checker itself. The Checker is a comparatively simple MVC application. On the one hand, it is directly accessible via a graphical interface, on the other hand via an interface provided for this purpose. As mentioned in Post 3, the interface for web requests is implmented for the uasge e.g. via the jenkins. The graphical interface, on the other hand, is used for direct interaction, e.g. via a browser, and offers extended interaction possiblitiy and a detailed output of the results.

Fig.1 shows an example of this graphical user interface. You can already see the charm of the standard MVC application. The application is divided into an input and output area. The input is made for the sake of simplicity via predefined entries in the web.config, which are read out at runtime and then displayed as a possible test destination.

2016-11-25-15_01_16-home-my-asp-net-application
Fig.1 Graphical User Interface of the Website Health Checker

It is sufficient to specify the interface URL of the target mentioned in Post 4. At the beginning of the application, it briefly checks whether the host of this URL is reachable. If so, this url is released for a check. This is done graphically with the output of a green Available.

If you now select the check button, the test will run automatically and fill the output area of the application dynamically. Some of these entries are shown in Fig. 2 Here, You can see that I took a simple Accordion to represent the results. Visually, each accordion entry is highlighted with green or red, regarding if the site is reachable or not, so the user can see directly if some sites are down.

2016-11-25-15_16_02-home-my-asp-net-application
Fig. 2 Representation of the check results

By clicking on the Accordion element, the details of the respective check of the URL are opened. Fig. 3 shows an example of such an unfolded accordion.

2016-11-25 15_21_56-Home - My ASP.NET Application.png
Fig.3 Representation of the check results per site

This single output is subdivided into an area for the results of the previous test, a section for the current test and a section for the comparison of the two tests so that the user at directly receives all the necessary information especially if something has changed. There you can see all the declared values  for the status of a web page that are targeted in Post 2.

If, on the other hand, you use the Webrequest interface to interact with the Website Health Checker, you simply call up the interface that is provided for this, just as the Jenkins makes it. This executes the corresponding parameterized web page check, and returns rudimentary information of the result in text form. As soon as the check has been completed, you will receive an more detailed e-mail with all the known information, if you have set this parameter. Fig. 4 shows, for example, such a call with return.

2016-11-26 14_15_09-Mozilla Firefox_ IBM Edition.png
Fig. 4 Call of the Website Health Checker via webrequest interface

Depending on whether the call was successful or not, a success message appears, as in this example, or a message with the corresponding error.

In the next part of the post I will now go on parts of the architecture and implementation and show how simple this actually is at the end.