Monday 27 November 2017

Custom Remote Events for Cache Rebuild mechanism

A couple of months ago I had to jump into a project for a while and I came across a problem with refreshing custom cache on content delivery servers. There was a custom cache mechanism that was running on each instance separately. It was relying on items based on specific template, every time one of these items was updated or created/removed, cache should be updated. I found out that the best way to refresh that is to prepare custom remote event.

The problem

I had to make sure that after publishing specific items, cache will be rebuilt. My first thought was to use publish:end event, so I could check if one of that items was published. But here the problem with checking came out. There is a parameter of class Publisher that is put to EventArgs on position 0. Unfortunately, it doesn't contain any list of published items, just the root item:

publisher.Options.RootItem

...or maybe fortunately, for huge amount of items published :) Anyway, if we are relying only on this property, we need to go through all items recursively to find the specific one:

publisher.Options.RootItem.Axes.GetDescendants().Any(x => x.TemplateID.ToString() == SpecificTemplateId)
You might see that here, on some publish events, using Axes and GetDescendants() is not very good idea (most of times it's not!). And we need to keep in mind that RootItem will be null if user ran full site publish...

Improve the performance

Okay, maybe some better ideas? Yes. There is an event called publish:itemProcessed that is fired every time an item is processed during publish. We can use it to find if currently processed item is based on specific template and then set some flag.


Flag used here will be static property of the event handler class:

/// <summary>
/// Static flag that indicates if any specific item was published
/// </summary>
protected static bool SpecificItemWasPublished = false;


After all items have been processed, the publish:end event will be raised. Here we can check if flag is set to true and run cache refresh action. This solution will work gracefully on single server application, but on CM/CD separated instances it will work only on Content Management server. We need to work out a better solution using custom remote events.

Using custom remote event

Custom remote event will be the best option to solve this problem. Our cache refreshing system will work like this
  1. While publishing we check if specific item is published - on publish:itemProcessed event. If there is one, we set up the flag.
  2. When publishing finishes (publish:end) we check the flag. If flag is set up, we raise cache rebuild event
  3. Cache rebuild event will raise remote event for cache rebuild.
Using this approach all hard work, like checking specific item published, will take place on the local server, remote servers will just do what first told them. It all works using EventQueue.

1. Class for remote event representation
First thing that we will need will be class that represents an event. There is no base class to derive or interface to implement, it can be plain class but members need to be serializable. In our example we will have a boolean flag that will indicate if full rebuild is needed.

2. Event raiser class
Next we will need a handy class that will be able to raise the event locally and add request to Event Queue for raising it on remote servers.

3. Pipeline processor for initializing event subscription
We need to create a pipeline processor that will subscribe to those remote events.

4. Event handlers class
This class will contain our event handlers. As described earlier OnItemProcessed will check if currently processed item is based on specific template and set up flag if found. OnPublishEnd will check that flag when publishing is finished and raise cache rebuild event using prepared earlier event raiser. Last event handler OnCustomCacheRebuild will do the actual call to index mechanism for cache rebuild.

5. Sitecore config patch
At last we have to bind all event handlers and processors into Sitecore. This Sitecore config patch does that:
 
And that's all, with all these parts our system is ready to use.


Testing solution 

To test our solution we need to set up two Sitecore instances on our local machine, first for CM role, latter for CD role.They need to have different InstanceName properties set in App_Config\Include\ScalabilitySettings.config.

<setting name="InstanceName">
  <patch:attribute name="value">SitecoreCoffeeCM</patch:attribute>
</setting> 

As well those two instances need to use the same databases.

After setting up those instances and publishing item based on specified template on CM server, there will be new record created in Core database in EventQueue table:

Id:            C3386293-8E1B-4EBB-A490-D57DC663E61B
EventType:     SitecoreCoffee.Foundation.RemoteEvents.Events.CacheRebuildEvent, SitecoreCoffee.Foundation.RemoteEvents, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
InstanceType:  SitecoreCoffee.Foundation.RemoteEvents.Events.CacheRebuildEvent, SitecoreCoffee.Foundation.RemoteEvents, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
InstanceData:  {"FullRebuild":true}
InstanceName:  SitecoreCoffeeCM
RaiseLocally:  0
RaiseGlobally: 1
UserName:      sitecore\admin
Stamp:         0x0000000000032E9E
Created:       2017-11-21 23:20:01.267

And as well on those two instances cache will be rebuilt:

ManagedPoolThread #2 23:20:01 INFO  CacheRebuildEventHandler: Rebuilding the cache.
ManagedPoolThread #2 23:20:01 INFO  CacheRebuildService: Cache rebuilt (full: True)
ManagedPoolThread #2 23:20:01 INFO  CacheRebuildEventHandler: Cache rebuilt in 0 seconds.

Summary

Solution described above explains how to use custom events in Sitecore to create efficient mechanism that will rebuild cache on local and remote servers, when specific item is published. It can be used to perform any other type of action that will require additional activity taken on remote servers.

Full code is available in my Helix solution here: https://github.com/ReoKzK/SitecoreCoffee

Happy Sitecoring!

Friday 31 March 2017

Translating Sitecore Client

Translating Sitecore Client to another language is not so tough issue. Sitecore comes with a pretty clean solution here. In this article we will use Sitecore 8.2 Update-2.

There are some ready-to-install client translations at Sitecore download site (section "Client Translations"): https://dev.sitecore.net/Downloads/Sitecore_Experience_Platform/82/Sitecore_Experience_Platform_82_Update2.aspx. The choice is not too big, there are only for Danish, German and Japanese. Fortunately, we can create our own client translation.

Preparation

First of all, we need to install language in Sitecore on specific database. We will start with core, where most of our client translations are kept. Let's go to Desktop and switch to Core db. After that let's go to Control Panel. Here we should add new language and set language code for it. In my example I will add Polish language

Sitecore - Control Panel - Add new Language

I'm leaving all steps with default values, so my Polish language code will be "pl-PL". After that we can check it in Content Editor under /sitecore/system/Languages:

Sitecore - Content Editor - Languages

Exporting language file

At this point we need to have a file that will be our source for translation. In other words, we need to export language file from one of existing languages in Sitecore. To achieve that, let's go again to Control Panel. There should be Core database selected as earlier. In Control Panel click on the Export languages and select the language you want to base your translation on:

Sitecore - Control Panel - Export language

After clicking next, you can choose which branch to export. For making translations select sitecore root item:

Sitecore - Control Panel - Export language - select item

After that you will be prompted for location of generated file. In the end Sitecore will process all items and language xml file will be generated.

Preparing language file

Let's take a quick glimpse to the exported language file. You can see that this is just xml file with <phrase> elements. Each that element represents single field of item and contains attributes like:
  • path - path of the item
  • itemid - id of the item
  • key - key name of field
  • fieldid - name of the field
  • updated - date of field update
Inside <phrase>, there is another xml element named after the language code. It surrounds the field value we will translate.

Sitecore - Exported language file

Next thing is to replace language elements with our destination language. In my case it will be pl-PL. The easiest and fastest way will be use some text editor and globally replace:
  • <en> to  <pl-PL>
  • </en> to  </pl-PL>

Replace globally


And that's it! File is prepared for sending to some translation services. They just need to know what they have to translate:

<phrase path="/sitecore/client/Speak/Layouts/Renderings/Common" key="Common" itemid="{1F2A25A4-A532-4E9B-9942-1FA6F10F61B0}" fieldid="__Short description" updated="20130814T120321Z">
    <pl-PL>Common controls like buttons, input fields, and lists.</pl-PL>
 </phrase>
In my case it should be translated to:

<phrase path="/sitecore/client/Speak/Layouts/Renderings/Common" key="Common" itemid="{1F2A25A4-A532-4E9B-9942-1FA6F10F61B0}" fieldid="__Short description" updated="20130814T120321Z">
    <pl-PL>Wspólne kontrolki, takie jak przyciski, pola wprowadzania, czy listy.</pl-PL>
 </phrase>

Just trust me ;)

Importing prepared language file

As we have our language file translated we can import it to Sitecore. Before that, it is highly recommended to backup processed database - in our case Core database. After our backup is done we can import our translation file. To achieve that let's go to Control Panel and click Import languages:

Sitecore - Control Panel - Import languages

Then we need to upload our prepared xml file (or put it somewhere in webroot of our Sitecore). After selecting the file, Sitecore should recognize what language we are importing.

Sitecore - Control Panel - Import languages

Then we need to select the database which items we were translating - for us it is the Core database.

Sitecore - Control Panel - Import languages

After a while import will be finished.

Configuring Sitecore client language

After the import we can use our language. One of the ways is to set globally Sitecore client language in the Control Panel. In the My settings section, there is a Region and languages options link. It opens window where we can set viewing formats and Display language:

Sitecore - Control Panel - Region and languages options

After setting it, you will be prompted to refresh browser window - and you can enjoy the translated Sitecore! More info on installing translations can be found on Sitecore documentation: https://dev.sitecore.net/Downloads/Sitecore_Experience_Platform/82/~/link.aspx?_id=D72CBF8CE581436CBBCAEE896C8646F7&_z=z

Another way is to set the language just for the user. We can find it in the User Manager by clicking Edit on selected user and setting Client language on Language settings tab.

Sitecore - User Manager - Language settings

Translating master database

We were translating only core items, but we can also translate master database items. I might not have sense for all Sitecore items, but for short descriptions of main items like content, layouts, templates, etc.


Happy translating!

Tuesday 28 February 2017

Sitecore development basics - Tools overview

As a Sitecore beginner it is very hard to get to know with all the tools used in Sitecore development process. Especially that you don't even know that some of them even exist. In this article I will try to collect must-haves that every Sitecore developer should know and use.

Object mapping

Object mapping frameworks are very useful in Sitecore. Using some objects based on transparent classes with full Intellisense support is more comfy than using Items with fields explicitly.

Glass.Mapper is the most popular ORM for Sitecore. It gives the availability to map Sitecore items to strongly typed objects, then they can be used in general code and unit tests as well. Glass is well optimized and easy to use.

Glass.Mapper has its own website - http://glass.lu/.
Tutorials can be found there also - http://glass.lu/Mapper/Sc/Tutorials.
 


 

Fortis is a tool similar to Glass but it is more like a wrapper than the mapper. It encapsulates Sitecore items with interfaces. Code is available here: https://github.com/Fortis-Collection/fortis and more info about usage here: http://fortis.ws/quick-start/ and here: http://fortis.ws/about/


Synthesis takes different approach than the two ones described earlier. It generates code based on templates in Sitecore instead of mapping fields or wrapping items. It is also very fast. Synthesis code is available on GitHub - https://github.com/kamsar/Synthesis and more info on wiki there https://github.com/kamsar/Synthesis/wiki

Serialization

Data serialization is a must in Sitecore projects. Solution must have a way to transfer templates, layouts and other types of items to different environments. It also should be automated for e.g deployments. Luckily there are some cool tools that solve this problem.

Team Development for Sitecore (TDS) is a tool from Hedgehog Development that gives availability to put and manage Sitecore items from the Visual Studio. Beside the serialization features it has a lot of other functionalities like code generation, .update package generation, delta deployments and many more. It is easy to use as well.

Official website - http://www.teamdevelopmentforsitecore.com/
Documentation - http://hedgehogdevelopment.github.io/tds/


Unicorn - tool from Connective DX, created by Kam Figy. Solves the same problems as TDS but in a bit different way. Whole serialization setup is configured in config patches and also there is a web console to fire the synchronization. Worth to mention are also Rainbow - new serialization engine using yaml files for items (they merge excellently) and also transparent sync. And off course it is free to use.

Repo at GitHub - https://github.com/kamsar/Unicorn
Kam's blog - http://kamsar.net/ - highly recommended source for new versions information.


Sitecore Courier is a tool that can build Sitecore update packages automatically. It can analyze serialized items and pack only changed ones. It comes with console runner, so builing packages is even easier. You can find it at Sitecore Marketplace: https://marketplace.sitecore.net/en/Modules/Sitecore_Courier.aspx and the code is located at GitHub: https://github.com/adoprog/Sitecore-Courier. More info can be found at blog by Alexander Doroshenko: http://sitecoresnippets.blogspot.com/2012/10/sitecore-courier-effortless-packaging.html



Continuous Integration


Sitecore Ship is a tool that gives availability to install Sitecore update packages remotely. As TDS and Unicorn have their own hooks for integrating with CI systems, Sitecore Ship fills a lack of it in Sitecore Courier. Full code is available on GitHub: https://github.com/kevinobee/Sitecore.Ship. Api documentation is here: http://docs.sitecoreship.apiary.io/. There are also PowerShell functions by Patrick Perrone https://github.com/patrickperrone/Sitecore.Ship-PowerShell-Functions




Sitecore Package Deployer from Hedgehog Development is a similar tool to Sitecore Ship. Instead of deploying packages sent by HTTP it deploys them from file system. More info you can find on TDS website: https://www.teamdevelopmentforsitecore.com/Blog/sitecore-package-deployer. Full codebase is available at GitHub: https://github.com/HedgehogDevelopment/SitecorePackageDeployer - you can find there installer also - built as .update package.

Data migration

Sometimes we need to transfer data between some Sitecore instances. It might be for update UAT environment with production content or maybe for Sitecore upgrade purposes, with approach of setting fresh new Sitecore instance.

RAZL is another nice tool from Hedgehog Development. It's purpose is to add availability to compare databases of two Sitecore instances and look for differences. It also adds option to move and synchronize data between instances.


Content Migrator Sidekick App by Jeff Darchuk is a tool for moving data between instances. It's core is Rainbow - serialization engine designed by Kam Figy for Unicorn. It needs a Sidekick installed first: https://jeffdarchuk.com/2016/10/03/sitecore-sidekick/. More info you can find at Jeff's blog: https://jeffdarchuk.com/2016/10/24/sitecore-sidekick-content-migrator/.


Coast for Sitecore is a module that was designed to give an easy copy-paste functionality for moving items between Sitecore instances. Here is more info about that: https://www.geekhive.com/buzz/post/2016/11/introducing-coast-for-sitecore/. Now, there is a version 3.0: https://www.geekhive.com/buzz/post/2017/02/introducing-coast-for-sitecore-version-3-0/. You can find it on Sitecore Marketplace: https://marketplace.sitecore.net/en/Modules/S/Sitecore_Coast.aspx.

Visual Studio plugins


 Sitecore Rocks was designed to integrate whole Sitecore stuff with Visual Studio. You can connect with your instance, edit items and manage just like in the Content Editor. It can really increase developer productivity. Plugin is available here: https://marketplace.visualstudio.com/items?itemName=JakobChristensen.SitecoreRocks and code on GitHub: https://github.com/JakobChristensen/Sitecore.Rocks

Unit testing

FakeDb is a unit testing framework for Sitecore. It enables creating fake Sitecore database, so then it can be used in tests. It can be found on GitHub: https://github.com/sergeyshushlyapin/Sitecore.FakeDb. There is also a pretty nice documentation: https://github.com/sergeyshushlyapin/Sitecore.FakeDb/wiki


AutoSitecore is a bunch of AutoFixture customizations prepared to use new testability features in Sitecore 8.2. It was created by Dan Soloway and it is available here https://github.com/dsolovay/AutoSitecore


Solution architecture


Helix, as the documentation says, is a set of overall design principles and conventions for Sitecore development. You might heard of this from Habitat project, which was the introduction to that approach. Helix was prepared to structurize all of that principals. Full documentation is here: http://helix.sitecore.net/. Full code of Habitat is here: https://github.com/sitecore/habitat.

Ignition - this is a development accelerator designed by team at Perficient. You can read more about that at Perficient website http://blogs.perficient.com/microsoft/2016/06/sitecore-developers-start-your-ignition/. Whole code is available on GitHub https://github.com/sitecoreignition/SitecoreIgnition. Here is also quick start guide: https://www.youtube.com/watch?v=rtd1XkWFKhw.






Sitecore official modules

Web Forms For Marketers (WFFM)
Module that adds availability to create forms in Sitecore and use them to collect user information and store it for analytics purposes. Official documentation is here: https://doc.sitecore.net/web_forms_for_marketers/

Email Experience Manager (EXM)
EXM is a module that enables creating e-mail campaigns. Official documentation: https://doc.sitecore.net/email_experience_manager

Federated Experience Manager (FXM)
FXM module is used to integrate non-Sitecore sites with existing Sitecore instance. You can track user information and collect that to extend whole user profile in Sitecore. Official documentation: https://doc.sitecore.net/sitecore_experience_platform/digital_marketing/federated_experience_manager

Sitecore Experience Accelerator (SXA) 
SXA provides reusable layouts and components for rapid website development. Official documentation: https://doc.sitecore.net/sitecore_experience_accelerator

Sitecore marketplace modules

Sitecore PowerShell Extensions - this module gives you the power of PowerShell inside Sitecore. It is incredibly useful and fast for advanced usage. A lot of examples can be found on blog by Adam Najmanowicz: http://blog.najmanowicz.com/sitecore-powershell-console/. You can download it from Sitecore Marketplace: https://marketplace.sitecore.net/en/Modules/Sitecore_PowerShell_console.aspx.



Front-End development

Feydra is another great tool from Hedgehog development. It gives front-end developers availability to work directly on virtualized Sitecore instance using their own tools. They can commit changes without intervention of back-end developers. More info about Feydra can be found here: http://www.teamdevelopmentforsitecore.com/Feydra.


Other stuff

Dianoga is a tool from Kam Figy that optimizes images for the media library. Full code is available here: https://github.com/kamsar/Dianoga.

Sitecore Instance Manager (SIM) is a great app that will help you manage your Sitecore instances. You can rapidly install new fresh instance with just few clicks. That is really helpful while investigating if some bugs are present in clean Sitecore or just in your code. You can download it from Marketplace: https://marketplace.sitecore.net/en/Modules/Sitecore_Instance_Manager.aspx and the code is available on GitHub: https://github.com/Sitecore/Sitecore-Instance-Manager

Sitecore Log Analyzer (SCLA) is a tool for analyzing Sitecore logs. It is very handy in situation when you need to find some entries but logs are splitted. You can search by dates and entry types. You can download it from Marketplace: https://marketplace.sitecore.net/en/Modules/Sitecore_Log_Analyzer.aspx

Sitecore Support Package Generator (SSPG) was designed for helping developers collecting all crucial data needed to investigate problem by Sitecore Support. It is very useful - it can take all required Sitecore and IIS logs, pack it and send right to Support. It is available at Sitecore Marketplace: https://marketplace.sitecore.net/en/Modules/Sitecore_Support_Package_Generator.aspx

Summary

Off course this list is just a quick overview of available Sitecore tools, but I hope it will give you more information how efficiently develop Sitecore applications. Happy Sitecoring!


Friday 13 January 2017

Razl scripting with PowerShell

Razl, tool from Hedgehog Development, that was designed to transfer items between Sitecore instances and compare them, has some nice scripting features.

I needed to use Razl scripting for Sitecore upgrade process. I created new fresh Sitecore instance (it was big jump, from 6.5 to 8.1) and started preparing what should be moved to new database. Old instance had a lot of datasource items and huge amount of media library items. Transfer all of this things was huge deal and was processing for over a dozen of hours. I decided to make some changes in my approach.

Preparation of Sitecore instances

I was using Razl 3.0.5. Unfortunately I had some problems with my solution that I couldn't connect with this tool to the Sitecore that had all of solution code deployed, so I've created a clean instance of version 6.5 and a clean version of 8.1. I've changed the connection strings of this two to the correct solution databases and I used this two clean instances just for transferring purposes - worked like a charm. You might not have exact problem, but this is how I went through that.

Preparing Razl script file

First you have to prepare the script file in the Razl. You can do it just like in general, by adding tasks to Task List:


Then, instead of running transfer, you can click 'Export Tasks' button. You will be prompted to save the script file. Let's take a look into the one:
<?xml version="1.0" encoding="utf-8"?>
<razl>
  <connection name="SC65VanillaWithSW.Master" readOnly="false" install="true">
    <url>http://sc650vanilla/</url>
    <accessGuid>047c5600-e111-449c-9e2b-179b06f17190</accessGuid>
    <database>master</database>
    <path>C:\inetpub\wwwroot\sc650Vanilla\Website</path>
  </connection>
  <connection name="SC81VanillaForSW.Master" readOnly="false" install="true">
    <url>http://sc81u2vanillaforconnection/</url>
    <accessGuid>8db29355-a8d4-4102-969a-537cc8c54f30</accessGuid>
    <database>master</database>
    <path>C:\inetpub\wwwroot\sc81u2vanillaforconnection\Website</path>
  </connection>
  <operation name="CopyAll" source="SC65VanillaWithSW.Master" target="SC81VanillaForSW.Master">
    <!--Copy with overwrite '/sitecore/templates/SW', all missing parents and all child items from 'SC65VanillaWithSW.Master' to 'SC81VanillaForSW.Master'-->
    <parameter name="itemId">b80ae69f-4212-43e6-af97-2f86ddcddae1</parameter>
    <parameter name="overwrite">True</parameter>
    <parameter name="lightningMode">False</parameter>
  </operation>
  <operation name="CopyAll" source="SC65VanillaWithSW.Master" target="SC81VanillaForSW.Master">
    <!--Copy with overwrite '/sitecore/templates/User Defined', all missing parents and all child items from 'SC65VanillaWithSW.Master' to 'SC81VanillaForSW.Master'-->
    <parameter name="itemId">b29ee504-861c-492f-95a3-0d890b6fca09</parameter>
    <parameter name="overwrite">True</parameter>
    <parameter name="lightningMode">False</parameter>
  </operation>
  <operation name="CopyAll" source="SC65VanillaWithSW.Master" target="SC81VanillaForSW.Master">
    <!--Copy with overwrite '/sitecore/layout/Layouts/SW', all missing parents and all child items from 'SC65VanillaWithSW.Master' to 'SC81VanillaForSW.Master'-->
    <parameter name="itemId">2141e479-3f72-447c-9afa-3b4db1ea283d</parameter>
    <parameter name="overwrite">True</parameter>
    <parameter name="lightningMode">False</parameter>
  </operation>
</razl>

It has a two connections for the instances which will be used in transfer. It comes from the Razl configuration, where firstly I created that connections. Under that elements there is a list of operations with specified source instance, target instance, ID of the item and configuration of the operation type - in my case it will be CopyAll with overwriting the target instance.

As far as I knew at that time, there was no way to edit exported script with Razl, so I was editing it manually.

Preparing PowerShell run script

At last I wanted to have a PowerShell script that will run my transfer script with just one click. I have prepared a PSs that run razl.exe with specified scripts. For core database this is quite simple - set your directory where Razl script are located in:


For master database I decided to split Razl script into smaller parts, so the I was able to comment out some of them to run just specific ones:


Also these scripts log full log into specific files. So everything that happens while transfer is saved for analysis. Here is some example part of the log:

    1 13:00:31,579 INFO  CopyAll Started Id: 563a2ddb-ad89-4182-9706-eb1512abe0b1, Path: /sitecore/system/Field types/List Types/Google Maps Multilist, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core, Overwrite: True
   1 13:00:31,579 INFO  CopyAll Processing /sitecore/system/Field types/List Types/Google Maps Multilist
   1 13:00:31,580 INFO  CopyItem Started Id: 563a2ddb-ad89-4182-9706-eb1512abe0b1, Path: /sitecore/system/Field types/List Types/Google Maps Multilist, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core
   1 13:00:31,847 INFO  CopyItem Finish Id: 563a2ddb-ad89-4182-9706-eb1512abe0b1, Path: /sitecore/system/Field types/List Types/Google Maps Multilist, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core
   1 13:00:31,928 INFO  CopyAll processing children of /sitecore/system/Field types/List Types/Google Maps Multilist
   1 13:00:31,928 INFO  CopyAll Processing /sitecore/system/Field types/List Types/Google Maps Multilist/Menu
   1 13:00:31,929 INFO  CopyItem Started Id: 60daf681-8069-46a2-aa39-5490741f6cec, Path: /sitecore/system/Field types/List Types/Google Maps Multilist/Menu, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core
   1 13:00:32,196 INFO  CopyItem Finish Id: 60daf681-8069-46a2-aa39-5490741f6cec, Path: /sitecore/system/Field types/List Types/Google Maps Multilist/Menu, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core
   1 13:00:32,252 INFO  CopyAll processing children of /sitecore/system/Field types/List Types/Google Maps Multilist/Menu
   1 13:00:32,252 INFO  CopyAll Processing /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Show Map
   1 13:00:32,252 INFO  CopyItem Started Id: ce073686-11cb-4921-b4db-61c98bc1f54a, Path: /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Show Map, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core
   1 13:00:32,519 INFO  CopyItem Finish Id: ce073686-11cb-4921-b4db-61c98bc1f54a, Path: /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Show Map, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core
   1 13:00:32,576 INFO  CopyAll processing children of /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Show Map
   1 13:00:32,576 INFO  CopyAll Processing /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Select All
   1 13:00:32,577 INFO  CopyItem Started Id: bbe0cd71-aac7-47bc-971a-49265078d17c, Path: /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Select All, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core
   1 13:00:33,153 INFO  CopyItem Finish Id: bbe0cd71-aac7-47bc-971a-49265078d17c, Path: /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Select All, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core
   1 13:00:33,209 INFO  CopyAll processing children of /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Select All
   1 13:00:33,209 INFO  CopyAll Processing /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Deselect All
   1 13:00:33,209 INFO  CopyItem Started Id: b54acbc5-0fc0-4d6d-a863-0f8657e50504, Path: /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Deselect All, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core
   1 13:00:38,480 INFO  CopyItem Finish Id: b54acbc5-0fc0-4d6d-a863-0f8657e50504, Path: /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Deselect All, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core
   1 13:00:38,537 INFO  CopyAll processing children of /sitecore/system/Field types/List Types/Google Maps Multilist/Menu/Deselect All
   1 13:00:38,593 INFO  CopyAll Finish Id: 563a2ddb-ad89-4182-9706-eb1512abe0b1, Path: /sitecore/system/Field types/List Types/Google Maps Multilist, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core, Overwrite: True
   1 13:00:38,705 INFO  CopyAll Started Id: 5cee31bf-120d-4936-b9c6-930cbf63cb57, Path: /sitecore/system/Field types/Simple Types/Google Maps Single Point, From: SC65VanillaWithSW.Core, To: SC81VanillaForSW.Core, Overwrite: True

More info about Razl scripting is in official Razl documentation: https://hedgehogdevelopment.github.io/razl/script.html.

Tuesday 10 January 2017

Sitecore Module - Dynamic Sitemap XML

After a lot of work spent on creating project specific sitemap xml implementations I have prepared my own generic sitemap xml module. It is based on original marketplace sitemap module but adds some new great features.


It has two main assumptions:
  • Flexible configuration - to give end user as many as possible configuration options, because it is easier to edit Sitecore items than edit and deploy config files.
  • Extensibility - code functionality should be extensible and override-able. It should be easy to extend or override functionality, without decompiling and copy-pasting a lot of code.

Specifying your own logic

To use or not to use marketplace module - that is the question! Most times main reason to write your own sitemap implementation is thought if there will be some custom tricky functionalities needed. Something like some static html pages or other links that exist outside Sitecore.

 
You can specify your own logic, that can add your custom items to the sitemap.

You should create class that implements IItemsProcessor interface, put it in your assembly and attach your class to the site configuration item, in format MyType, MyAssembly.


In this approach, main functionality of module can be easily changed. More info here https://github.com/ReoKzK/Sitecore.SharedSource.DynamicSitemap/wiki/Specifying-your-own-logic

Separation from content

I also decided to definitely separate sitemap things from the actual content. So deciding whether the item goes to sitemap or nor or setting the change frequency or priority, is set on the sitemap configuration item in Sitecore. This approach will keep your items clean. More info here https://github.com/ReoKzK/Sitecore.SharedSource.DynamicSitemap/wiki/Creating-new-sitemap-configuration

That's all :)

Module is uploaded to official Sitecore Marketplace https://marketplace.sitecore.net/Modules/D/Dynamic_Sitemap_XML_Module.aspx

Whole documentation is available here https://github.com/ReoKzK/Sitecore.SharedSource.DynamicSitemap/wiki

Library is also available at nuget:
Install-Package Sitecore.SharedSource.DynamicSitemap
Hope that my module will be useful and will improve your websites development process.