Sitecore Forms – Custom Field Validator

Just like any other feature in Sitecore, Sitecore Form’s Field Validator can also be customized based on our need.

Any forms would require a client side validation and server side validation. In Client Side we can validate the field for any special characters and block user from entering them. However, in the server side we may need to validate them for few other conditions apart from the special characters.

Meaning, say we have a registration form and it has an UserId field. In any application the UserId field which is picked by the user must be unique. So in those forms, we do this validation of whether that UserID already exists in the DB or not  in the server side.

Sitecore doesn’t provide any OOTB components for such scenarios and of course there is no reason for Sitecore to provide one as well, as these are project specific requirements.

However we do have the option of creating a Custom Field Validator on our own to cater our requirements.

This post is about to how to create a custom Form Field Validator and associate the created Validator with a field, so that the Content Authors can opt for the required validators while creating the forms in the Form Editor window.

  • Create a new Validator element under /sitecore/system/Settings/Forms/Validations based on the template /sitecore/templates/System/Forms/Validation
  • The created element has 3 Settings fields
    1. Type – Namespace, Assembly
    2. Message – Client Side Validation Error Message. {0} will be replaced with the Field Name.
    3. Parameters – This is a key value pair, that can be configured from Sitecore end and it will be used during run time to perform client and server validations. These parameters will be fetched in the code and processed according to our need. In the below example, regularExpression used for validating the input both in client and server side.
  • Now to the code part,
    1. Create a Validator class that inherits from ValidationElement<RegularExpressionParameters> under Sitecore.ExperienceForms.Mvc DLL. Note that the RegularExpressionParameter mentioned here is not mandatory. ValidationElement<TParameter> is  the actual base type. Meaning instead of Reg.Exp Parameter you can use String as well.
  • Inside this class, we have to override 3 methods,
  • Initialize – Initializes the class attributes with the values from the corresponding sitecore item.
  • ClientValidationRules – We will the client side validation elements for the validator. In this example just a regex.
  • Validate – Actual Server Side validation takes place here. Inside this methods we can add our logic to validate with any 3rd party components. In case of the UserID part, we can have our API call to validate here and send a response accordingly.
  • The Initialize method will be invoked both during form load and form post once per field. ClientValidationRules execute during Form Load and Validate during Form post. (This is needless to say given the method name the functionality they perform yet thought I record this note here)
  • Once the class file is added, add the Namespace and assembly in the type field of the validator element.
  • Now, to associate this validator with the field type, go to the relevant field under /sitecore/system/Settings/Forms/Field Types. For Ex. Single-Line text under Basic, under Settings section, Allowed Validations multi list field, add the Field Validator which is created.
  • This will allow content authors to opt for the required validations for the field while adding the field to the form in the form editor window.

Reference,

Walkthrough: Creating custom validation (sitecore.com)

Sitecore 10 Content Serialization – Command Line Interface

With Sitecore 10 release, Sitecore has released two new modules for the sole purpose of serializing Sitecore Contents making it easy to port between Sitecore instances. (One dev to another dev or from local to dev/uat or higher environment)

Well.. SCS(Sitecore Content Serialization) is not a new concept all together. We already have tools like Unicorn/TDS in the market that solves the Serialization concerns. But, to have SCS as a module from Sitecore means a lot. They can provide additional support and this SCS module can be extended to provide additional feature with upcoming releases.

SCS comes with two options.

  1. Sitecore Command Line Interface
  2. Sitecore for Visual Studio

Sitecore CLI is free it can be accessed via PowerShell whereas Sitecore for Visual Studio is plugin/extension kind for Visual Studio and needs a separate license.

Note 
Sitecore for Visual Studio requires a separate license that you can purchase at the Team Development for 
Sitecore website.

This post is about Sitecore CLI installing, configuring and using them.

Sitecore CLI Requirements:

  1. Well most of the Sitecore system must already have PowerShell installed.
  2. In addition to PowerShell, Sitecore CLI needs .NET Core. (Sitecore CLI is used as a dotnet tool)
  3. You need to download and install Sitecore Management Services. The usual Sitecore->Control Panel->Administration->Install a package.
    • SMS contains some GraphQL configs/DLLs that is needed for the serialization purposes.

Once the Sitecore Management Service is installed, to install Sitecore CLI

  1. Open PowerShell in admin mode, cd to your Project Solution Root directory.
  2. Use the below command to install Sitecore CLI tool.
dotnet new tool-manifest dotnet tool install Sitecore.CLI --add-source https://sitecore.myget.org/F/sc-packages/api/v3/index.json

Initialize the setup using the below code

dotnet sitecore init

After initializing, let’s connect with our Sitecore instance using sitecore login command. It redirects us to sitecore login page and once given the credentials, we need to check the permission and allow them.

Once this is done, notice in your Project root folder, few new folders/ Sitecore.json file auto created. These are config files which has information like what are files to lookout for and what are their file paths, module configurations and user configurations etc. Please add to gitignore the user configuration/any other config file as necessary as it contains access token/refresh token – individual user login related info. By default, when we install/init Sitecore CLI it takes care of these things. You can add/remove as per your needs.

Most probably we would be having our Solution as per Helix Principles and based on Helix principles along with the code, we have our sitecore content items serialized under serialization folder  in Layer/Module Name/serialization.

We instruct Sitecore CLI to look for “ModuleName.module.json” for sitecore items path for serializing.

Reason we pick up .module.json is because in Sitecore.json config which is created under project root path is instructed to be found in .module.json files.

For this demo consider the below Website.module.json

Ignore the serialization folder, it will be automatically created when we pull the items from sitecore content tree for serialization.

We have added a namespace name SolutionName.Layer.ModuleName

Included the items that are included in the module and their sitecore content tree path. Ignore the Feature-template and Project-template it was just intended to denote any name can be specified for the configuration.

Notice here the order in which they are included. Maintaining this order is necessary as content items which is finally rendered needs the corresponding layouts/renderings and templates first. It might throw an error if the ordering is not followed.

Once, the above steps are completed, we can use dotnet sitecore ser pull to serialize the sitecore items from the content tree to the disk

You can see the items serialized to a YML file available under /serialization folder. Sitecore CLI creates a serialization folder in the same level as of website.module.json which has the serialized items in YML format for the corresponding module.json configurations.

These YML files contains information about the sitecore contents and can be maintained in any version control just like code files.

Once the items are serialized they’re all marked and only when there’s change made in those files, they’re identified by CLI for serialization.

Similarly, once the serialization is complete and it is available in source control, it can be ported to another developer’s local and the deserialization – yml file to sitecore item can be performed using dotnet sitecore ser push command.

References:

Sitecore Content Serialization

Sitecore – Experience Profile

I was always curious to know about how Amazon shows relevant products, how YouTube recommends new videos and Netflix/Prime next series/movies.

Well the below post is the Sitecore version of it. It’s about how we can achieve a similar personalized user experience in a Sitecore based site.

In this post, I am gonna discuss about a site’s User, Visitor and a Contact. What are they? How do they differ and How/Where/When to create/identify a contact, Contact tracking.

Visitor – A Visitor is some one who visits our website. They may be redirected to our site via a search engine or any online/offline promo/campaigns. They can be anyone who has access to our site. Bottom line is, to us they are anonymous. We don’t have any information about them. By information I mean their name, email or number etc.,

User – User is some one who has already registered to our site. They have a membership with our site. They have a login credentials, they can login to our site and avail services. We also have their name, email or number that can be used to identify them among our visitors/users.

Contact – Contact is an entity that holds information about visitor’s/user’s interaction with our site, like the pages they have visited, events/goals they have triggered. The time they have spent in each page, their total interaction duration and many more. Basically the marketing data that can be associated with a user/visitor.

Contacts can be of two types. Anonymous and Known Contacts.

In Sitecore, every time a visitor visits you  site, a analytics cookie (sc_analytics_global_cookie) is created and it is associated with the current visitor. This cookie has a contact id – GUID. Sitecore captures all the interaction data (mentioned above) of the visitor during the current visit and stores it in the DB.

(The Contact ID in the cookie value is associated with a identifier and a device profile ID and stored in DB)

If the same visitor visits our site with the same browser again. Sitecore identifies the visitor using the cookie and remembers the visitor’s previous interaction and also associates the interaction data captured during the current visit along with the data from the previous visit.

Now, if the visitor clear the cookie, the cookie value is lost. Even though the visitor has visited our site before due to the lock of cookie, he will identified as a new visitor and a new GUID will be associated with the visitor. Basically, we won’t be able to link his previous interaction data with his current visit.

Well, this is the case for all the public sites without any user membership.

But, for sites that has membership i.e., Login it can be different. Say once the user logs in, an identifier  – username or emailid or contact number can be used to identify the user and capture their interaction data. Even if they visit the site again, using this identifier we can associate their current collected interaction data with their previously collected data.

Sitecore handles the collection of interaction data using xConnect components. xConnect is a service layer in between the xDB and any client that wants to read, write or search contact and interaction data.

XConnect can be consumed via Sitecore Context and also from any other trusted client.

Anonymous Contacts have no registered identifiers. Known Contacts have registered identifiers.(username, emailid or number )

Now, moving on to Creating and Identifying a contact.

In all our membership sites, we have a sign up module, allowing user to create accounts in our site to login and avail services. We should create contacts that can be associated with the user along with an identifier say emailid or username. The Identifier is a unique attribute associated with a contact. No two contacts can have same identifier. In fact Sitecore throws exception if your try to create two contacts with same identifier.

Facet is an information about a contact. It’s like an attribute to a class. First Name, Last Name, Email-ID and phone number are some of the common examples of facet to a contact. In the example below Name, Job Title , Email Address, Phone Number and Contact Address facets are filled for the following contact.

Contact contact = new Contact(new ContactIdentifier(source, Identifier, IdentifierType));

Similarly, we have login module to authenticate our users. Once, the login authentication is done, we can identify the current user to a known contact using the unique identifier. So that the interaction data captured can be associated with previous data.

var identificationManager = Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetRequiredService();
Sitecore.Analytics.Tracking.Identification.IdentificationResult result = identificationManager.IdentifyAs(new Sitecore.Analytics.Tracking.Identification.KnownContactIdentifier(“Local”, “realmadrid”));
Sitecore.Analytics.Tracker.Current.StartTracking();

In the screenshots, for illustration, I have created a helper method to create contacts and simple controller rendering that identifies the current user to a known contact (previously created one). Basically this setup is for me to collect some marketing data that I can use for exploring other modules of Sitecore like Marketing Automation or EXM etc.

Now, connecting the intro in this post, Amazon, YouTube, Netflix or Prime. Remember in my previous post, I would have written about Profiling the contents, creating profile cards and pattern cards. The collected interaction data combined with content profiling, we can provide personalized customer experience.

For Eg. Based on visits, it’s profiled currently as some one who likes travelling to Cities and Cultural places.

For more details,

https://doc.sitecore.com/developers/91/sitecore-experience-platform/en/contacts.html

https://doc.sitecore.com/developers/91/sitecore-experience-platform/en/tracking-contacts.html

https://doc.sitecore.com/developers/91/sitecore-experience-platform/en/identifying-contacts.html

Sitecore – ‘P’ for Profiling

Profiling – the activity of collecting important and useful details about someone or something.

Back when I started working on Sitecore, I was awestruck by it’s OOTB profiling/personalization features. I came across a demo site, that profiled visitors and presented contents based on their interests. This was something super cool for me. And naturally raised my curiosity.

Finally after days made some time for a casual dive on the idea, thereby sharing my findings here.

In other words, this article is about Sitecore Profile, Profile Keys, Profile/Pattern Cards and Personalizing contents based on the profiling. (Yea Profiles, Profile Cards/Pattern Cards have been there for many years now but still it was kinda new to me)

For demonstration purpose, I am gonna make use of a travel destination site. This site serves as a online catalogue of different tour destinations, providing information about different countries and their tourism details.

As for as Personalization is concerned, We’re gonna have a default page banner on the home page, once the visitor starts browsing the site for destinations, Sitecore’s gonna profile him and gonna suggest him with relevant destinations based on his interests, (Which we would have predicted by profiling him) by showing him a related page banner content.

Before we proceed further, I would like to mention that, the Profiling/Personalization’s accuracy depends heavily upon the way they are configured. Sitecore provides several OOTB features to achieve best profiling/personalization experience that can match your content strategy.

First, I will explain about the terminologies that we will come across in this article,

Profile – Profiles are means to categorize different types of visitors/Contents to your site. For this travel site, the Profile will be Destination. (To create a profile, go to Marketing Control Panel module under Marketing Applications section in the Sitecore Launchpad. You can create one under /sitecore/system/Marketing Control Panel/Profiles – using insert options)

Notice, the type field. This is how sitecore determines the profile value. The other values include Sum, Average. For now we will go with Percentage.

Profile Keys – Profile Keys constitute a Profile. For my Destination Profile, the keys may include Historical, Safari, Adventure and Hiking, Cultural, Romantic and Urban. These are more like attributes that when assigned a numerical value will give the type of destination, a visitor is interested in.

We can create a Profile Key under the profile based on the Profile Key template using Insert Options. Here, Minimum/Maximum value can be any number. Based on these Min/Max and Default values, we will update the Profile/Pattern Card which in turn can be associated with a Content or Visitor.

Similarly, we can create Profile Keys for Culture, Historical, Romantic, Safari and Urban.

Profile Cards – Different profile cards can be created for a Profile. Profile Card holds a numerical value for each Profile Keys associated with the corresponding profile. We can then assign these Profile Cards to each of the site’s pages (content items) based on the content they describe. They can be created under Profile Cards folder (which is auto created when we create a profile) using it’s Insert Option.

In this Travel Destination Site, the  types of Profile Card may include, Adventure and Hiking Destination, Historical and Cultural Destination, Metro Destination, Romantic Destination and Wildlife and Safari Destination. Each profile cards, hold different values for their profile keys based on their destination type. Say, for Metro Destination profile card, Urban Profile Key will higher value for Urban Profile Key whereas other profile keys will have less values.

For Metro Destination Profile Card, we have given ‘3’ for Urban Profile Key where as default value ‘1’ for other profile keys.

For Adventure and Hiking Destination Profile Card, we have given ‘3’ for Adventure and Hiking Profile Key where as default value ‘1’ for other profile keys.

Pattern Cards – Pattern Cards are similar to profile in a way. They both have the same Profile Keys associated with the relevant Profile under which they are created. That’s the only similarity. Now the difference, Unlike Profile Cards, Pattern Cards represent the person who visits the site(visitor). To elaborate further, for our travel site, based on the profile keys we have created we can categorize the visitors to, City Slickers (Who likes to travel to Metro Cities like New York, Montreal), Wildlife Travelers (who likes to do Safari and like to visit destinations like Tanzania, Namibia), Romantic Goer (who likes to visit Romantic Getaways like Italy), Thrill Seeker (who likes to do Hiking and Adventurous trips and like to visit destinations like Austria, Norway) and finally Culture Vulture(who likes to visit Cultural and Historical destinations like India, Japan)

They can be created under Pattern Cards folder (which is auto created when we created a profile) using it’s Insert Option.

Just like Profile Cards, each Pattern Cards will have different values for each Profile Keys based on the type of the visitors they represent. Wildlife Traveler will have more value for Safari Profile key than other Profile keys. Likewise for other pattern cards.

For Thrill Seeker Pattern Card, we have given 5 for Adventure and Hiking Profile Key and default value – ‘1’ for other Profile Keys.

For City Slickers, Urban profile key is set to ‘5’ whereas other key are default.

Notice that the profile card and pattern card naming convention is different although they have same set of profile keys. This was made deliberately to denote that Profile Cards will be associated with contents and Pattern Cards will be associated with Visitors.

Now let’s associate the profile cards to Sitecore page items. Click on the icon present in the right top, above the Quick info title bar to edit the profile cards associated with the item.

Then Select Edit option for the Destination Profile.

Since, New York is a Metro Destination, select the Metro Destination profile card.

Similarly for India, I’ve chosen Historical and Cultural Destination card.

Updated the profile cards details for other countries/cities available.

Now the final act, adding a personalization rule for the Home Page Banner rendering based on the Profile/Pattern Card.

Okay, here the idea is when the user visits the site, browses through different Destination pages, say India, Japan, Austria, New York and Montreal. After visiting few pages, the user will be mapped to anyone of our Pattern Card under Destination Profile.

While visiting these pages, Sitecore triggers the Profile Card associated with these contents and updates the Pattern Card associated with the Visitor. A Visitor will be associated with only one Pattern Card at a time. So, when he visit’s a page say India, which is mapped to Historical and Destination Profile Card, his Destination Profile’s Culture and Historical Profile Key’s values will be incremented. Thus, the user will be linked to anyone of our Pattern Cards. And we can predict his interests.

Meaning, if he visits, pages like Tanzania, Namibia, we can assume that he’s interested in Safari and will be associated with Wildlife Traveler Pattern Card eventually. If he visits, pages like Italy, Venice, Paris we can assume that he’s interested in Romantic Getaways and will be associated with Romantic Goer Pattern Card.

Here, for the demo, say after he visits New York and Montreal , he will be mapped to a City Slicker Pattern Card. And now if he hasn’t Australia which is again a Metro Destination, we are personalizing the Home page banner to present content related to Australia.

P.S: If he has visited other pages say Tanzania, Namibia his Adventure and Hiking/Safari Profile Key will have high value at some instance during his visit and he will be mapped to Thrill Seeker or Wildlife Traveler Pattern Card. In that case, this rule wont be executed and default Page Banner will only be presented to the Visitor.

Home Page Banner Before Personalization
Customer visits New York page
Customer visits Montreal page
At Home Page, Personalization kicked in!

Finally, after the Visitor is mapped to City Slicker Pattern Card and if he hasn’t visited Australia page yet, home page is personalized with a page banner redirecting to Australia.

Although it doesn’t make much sense to personalize a home page banner, the same rule and concept can be applied to a different component say, a recommender list rendering which can be included in a Destination page’s Side bar or can be put to use for other wide requirement.

Note:

  1. Profiling will kick in only after a visitor has browsed at least 3 pages associated with Profile Card in your site. This is a default setting – Analytics.Pattern.MinimalProfileScoreContent present in Sitecore.Analytics.Tracking.config
  2. The idea is to not to rush in profiling a visitor. However, this value varies depending upon the site as it is associated with the number pages in your site and can be modified accordingly.

Sitecore – StripLanguage Processor

Recently, I faced an issue in one of the site of a Sitecore Multi-Site solution. A request was redirected multiple times and chrome was throwing request redirected too many times error.

The request was for a Not Found Page item and seems like that item was not found and it was again redirecting to Not Found Page Item. Except that item was present in the content tree and it was accessible via URL as well.

Upon deep analysis, identified that in the failure case, the language code used to access that item was different. Say for eg.,

www.mark3.com/en/product/NotFound  – success scenario

www.mark3.com/en-us/product/NotFound – failure scenario

Not Found item had only en version and no en-us version. So, if the request comes for /en-us/product/NotFound it wouldn’t exist in Sitecore and it was redirected to /product/NotFound.

Keeping this aside,

Now, Sitecore has a Sitecore.Pipelines.PreprocessRequest.StripLanguage processor that based on the Sitecore setting – Languages.AlwaysStripLanguage strips the langauge code, if it comes immediately after the host name.

Meaning,

www.mark3.com/en/product/NotFound will be resolved to www.mark3.com/product/NotFound With language version as ‘en’.

Now, coming back to the issue, thus, /product/NotFound was redirecting to /product/NotFound and hence, the circular redirection. To fix it, if the Languages.AlwaysStripLanguage property should be set to false, that would treat the component immediately after the host name as a sitecore content tree item and process accordingly.

So set that property to false and now tested the failure scenario and it was working fine redirected to /product/NotFound with out any issues.

But, when in a multisite solution, when one site needs the language code after domain name and at the same time, no language folder is to be created in the sitecore content tree, this would cause an issue if not handled properly.

www.mark1.com/en/Careers/Tech

www.mark1.com/es/Careers/Marketing

So, to fix this, thought of patching the Strip Language processor and enabling/disabling the Languages.AlwaysStripLanguage with a custom site property –  site wise.

Another road block, StripLanguage processor comes under PreprocessRequest Pipeline and Sitecore.Context.Site is setup in the HttpRequest pipeline – SiteResolver processor. Meaning we can’t access the site property in the Strip Language processor unless we write some logic to call SiteResolver methods from StripLanguage Processor.

These are making all things complex. So, to resolve this simply, we can use the virtual path attribute of Site Property.

In the site definition, for the www.mark1.com created two sites which differs by virtual path. Meaning /en as virtual path for one site and /es as virtual path for another site. With the languages set to en and es accordingly.

This can be applied for all the sites that has similar requirement in the multi site instance.

P.S: The Strip Language processor, gets the SitecoreContext.Language and SitecoreContext.Data.FilePath properties from arguments. But when I tried to replicate the same in my Custom Strip Language Processor, I got can’t be accessed error. Upon checking this, identified, SitecoreContext is of internal access specifier and again, we have to do a work around for this. Hence, the Site definition approach.

Sitecore PowerShell Extension

Sitecore PowerShell Extension (SPE) is the most powerful module that I have ever used. It can greatly reduce your efforts of maintaining the Sitecore Contents. And It can also be used to pull some useful reports.

Thanks to the creators- It’s an open source. There are many blogs about SPE and it has some very good documentation that can help you get started. I was aware of it’s existence long back. Since I had zero experience on PowerShell, I never really gave it a try.

Things got changed when I Installed Sitecore 9 via the PowerShell Scripts and thanks to some of the build scripts I came across that were written in PowerShell, I got quite familiar with it’s semantics. So right when I got myself into a situation where I thought, SPE might help me, I jumped straight into it.

I guess we could agree on how terrible, Authoring and Managing the Content could become. Esp. if it’s a multi lingual/multi site environment. SPE could turn hours of work to minutes.(Trust me I am not overselling it). Well, to me right when you setup your UAT/PRE-PROD environment, along with the installation of Sitecore in those environment, you should  setup SPE as well.

Setting Up – SPE Installation is simple and straight forward. Just like installing a package. You can refer the official documentation for Setup and Installation

Sharing here some of my PowerShell Scripts, (Hoping to add more as I get more hands-on). These have some simple Scripts like getting an item/child item/child item based on condition and item’s rendering etc as well. (Basics!!!)

  • Get Items with a Specific Rendering and update it’s data source (You can modify the same script to add a certain rendering/data source to all the items)

$rendering = Get-Item -Path “master:Rendering-Path”

$items = Get-ChildItem -Path “master:Parent Item Path” -Recurse | Where-Object { Get-Rendering -Item $_ -FinalLayout -Rendering $rendering }

$DatasourceId = “{DataSource Item ID}”

write-host $items.Count

foreach($item in $items) {

    $renderingInstance = Get-Rendering -Item $item -FinalLayout -Rendering $rendering

    if ($renderingInstance) {         

 if($renderingInstance.Datasource -ne $DatasourceId)

 {

   Write-Host $item.FullPath

              Write-Host $renderingInstance.DataSource

   Write-Host “Updating Rendering DataSource”

   $renderingInstance.Datasource = $DatasourceId

              Set-Rendering -Item $item -Instance $renderingInstance

   Write-Host “Updated DataSource ID”

   Write-Host $renderingInstance.Datasource

 }

         else

 {

   Write-Host “Correctly Mapped”

   Write-Host $item.FullPath

           Write-Host $renderingInstance.DataSource

 }

        }

    }

  • Change Child Item Template

$items = Get-ChildItem -Path “master:” -Recurse | Where-Object { $_.TemplateID -eq “{Template ID of the items you wish to change the Template}” }

$templateitemid = “Target Template ID”

$templateitem = Get-Item -Path “master:” -ID $templateitemid

foreach($item in $items)

{

if($item.TemplateID -eq “{Template ID of the items you wish to change the Template}”)  //Basically, you don’t need this, because already your list contains only the child items matching this template ID//

{

Set-ItemTemplate -Item $item -TemplateItem $templateitem

}

}

P.S: Set-Template has an optional parameter -FieldsToCopy which can be used to map the Fields of Source Item of Tempalte A to Modified Item of Tempalte B

  • Add-Rendering to an Item

$item = Get-Item -Path “master:/sitecore/content/…”

$rendering = Get-Item -Path “master:/sitecore/layout/Renderings/….” | New-Rendering

Add-Rendering -Item $item -Instance $rendering -PlaceHolder “PlaceHolder” -DataSource “Data Source” -FinalLayout

Adding a rendering to a group of items can be done in several ways – if they all belong to the same template we can add the rendering to the Standard Templates, or even if they are from different templates, we can leverage the individual template’s standard template and get the job done.

Imagine a situation where we can’t apply the above two solutions. May be they are from same template but the Data Source to be set for these rendering differs item wise or these renderings are to be added only to a particular sub children of items belonging to a certain template. In those scenarios, the Data Source can be fetched dynamically via PowerShell script based on the requirement and can be passed on to renderings to be added.

  • Add/Update Rendering Parameters for all child items

$items = Get-ChildItem -Path “master” -ID “ITEM ID” -Recurse

$renderingItemID = “”

foreach($item in $items)

{

Get-Rendering -Item $item -FinalLayout | Where-Object { $_.ItemID -eq $renderingItemID} |

Set-RenderingParameter – Parameter @{“KEY”=”VALUE”} |

Set-Rendering -Item $item -FinalLayout

Write-Host “Updated Items:” $item.Paths.FullPath

}

If it’s an existing parameter, we can specify the Key and new value. It will overwrite the existing value. If it’s a new Parameter, it will add the parameter to existing rendering parameter list.

Note:

  1. It’s wise to take  a back up of the Content Items, before working on modifying items on a large scale like a package or from a DB end. So that, you can always have an option of reverting back to previous version.

Sitecore – 404 for Media Items – Custom Media Request Handler

After I started exploring Sitecore HttpRequestProcessor pipeline, I came to know how powerful it is. Right from handling 404 requests to configuring redirection from Sitecore Application level, everything can be handled by patching that pipeline.(I am referring stuffs other than it’s default purpose)

Esp. In a multi-site environment where each site has a different business requirement for handling 404 or redirection, customizing this pipeline is the wide spread industry practice.

Initially I thought the same custom pipeline could be used for serving media 404 items and handling media redirects. But I was wrong. When I browsed further, I came across two solution,

  1. Patch the notfounditem url in the sitecore.config to the 404 page url.

This works like a charm if you want all the websites in the Sitecore instance to be redirected to a same 404 page.

But in most of the cases, we need to redirect them to different 404 pages based on the site.

   2.  Just like the custom httprequestprocessor, we need some thing that checks if the media item is present in the sitecore or not and then redirect to site specific 404 pages.

Before going into the solution, let’s see why the custom pipeline is not working for the media items.

Sitecore handles media requests separately. If it’s a media request, before the request even hits, the sitecore HttpRequestProcessor, it is passed to the Sitecore Media Request Handler. Which processes the media request and provides a response. Meaning, if the request is for a Sitecore Media item, the request wont even be passed through the custom pipeline.

Say, your media request is, http://cms.mark3.com/-/media/mark3/Ronaldo.jpg

Sitecore converts the ~ or – to sitecore and media to media library and then removes the extensions if any

So that your request becomes http://cms.mark3.com/sitecore/media library/mark3/Ronaldo

Sitecore then finds the Media item via the path (/sitecore/media library/mark3/Ronaldo) and serves the media (images/pdfs/docs or etc)

So, now to the solution. We need to create a custom media request handler and handle the site specific 404 media request logic there. Even for a media request redirection, we need to handle via the same.

In this case, we have to create a class that extends Sitecore MediaRequestHandler and handle our business logic there.

Once the class is created, we need to make update the MediaRequestHandler setting in web.config. Since this change needs to be done in web.config, it can’t be patched like other sitecore-configuration.

Update the sitecore_media.ashx type from default one to the created class/namespace.

Similarly in the same class we can add logic to handle redirection for Sitecore Media Items as well.

Setting up Sitecore 9.3 PaaS

Back in 2018, when Sitecore introduced it’s PaaS version, I was really excited but I didn’t get a chance of exploring  the Azure, PaaS and Setting up Sitecore – PaaS processes. I have always wanted to experiment with Sitecore PaaS version and I didn’t know how or where to start…Until Recently.

As you would have already known, Sitecore is not an open source CMS and it’s not easy to get hands on unless you are working on a Sitecore Project at work. To setup and get more hands on you would need a license. I don’t have to remind you about the license pricing.

Sitecore provided an option for developers to overcome this problem by introducing trial license – valid up to 60 days. Again for the setup file, either you have to have access rights for your organization’s setup files or you can get certified and gain access to dev.sitecore.com to download  sitecore products and get to know them.

One might wonder, what this all has to do with Setting up Sitecore 9.3 on PaaS? Until few days ago, I thought getting access to Microsoft’s Azure – Cloud Eco System and  Sitecore Experience Cloud (PaaS Version) is not within the reach of Individual Developers.

But I guess, there is always a way! In this post, I will share my experience of setting up Sitecore Experience Cloud  – Sitecore PaaS  in Azure using Azure Free Trial Account.

Microsoft provides free Azure account. Once you enable the Free Trail subscription, you will be credited with Rs.13,300 for use so that you can access Azure tools for free until the trial period is over. Apart from this, Azure also provides certain services free for lifetime. Check this link to know more about the Free stuffs.

It’s going to be pretty much straight forward and easy, we are going to create a separate resource group to manage every resources that fall under the our Sitecore Application. We are then gonna use Sitecore Experience Cloud App Template available in Azure Marketplace. Provide the necessary configurations and select the created resource group, other options and deploy them.

  •  Once you login to Azure Portal, click on Resource Group and select create.
  •  Give the Resource Group an appropriate name and Select the Region on which you need the Resources. I prefer East US. I had some failure experience while setting up the same in Asian Region.
  •  Fill in the Tag details and click Create. Once every details you’ve provided is Validated, click on Create.

Your Resource Group will now be created. We will use this resource group to Setup Sitecore.

  •  Go to Azure Home and Select Create a resource.
  • Go to Web Category and Select Sitecore Experience Cloud
  • Make use of the Azure Free Subscription or your Organization’s Subscription and Select the Resource Group which we created in the first place.
  • Now, let’s configure Sitecore Settings. Start by selecting the Sitecore Version. Depending upon your agreement with Sitecore select the appropriate Version.
  • Sitecore provides 3 topologies. Refer the link to know more, the one that suits your requirement.
  • Then select your required configuration. Along Sitecore XP or XM, Sitecore also provides options for selecting and installing their other products like SXA,JSS etc. Select them based on your requirement and supporting license. Then click Next.
  • Fill in the required details like Setting up Sitecore Password, SQL Credentials etc and click Next.
  • Now select the Region and click Next.
  • Now you will be redirected to Summary section that provides details of your selection. If everything seems fine click OK.
  • Go to the Legal Terms section and once you’ve read them click on Create.
  • Once everything’s done, click OK.
  • You will get a notification that Deployment has been initialized and now Deployment is IN progress. If anything fails out, please check the error log and repeat the activity from Create a Resource step.
  • It took more than 25 mins for the deployment. Once the deployment is done, you will get the notification.

Resource Group – Once Deployed!

You can now access the site using it’s host name….. and Voila!

The Activities mentioned in this post are intended only for the Developers to understand the process of setting up Sitecore PaaS. It is intended to share the learning experience and it is not going to be used commercially at any cost.

The Apps that were created are deleted already.

Sitecore – Social Media Integration – 2 : Tweet a Sitecore Page via Content Editor

This is the second part of the Sitecore – Social Media Integration Series. In this post we will look on how we can tweet a Sitecore page to Twitter from Content Editor.

It is very much similar to the previous post, where we published a Sitecore Page as a Facebook Post. This is just a follow up post, we would be developing components similar to the previous post, Setting up developer account, creating an app, getting the necessary permissions/keys/tokens, creating sitecore custom commands everything.

The only difference I felt while developing this component is Facebook uses OAuth2 were as Twitter API still uses OAuth1.

We are just laying the foundation for the Analytics SPEAK component which we would be creating later. We should get the analytics details of how a Sitecore Item is performing in twitter. For that the first step is to enable the Digital Marketing team to tweet a sitecore page via Content Editor. That’s what we will work on in this post.

It’s a three step process.

  1. We need to setup a Twitter App – using a Twitter Developer Account. This should be created with the related Twitter Handle to which we wish to tweet our page.
  2. Once the app is setup, we will get the necessary Keys/Tokens to access the twitter API, to post our Sitecore Page.
  3. We will work on creating our custom command in Default Context Menu that tweets the Page item.

Setting Up Twitter Developer Account and Keys/Tokens/Permission:

  • The App is needed to get the Access Token/API Key and it’s secret key. These values will be used for authorization while accessing the Twitter API.

  • Another important point to note here is, we have setup the permission of this app clearly.

Creating Sitecore Items and the logic:

  • I wouldn’t be walking through on the steps to create a custom command. For more details on this as already mentioned above refer this post.
  • Here, I have made use of SEO Fields of a Page item and added them as Tweet captions. Of course we can create a separate Social Media Section and related field names Twitter Caption and make use of it.
  • After adding the necessary menu items in Core DB, the corresponding class and creating the corresponding config patches,

In upcoming posts, we will work on setting up the analytics dashboard using Facebook Graph API or Twitter Analytics API that provides Analytics data of how this Sitecore page performs different social media platform.

Publish Sitecore Page as a Facebook Post aka Sitecore – Social Media Integration – Part 1

I am planning to write a series of posts on Managing Social Media Contents from Sitecore/Sitecore – Social Media Integration and this is the first of the series.

Social Media plays an integral part of Digital Marketing. Contents posted on a Facebook page is created from different sources. Although these contents have different origins, they are shared across Facebook, Twitter or any other social media.

These posts most probably contains links to our Website pages about our products/services. When I say different origins I meant that it also includes the CMSs where these pages are created in the first place.

Now in terms of CMS, once a particular page is created by the digital marketers, these links are shared across different pages/ twitter handles. Usually each organization would have their own Facebook Pages or Twitter Handles etc as a Social Media front. The admin/Editor of these pages share these links in those mediums by logging in to these Accounts.

Analytics details of these posts/tweets like interactions and how these posts are performing is important. The performance of these posts are decided my multiple factors and one of the undeniable parameter is the Content of this post – in simple terms, the post’s captions/Images. (Which is again a Content to us)

“Although we have Facebook Analytics, Twitter analytics to provide us that info, I personally felt that it creates a tiny separation between a Page and a Facebook Post even if the post is about the same page and I feel that it should be considered as a single entity.

When thinking about this deeper, what better place to manage those social media contents (Posts/Tweets) than it’s origin – CMS (which Sitecore in our case.)

Although I wanted to share a wide, more complete solution, I’m afraid whether I would be able to make time for doing it in near future hence this first part.

When I say wide, we can use Graph/Insights API and Twitter  Analytics API and create a Sitecore SPEAK application probably with graphs and tables as stats to show how each post associated with a Sitecore page is performing in different Social Media.

But as I said for now, I was able to make the first step alone. Hoping to work on this more and share the complete solution.

All the above paragraphs were meant to give you the answer for why this post.

Now coming back to the title, In this post, I am sharing my experience on creating a custom sitecore command that allows you to post a Sitecore page as Facebook Post from Sitecore Content Editor.

Of course this would require some stuffs like a Facebook Page, it’s admin credentials, Authorization token.

We’ll be using Facebook’s Graph API for posting to your Facebook Page.

Once, the APIs, Tokens are setup, we would be using a similar logic like  Create Custom Compress Command   and create a Custom Command named Publish to Facebook.

Getting to know about Graph API:

  • Login to https://developers.facebook.com and create an App. We will be making use of this app to post to Facebook via Sitecore.
  • Facebook has a decent documentation on it’s Graph API that is more than enough for us to get started.
  • You can access the documentation here
  • Once the App is created make note of it’s ID (APP ID)  and Secret Key (APP Secret)
  • Add Login product, setup page access token for the app for managing/publishing contents to the page.
  • For the time being I made use of Permanent Access Token, but for higher environment, this is not recommended and it is best practice to make use of Facebook’s OAuth 2.0 authentication. https://graph.facebook.com/{page-id}/feed?message=Hello_Fans!&access_token={page-access-token}
  • This is the API we will be using for posting the page content to Facebook.
  • For getting the access token, please refer.

Publish to Facebook Command

  • I wouldn’t be walking through on the steps to create a custom command. For more details on this as already mentioned above refer this post.
  • Here, I have made use of SEO Fields of a Page item and added them as Post captions. Of course we can create a separate field names Facebook Caption and make use of it.
  • After adding the necessary menu items in Core DB, the corresponding class and creating the corresponding config patches,
@Social Media 
Susi ng 
us ane 
using 
u51 ng 
Mark3.FeaturesSocialMedia.Publish.PostToFacebook 
Sitecore. Data. Items; 
Sitecore. Di agnost ics ; 
Sit ecore. Shell. F rm•ork. Cc—ands ; 
Sy stem; 
System. Collections. Generic ; 
System. Ling; 
System. Text; 
System _ Threading. Tasks; 
mark3. Features. . Repository; 
mark3 Jfoundati6iiL Si tecoreExtensicm. 
12 
Enamespace 
O refe 
public class PostToFacebook : CCNmand 
public override void Execute(ConnandContext context) 
Assert. (context. " context" 
Item item = context.ltems[øl; 
IPubIiShTOFacebcnkRePOSitor•y = publishTOFacebOOkRePOSitory(); 
string E?sponse — _pubIishTOFacebookRepository.PubIishFacebOOkPost(item); 
/ /WeryState 
public override Ct—andState QueryState(CornandContext context) 
Sf (context. Items. Length — 
Item currentlt& — context. 
if (currentltem.VisuaIization. Layout I—null) 
return base. Werystate(context); 
else 
return CormandState. Disabled; 
return base. ;
Social Media 
using 
using 
u51ng 
using 
using 
using 
Mark3.FeaturesSociaI Media.Repository.PublishTOFaceb00kRepc 
Mark3. Features . .l%dels; 
Newton S Oft. ; 
Si tecore. Data. ; 
System; 
System. 10 ; 
System. Net ; 
. Foundation. Sitecor•eExtensIon. ; 
Enamespace mark3. Features Repository 
class PublishToFacebookRepository : 
public string PublishPost(string 
string Respmse — string. E.ty; 
FacebookResponse response — new FacebookResponse(); 
string Access Token — "Permanent Access Token", 
string urI - 
"htrps: / 'eraph_ token-{1)"; 
string endpoint string. ; 
request 
request.Method — "POST"; 
request.ContentType — char-utf-8"; 
webRe%Xjnse = 
using (Stream stre— = 
if (stream null) 
using (StreamReader reader new 
string result; 
result - reader. ReadToEnd(); 
if 
response = JsonConvert . 
Respnse = id;
etch (kbExc%'tim webex) 
throw æbex; 
catch (Exception ex) 
throw ex; 
return Resmse; 
public String 
return it&. . Value; 
public string item) 
— FacebOOkPost() ; 
= SitecoreHelper 
p ageURL 
fbpost . PostCaption - 
string response — PublishPost(fbpost *ssage); 
•turn respnses
Guardian 
Home 
404 
El 500 
Around the World 
•O Business 
India Today 
Logistics 
Technology 
Sports 
Champions League permutations Who is thr 
Is Liverpool vs Man City the Premier League 
Shami Ashwin leave Bangladesh in tatters 
Article Page 
Shared Content 
MySite 
Insert 
Search 
Publish To Facebook 
Duplicate 
Delete 
Rename 
Copying 
Sorting 
Edit 
Experience Editor 
Publish Item 
Console 
Is Liverpool vs Man City the Premier League title decider 
components has been added to this page. 
you want to create a test? 
Create a test 
item is controlled by Unicorn 
nges to this item will be written to disk so they can be shared with others. 
figuration: Mark3DefauIt 
2dicate Component: Content 
Ysical path:D: Liverpoo 
{75106703-FCCF-4C21 -ACBI B7FC91 OED) 
Is Liverpool vs Man City the Premier League title decider
Guardian 
Home 
404 
.5 500 
Around the World 
•s' Business 
India Today 
Logistics 
Technology 
Sports 
Champions League permutations Who is through and who c 
Is Liverpool vs Man City the Premier League title decider 
Shami Ashwin leave Bangladesh in tatters 
Article Page 
Shared Content 
Meta Data Section 
Browser Title: 
Is Liverpool vs Man City the premier League title decider? 
Description: 
The two best teams in England clash in a colossal affair at Anfield this afternoon. Will the result decide where the Premier League title resides come May? 
Keywords: 
Football, News, Premier, League, Fixtures, Results 
Author. 
Guardian
posts 
i 'ubl•shed by Post to Page 2 mins 
The two best teams in England clash in a colossal affair at Anneld this 
afternoon. Will the result decide where the premier League title resides 
come May? 
https://cms.mark3.com/Sports/ls-Liverpool-vs-Man-City-the-Premier- 
League-title-decider 
Like 
Comment 
Boost Post 
Share

Similar to this we can create a Publish to Twitter command and make use of Twitter API to post it on corresponding twitter handle.

Design a site like this with WordPress.com
Get started