SXA: Dynamic Browser Title

Hi Folks,

I would like to share my learning and findings with you. Recently one of my project required to implementation SEO changes like dynamic browser title which should display value of page field into browser title of the page.

The project was setup by another developer, so never bother to look for an implementation.

After digging the component for the implementation, I discovered that Source of Browser title is actually a “Variant”…! 🙂

By default it refers the Title field of Browser Variant under Settings.

However, in our case we implemented another field called Product Title of type “Template”, because we want “Product Title” field to apply the only specific template. Template field allows us to refer content item’s field value as show in below screen.

Browser Title 1

We also add another rule to default title field to exclude the product template, thus only one title gets applied.

I hope you like it and find useful in your project.

SXA: Personalized Rendering Variants

Idea…!

I see the rendering variant as a separate component compare to traditional Sitecore renderings. Currently, Sitecore supports personalization on Renderings directly but not Rendering Variants. You can still achieve the personalization within the rendering variant by applying rule which is not user-friendly, but not between the variants.

Solution

This solution will allow a content author to personalize the rendering with the available variants through the personalization dialogue screen.

If a variant personalization has been setup by the content author, then whenever personalization rule matches it will apply the rendering variant setting to the given component at runtime.

Some use cases

  • Display partial view if a user is not logged in, once a user logged in successful show comprehensive view of the content.
  • Present content with a different look and feel when user SSO (Single Sign On) in to your website based on the client.
  • Display different view when a user visits from the different geographical location.
  • Any situation where you want to switch between the rendering variants based on some condition.

Installation

  • Install the package.
  • In case of different .Net version, manually compile the code according to you .Net version and deploy the dlls into the bin folder.
  • In case of different Sitecore version, you many have to change the processor.

Usage

Assuming you have followed the installation process.

  1. Select any SXA component which supports the rendering variant(Presentation->Details->Layout Details)
  2. Click Personalize button
  3. You will find the Variant Drop-down listing all variants for the respective components.
  4. Add personalization rule
  5. Select the rendering variant for the rendering.

Implementation

This solution has implemented below items:

  1. Overriding the default personalize box with the custom personalize dialog box, which shows the variant drop-down list.undefined
  2. New action to apply rendering variant parameter to the given rendering.undefined
  3. Few processors to pass the applied personalized variant parameter between the processors. undefined

Existing Issue

Experience Editor: A user cannot see the variant applied when they change the personalization from the drop-down list during the edit mode.

Repository

Code

Thanks for reading and liking. Feel free to extend the module or contact me in case of an issue at it.mrunal@gmail.com

Note: I have not thoroughly tested this module.

Sitecore TDS to Unicorn

Migration: TDS to Unicorn in Sitecore

Sitecore TDS to Unicorn

Hi Friends, recently I received an inherited project of the Sitecore which was using TDS (Team development System). I like that product however due to cost saving and developer preference we had to convert that all TDS project into Unicorn based config.

There were approx 60 projects and we had two approaches:

  1. Manual creation of unicorn config file which contains the predicates
  2. Script to convert and create unicorn config file.

We choose the option 2 started. I started analyzing the TDS Project’s file and its XML structure. The good thing about the project was they were name based on helix pattern.

It had many situations like:

  1. Include Tree
  2. Include Item without child.
  3. Include Item with the selected child.
  4. Exclude the item
  5. And many more…..

I ended up with the below script which generates the single Unicorn config file containing all predicates following helix pattern. I also created the base config file which you can use in you project to remove the base predicates from the generated file.

Git Repository : https://github.com/mrunalbrahmbhatt/Utilities

I hope this utility will save your time and effort. Feel free to change the script according to you needs.

Happy Sharing…

Export Sitecore Item as Package

Hi Sitecore Enthusiast,

Today I just made another small module for Sitecore content editor from where user can export sitecore item and its children as package directly without going to Package Designer.

Off course this is not package designer replacement, but it is developed by keeping in mind that mostly content editor or developers needs to move small content from one environment to another very frequently e.g. dev to staging OR staging to live.

Export sitecore item as package

Export Sitecore Item as Package

Installation Steps:

1. Download Sitecore module from marketplace or Github.

2. Install using sitecore install package wizard.

3. Restart client.

4. Enjoy module.

 

Thanks for reading and using module.

-Mrunal

 

Sitecore + SOLR

First experience with Sitecore 8 using SOLR ?

Hi Sitecore Enthusiast,

Today I want to share my first experience with Sitecore 8 using SOLR. I’m fan of Lucene and have implemented complex search architecture so far. However I wanted to play with SOLR as I heard about its benefits like e.g. if loads of content then SOLR is better , if you access index over HTTPS then SOLR and bla bla bla but not clearly documented anywhere.

Recently Sitecore posted very useful articles which will helps you in clear your queries and helps you to decide weather you should use Lucene or SOLR base on your requirement.

When and Why ?

  1. Using Solr or Lucene
  2. The role of Solr and search in the xDB

After reading above articles I got clear picture of both tools and its capabilities, then I read many blogs on implementing SOLR locally and found almost everyone has different experience and challanges of installation and implementation as SOLR and Sitecore 7.x and 8.X has changed their config and API as part of evolution and improvement.


How to ?

I followed below blogs to setup SOLR(5.2.1) locally with my existing Sitecore 8 (update 3) successfully.

Setup

Good for understanding as they target 7.X and older SOLR version.

https://sdn.sitecore.net/upload/sitecore7/70/sitecore_search_scaling%20guide_sc7-a4.pdf
http://www.dansolovay.com/2013/05/setting-up-solr-with-sitecore-7.html

Below one I used and succeed.

https://sitecore-community.github.io/docs/search/solr/Configuring-Solr-for-use-with-Sitecore-8/

SwitchOnRebuildSolrSearchIndex

I follow below link to implement SwitchOnRebuildSolrSearchIndex so that my environment will not get downtime while index rebuilding.

https://doc.sitecore.net/sitecore%20experience%20platform/search%20and%20indexing/switch%20solr%20indexes

Issues

I face below errors while implementing SwitchOnRebuildSolrSearchIndex .

Error:

Could not resolve type name: Sitecore.ContentSearch.SolrProvider.Swi
tchOnRebuildSolrSearchIndex, Sitecore.ContentSearch.SolrSearchProvid
er (method: Sitecore.Configuration.Factory.CreateType(XmlNode config
Node, String[] parameters, Boolean assert)).

Solution:

Replace below line.

<index id="sitecore_analytics_index"
type="Sitecore.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex, Sitecore.ContentSearch.SolrSearchProvider">

With

<index id="sitecore_analytics_index"
type="Sitecore.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex, Sitecore.ContentSearch.SolrProvider">

Error:

Could not create instance of type: Sitecore.ContentSearch.SolrProvid
er.SwitchOnRebuildSolrSearchIndex.No matching constructor was found.

Solution:

Comment out below line, as class SwitchOnRebuildSolrSearchIndex only take 4 parameters.

<!--<param desc="group">experience</param>-->

Thanks for reading, I hope post has help you to understand and setup your environment.

My experience was good as many people has posted their hard work. I keep sharing my update on SOLR and Sitecore.

-Mrunal

Minimum On-Premise Sitecore 8 Setup

Hi Sitecore Enthusiast,

Sitecore 8 is getting popular day by day due to its new power and capabilities, also customers are showing willingness to create/migrate their website on this powerful platform.

With this new solution, it also brings different infrastructure requirement which really makes it powerful. Being a Sitecore lover and Solution Architect I keep reading lots of blogs and articles to brush up my skills and knowledge. I was amazed by knowing Sitecore 8 scalability options available like On-Premise, Hybrid and xDB Cloud.

One day my Project Manager Sam, asked me to propose infrastructure requirement for our new client and our conversation begins:

Sam: Hey Mrunal we have new client and have to propose infrastructure requirement.
Me: That’s great… ! Which version they want to implement?
Sam: Sitecore 8…..!
Me: Hurry we have first client on 8 🙂 No worries I will give you by EOD. (But in my mind I was not confident about it as we never implemented locally or on production practically, it was all theoretical til now)

While gathering information from xDB configuration document, I figured out for best result and scalability point of view you need roughly below setup:

#5 – Sitecore Instances

  1. Content Delivery Server
  2. Content Management Server
  3. Processing Server(Optional)
  4. Aggregation Server(Optional)
  5. Reporting Server(Optional)

#3 – SQL Server Instances

  1. SQL Server (Core, Master)
  2. SQL Server (Core, Web)
  3. SQL Server (Reporting)

#1 – MongoDB server instances

  1. MongoDB Session Server (Optional) can be SQL instance or In proc(not recommended for production).

When replication implemented, also below Servers not required if you select xDB option i.e. hosting this database in sitecore xDB environment

#3 – MongoDB server instances,when replication set implemented

  1. MongoDB Server (Primary)
  2. MongoDB Server (Secondary – Optional)
  3. Windows Server (Arbiter – Optional)

Above servers not required if you select xDB option i.e. hosting this database in sitecore xDB environment

Hardware Requirements

Sitecore 8 hardware requirements

Hardware requirements

Software Requirement:

For each xDB server instance that you install you need the following minimum software prerequisites:

  • Microsoft .NET Framework 4.5.
  • Windows Server 2012 R2 – recommended for most Sitecore instances, especially processing/aggregation servers.
  • MongoDB 2.6.1 or later for the collection database, session storage and tracking databases. Install MongoDB on Microsoft Windows Server as a Windows service.
  • Microsoft SQL Server 2008 R2 SP1 or higher for the reporting database.

Ref: https://sdn.sitecore.net/upload/sitecore7/75/xdb_configuration_guide_sc75-a4.pdf


According to John West:

For a Mongo server in the content delivery environment, Sitecore would generally recommend at least:

  • Quad-core processor(s)
  • Minimum 16GB RAM
  • 500GB of storage spread over at least two solid-state drives
  • Only use SSDs
  • As much RAM as the environment can use for maximally effective indexing
  • If the active working set reaches 60% of RAM, add shards and/or RAM
  • Never use remote file shares
  • Use 64-bit
  • Avoid NUMA disk allocation strategies
  • If you use Mongo for session, use a separate Mongo instance than that used for xDB

Ref : http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2014/11/sitecore-requirements-and-recommendations-for-mongo-in-content-delivery.aspx


The above setup/requirement totally makes sense as its purpose is to scale(horizontally and vertically) and distribute processing power between different servers to achieve the best result for enterprise application.

Me: Hey Sam, there are multiple ways to implement and host Sitecore 8, who will take decision which approach we are using like on-premises, hybrid or xDB one?
Sam: It’s totally depends on client.
Me: Can I have their license details please?
Sam: They have 3 Sitecore licences, 1 for Staging/UAT, 1 for CM and 1 for CD.
Me: What about xDB option?
Sam: I believe it will be on-premises.
Me: What about MongoDB servers and replication set?
Sam: Try to put best minimum On-premise Sitecore 8 setup with recommendations.
Me: Great… this information will help me to design infrastructure diagram.

 

Minimum On-Premise Sitecore 8 Production Setup

Minimum On-Premise Sitecore 8 Production Setup – Developer Version

 

Minimum On-Premise Sitecore 8 Setup Simple

Minimum On-Premise Sitecore 8 Production Setup – End User Version

I believe above brain storming helps you to design your solution. Keep an eye on this space where I’m going to publish how to implement above setup practically 🙂 In two versions, one for developer and one for production.

Kindly post your suggestion or idea to make this better.

Thanks for reading.
– Mrunal

Parameterized Sitecore Scheduled Task Agent

Hi Sitecore Enthusiast,

Recently one of our project require schedule agent to generate order status report for past 1,3,5,7 days (can add more in feature).As part our solution design we (I and Sam, another developer) start discussing solution so that we both remain on same page.

Sam: We need to create four schedule agents in config file with parameter Day: 1,3,5,7 and so on.

I: But they might have more agents in future with more number of days or they might want to disable some.

Sam: We will disable them from config file

I: Ya, but it will restart IIS (which I always try to avoid if solution can be achieve other way)

Sam: Also this agent should run between given time

I: What if they ask us to change time period which is quite often

Sam: But config is only way where you can specify parameters and they get mapped to property automatically or we need to extend schedule task template by adding custom properties  and can be read out from code. However it may possible other Schedule task don’t want these fields (functionality specific)?

I: Let’s add single parameter field in task template and bind parameter to properties dynamically.

Sam: That would be cool! How?

I: Here is code and solution which we will use now on words for such requirement.

Sam: Wait wait but what about schedule job must run in given time frame and must execute once per day only ?

I: Brain has already provide solution on his blog which is really good solution and fulfills our requirement, just find code below which will include all requirement and you just have to write business logic.

Sitecore Schedule Task

using Sitecore;
using Sitecore.ContentSearch.Linq.Utilities;
using Sitecore.Diagnostics;
using Sitecore.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Client.Core.Agents
{
	public class ReportAgent
	{
		public ReportAgent() { }

		#region Common Property

		public string StartTime { get; set; }
		public string EndTime { get; set; }

		#endregion

		#region Task Specific Property
		public string Days { get; set; }

		#endregion

		private DateTime startDateTime;
		private DateTime endDateTime;

		public void Run(Sitecore.Data.Items.Item[] items, Sitecore.Tasks.CommandItem command, Sitecore.Tasks.ScheduleItem schedule)
		{
			try
			{

				if (schedule != null)
				{
					string parameters = schedule["parameters"];
					if (!String.IsNullOrEmpty(parameters))
					{
						Sitecore.Reflection.ReflectionUtil.SetProperties(this, parameters, false);
					}
				}

				startDateTime = DateTime.Now;
				endDateTime = DateTime.Now;

				if (!string.IsNullOrEmpty(StartTime) && !string.IsNullOrEmpty(EndTime))
				{
					DateTime.TryParse(StartTime, out startDateTime);
					DateTime.TryParse(EndTime, out endDateTime);

					if (!IsDue(schedule))
						return;
				}
				Execute();
			}
			catch (Exception ex)
			{
				Log.Error("ReportAgent: Error occurred", ex, this);
			}
		}

		private bool IsDue(ScheduleItem scheduleItem)
		{
			return (CheckTime(DateTime.Now, startDateTime, endDateTime) && !CheckTime(scheduleItem.LastRun, startDateTime, endDateTime));
		}

		private bool CheckTime(DateTime time, DateTime after, DateTime before)
		{
			return ((time >= after) && (time <= before));
		}

		public void Execute()
		{
			try
			{
				//Business logic.
			}
			catch (Exception ex)
			{
				Log.Error("ReportAgent: Error occurred", ex, this);
			}
		}
	}
}

Summary :

I believe both approaches has pros and cons, but if we get more flexibility by doing small change then I always prefer to do trade off.

From Sitecore:

+ Very flexible easy to manage like configure, enable/disable

+ Can specify day(s) of week in frequency

+ No IIS restart on change, just save and publish

– Parameter not supported (by default, but can be extended)

From Config:

+ Support parameter

+ Does not depend on Sitecore task agent to get executed

– Requires IIS restarts to change.

– Not able specify day(s) of week in frequency

 

I hope you like our conversation and might help you understand real essence of solution. If you have any feedback I would like to hear.

-Mrunal

 

How do I hide the “publish subitems” option in the publish dialog.

Hi Friends,

Recently in Sitecore Forum, Joseph asked “How do I hide the “publish subitems” in the publish dialog.” I already knew solution steps but just google to find any ready made post available if any then post in reply.

I found few but not to the point so I replied with steps exactly Joseph required and he was able to achieve his task and found him encouraged. Thus thought lets put in public so other developers have benefit too.

Steps:

1. Copy Publish.xml file from “sitecore\shell\Applications\Dialogs\Publish” folder to “sitecore\shell\override” folder, so that you don’t messed up original file in case if you want to revert back your changes, just delete newly copied file.

2. Find xml code for control in Publish.xml file, some thing similar to below:

Before Sitecore 7.5:


<Border ID="PublishChildrenPane"  Visible="false">
   <Checkbox ID="PublishChildren" Header="Publish Subitems"/>
</Border>

From Sitecore 7.5 onwards:

<Border ID="PublishChildrenPane" >
   <Checkbox ID="PublishChildren" Header="Publish Subitems"/>
   <br />
   <Checkbox ID="PublishRelatedItems" Header="Publish Related Items"/>
</Border>

3. Add Visible=”false” attribute to border control like below: e.g.

<Border ID="PublishChildrenPane" Visible="false">
   <Checkbox ID="PublishChildren" Header="Publish Subitems"/>
</Border>

4. For default checked or unchecked you can add attribute IsChecked=”True” to checkbox

<Border ID="PublishChildrenPane" Visible="false">
   <Checkbox ID="PublishChildren" Header="Publish Subitems" IsChecked="True"/>
</Border>

Hope you like it… 🙂
-Mrunal

Sites with individual WFFM folder in Sitecore Foundry

Hi Folks,

Generally in Sitecore foundry every website will share single WFFM’s webform folder. However if you have multiple clients on same foundry instance then each client will have different webforms for their site. Its good to have separate webform folder for each client so no other client can access webform and its data of other client.

Also when we want to generate Sitemap.xml file for each website using sitecore task we need each website scheme i.e. “http” or “https” so that you can create site specific Url.

Below solution will help to achieve above goal.


using Sitecore.Data.Items;
using Sitecore.Foundry.Sites;
using Sitecore.SecurityModel;
using System.Linq;
namespace YournameSpace
{
	public class SetFoundrySiteProperties : FoundrySiteProvider
	{
        public ID Template_WFFMFolder = new Sitecore.Data.ID("{C0A68A37-3C0A-4EEB-8F84-76A7DF7C840E}");
		protected override System.Collections.Generic.List<Sitecore.Sites.Site> GetFoundrySites()
		{
			var sites = base.GetFoundrySites();

			using (SecurityDisabler securityDisabler = new SecurityDisabler())
			{
				foreach (var site in sites)
				{
					Item siteRoot = Sitecore.Foundry.Context.SiteDatabase.GetItem(site.Properties[FoundrySiteProvider.RootPathProperty]);
					if(siteRoot != null)
					{
						//Traverse Site root children for Local WFFM's webform folder.
						Item wfRoot = siteRoot.Children.Where(c => c.TemplateID == Template_WFFMFolder).FirstOrDefault();
						if(wfRoot != null)
						{
							site.Properties["formsRoot"] = wfRoot.ID.ToString();
							site.Properties["scheme"] = "http";
						}
					}
				}
			}
			return sites;
		}
	}
}

Web.Config:


<siteManager set:defaultProvider="customFoundrySiteProvider">
	<providers>
		<add name="customFoundrySiteProvider" type="YourNameSpace.SetFoundrySiteProperties, YourAssembly" />
	</providers>
</siteManager>

Let me know if you find this solution useful. 🙂

Sitecore: SEO friendly Media Urls

Hi Sitecore Lover,

Today I received new requirement from client, they want their media Urls to be SEO friendly, thus media urls will have no ‘ ‘ it should be replaced with ‘-‘. Sitecore manages page url very well, however media url requires custom development.

To achieve result, we need to overwrite  Media Provider.

Solution:

Code:

using Sitecore.Resources.Media;
namespace YourNameSpace
{
    public class MediaProvider : Sitecore.Resources.Media.MediaProvider
    {
        public override string GetMediaUrl(Sitecore.Data.ItemsMediaItem item, Sitecore.Resources.MediaMediaUrlOptions options)
        {
            string mediaUrl = base.GetMediaUrl(item, options);
            //Replace with Hypen
            return mediaUrl.Replace(" ", "-");
        }

        protected override Sitecore.Resources.Media.MediaData GetMediaData(Sitecore.Resources.MediaMediaUri mediaUri)
        {
            MediaData md = base.GetMediaData(mediaUri);
            if (md == null)
            {
                //If default not found, try to replace hypen
                return base.GetMediaData(new MediaUri(
                    mediaUri.MediaPath.Replace("-", " "),
                    mediaUri.Language,
                    mediaUri.Version,
                    mediaUri.Database
                    ));
            }
            return md;
        }
    }
}

Web.config Change:

Replace:

<mediaProvider type="Sitecore.Resources.Media.MediaProvider, Sitecore.Kernel"/>

With:

<mediaProvider type="YourNamespace.MediaProvider, YourAssembly"/>

Caution:

Any item has “” in their name will not be served by Sitecore as it creates ambiguity between name.

I have tested this solution on Sitecore.NET 7.0 (rev. 140120).

Thanks for reading.
-Mrunal