<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sitecore &#8211; Fire Breaks Ice</title>
	<atom:link href="http://firebreaksice.com/category/sitecore/feed/" rel="self" type="application/rss+xml" />
	<link>https://firebreaksice.com</link>
	<description>Sitecore Tips and Best Practices by Mark Ursino, Sitecore MVP</description>
	<lastBuildDate>Tue, 17 Feb 2026 21:37:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>
	<item>
		<title>Support Explicit User Types with Sitecore Personas</title>
		<link>https://firebreaksice.com/support-explicit-user-types-sitecore-personas/</link>
					<comments>https://firebreaksice.com/support-explicit-user-types-sitecore-personas/#comments</comments>
		
		<dc:creator><![CDATA[Mark Ursino]]></dc:creator>
		<pubDate>Wed, 01 Nov 2017 20:58:04 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<guid isPermaLink="false">http://firebreaksice.com/?p=1090</guid>

					<description><![CDATA[Learn how to leverage Sitecore personas/profiles and some simple code to support explicit self-selected visitor types.]]></description>
										<content:encoded><![CDATA[<p>Sitecore has built-in ways to to track user types via the personas/profiles construct. This allows content to be scored against custom personas/profiles so users can be implicitly categorized based on their browsing behavior. This enables marketers to segment visitors for analytics purposes and allows them to leverage the rule engine to personalize content based on inferred personas. While personas work out of the box for implicit behavior-driven categorization of visitors (assuming marketers define personas and score pages), we can leverage some simple code to also use personas for explicit self-selected user types. Read on to learn how to achieve this.</p>
<h2>Explicit user types</h2>
<p>Let&#8217;s first understand the use case. Some websites are structured in a way to allow visitors to self-select their interests, perhaps by self-selecting a user type. For example, an eCommerce website might categorize content differently between end consumers and businesses, so allowing the visitor to self select as a business user vs. an end consumer may be beneficial to getting the user what they want sooner. There are many ways we can achieve the ability to personalize content for explicit self-selection:</p>
<ol>
<li>Leverage a custom cookie for &#8220;explicit user type&#8221; and create a custom rules engine cookie condition</li>
<li>Leverage another typical state management construct (e.g. session) for &#8220;explicit user type&#8221; and create a custom rules engine condition</li>
<li>Extend xDB contacts with a custom facet for &#8220;explicit user type&#8221; and leverage a built-in rules engine condition</li>
<li>Or, don&#8217;t reinvent the wheel, <strong>leverage personas/profiles!</strong> and leverage a built-in rules engine condition</li>
</ol>
<p>The advantage of leveraging personas to handle this is the out-of-the-box analytics tracking in Experience Analytics will surface user types via these personas with no extra analytics code. While the persona/profile route is very similar to the xDB contact custom facet route, there may be more work involved in reporting analytics on custom facets.</p>
<h2>Defining the Explicit User Type persona in Sitecore</h2>
<p>So let&#8217;s get started with the definition work in Sitecore. We need to define the &#8220;Explicit User Type&#8221; persona itself with the possible user values, which would end up being dimensions or &#8220;profile keys&#8221; on the persona. For each possible user type, create a key under the persona. I&#8217;ll continue with the eCommerce user type example from before:</p>
<p><img fetchpriority="high" decoding="async" src="https://firebreaksice.com/wp-content/uploads/2017/11/personas-1.jpg" alt="" width="225" height="437" class="alignnone size-full wp-image-1094" srcset="https://firebreaksice.com/wp-content/uploads/2017/11/personas-1.jpg 225w, https://firebreaksice.com/wp-content/uploads/2017/11/personas-1-154x300.jpg 154w" sizes="(max-width: 225px) 100vw, 225px" /></p>
<p>Since the trick of this solution is to leverage binary scenarios (a visitor should only be one type), set the max value for a profile key (think dimension, or value of their user type) to 1:</p>
<p><img decoding="async" src="https://firebreaksice.com/wp-content/uploads/2017/11/personas-2.jpg" alt="" width="169" height="406" class="alignnone size-full wp-image-1095" srcset="https://firebreaksice.com/wp-content/uploads/2017/11/personas-2.jpg 169w, https://firebreaksice.com/wp-content/uploads/2017/11/personas-2-125x300.jpg 125w" sizes="(max-width: 169px) 100vw, 169px" /></p>
<p>So the applied usage of this binary approach would be: Consumer user = 1, Business user = 0 which means they&#8217;re a consumer. More on this later&#8230;</p>
<h2>Defining the pattern cards in Sitecore</h2>
<p>Now that we have a profile (&#8220;persona&#8221;) defined, we need corresponding pattern cards in order to match against users in the rules engine via the built-in rule:</p>
<blockquote><p>where the current [contact/visit] matches the <u>specific pattern card</u> in the <u>specific profile</u></p></blockquote>
<p>Since we plan to leverage the profile keys in a binary scenario (you can only be one user type), we want the pattern cards to match their possible 0 or 1 values. For each possible user type, create a corresponding pattern card and make each pattern match the corresponding 0 or 1 scenario:</p>
<p><img decoding="async" src="https://firebreaksice.com/wp-content/uploads/2017/11/personas-3.jpg" alt="" width="867" height="212" class="alignnone size-full wp-image-1098" srcset="https://firebreaksice.com/wp-content/uploads/2017/11/personas-3.jpg 867w, https://firebreaksice.com/wp-content/uploads/2017/11/personas-3-300x73.jpg 300w, https://firebreaksice.com/wp-content/uploads/2017/11/personas-3-768x188.jpg 768w" sizes="(max-width: 867px) 100vw, 867px" /></p>
<h2>Putting it together with some code</h2>
<p>Now that we have the Sitecore constructs in place, let&#8217;s leverage the binary scenarios and some code to apply a 0 or 1 to the user based on their self-selected user type. <strong>NOTE:</strong> when you add a profile key value to a visitor, it gets incremented over time. So without code to handle it as a binary scenario, you could end up with incremented values over time, e.g. Consumer user = 4, Business user = 5 means the user self-selected as consumer four times and self-selected as a business user five times. So in our code we handle this by removing the profile and re-adding it every time a user self-selects.</p>
<p>Here&#8217;s the meat of the code (without all the upstream initialization and checks):</p>
<p>[sourcecode]</p>
<p>public static void SwitchProfileValues(string profileName, Dictionary&lt;string, float&gt; scores)<br />
{<br />
	&#8230;</p>
<p>	// if the user already had a value for<br />
	// the profile, delete it so we can<br />
	// record a new binary scenario<br />
	if (Tracker.Current.Interaction.Profiles.ContainsProfile(profileName))<br />
	{<br />
		Tracker.Current.Interaction.Profiles.Remove(profileName);<br />
	}</p>
<p>	var profiles = new List&lt;Sitecore.Analytics.Model.ProfileData&gt;<br />
	{<br />
		new Sitecore.Analytics.Model.ProfileData(profileName)<br />
	};</p>
<p>	Tracker.Current.Interaction.Profiles.Initialize(profiles);<br />
	profile = Tracker.Current.Interaction.Profiles[profileName];               </p>
<p>	profile.Score(scores);<br />
	profile.UpdatePattern();</p>
<p>	&#8230;<br />
}</p>
<p>[/sourcecode]</p>
<p>And example ways to call it:</p>
<p>[sourcecode]</p>
<p>// self-selecting as a consumer user:<br />
SwitchProfileValues(&quot;Explicit User Type&quot;, new Dictionary&lt;string, float&gt;(){{ &quot;Consumer user&quot;, 1.0}, { &quot;Business user&quot;, 0.0}});</p>
<p>// self-selecting as a business user:<br />
SwitchProfileValues(&quot;Explicit User Type&quot;, new Dictionary&lt;string, float&gt;(){{ &quot;Consumer user&quot;, 0.0}, { &quot;Business user&quot;, 1.0}});</p>
<p>[/sourcecode]</p>
<p>So, does this really work in the real world? Yes! In the last 2 months I&#8217;ve used this approach twice already. Let&#8217;s look at some real world analytics to see how it surfaces. Navigate to Experience Analytics > Audience > Pattern Matches. Below is recent analytics data with the real user types redacted since I don&#8217;t want to give away information about a current client.</p>
<p><img loading="lazy" decoding="async" src="https://firebreaksice.com/wp-content/uploads/2017/11/personas-4.jpg" alt="" width="785" height="455" class="alignnone size-full wp-image-1101" srcset="https://firebreaksice.com/wp-content/uploads/2017/11/personas-4.jpg 785w, https://firebreaksice.com/wp-content/uploads/2017/11/personas-4-300x174.jpg 300w, https://firebreaksice.com/wp-content/uploads/2017/11/personas-4-768x445.jpg 768w" sizes="auto, (max-width: 785px) 100vw, 785px" /></p>
<p>And there you have it. If you have solved this problem in another way, please comment with your solution!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://firebreaksice.com/support-explicit-user-types-sitecore-personas/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Rollback Sitecore Content</title>
		<link>https://firebreaksice.com/rollback-sitecore-content/</link>
		
		<dc:creator><![CDATA[Mark Ursino]]></dc:creator>
		<pubDate>Fri, 23 Jun 2017 17:20:00 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<guid isPermaLink="false">http://firebreaksice.com/?p=1080</guid>

					<description><![CDATA[Learn how to rollback Sitecore content to a prior version on the live website.]]></description>
										<content:encoded><![CDATA[<p>I have another <a href="https://firebreaksice.com/unpublish-sitecore-content/">blog post about how to unpublish Sitecore content</a>, however there seem to be a number of questions about how to rollback to a prior version of content. The purpose of this blog post is to clear up the process.</p>
<p>The process of rolling back content &#8212; or said another way &#8212; publishing a prior version of content, is the same as unpublishing content. You must leverage publishing restrictions to determine what should be published to the live site.</p>
<h2>Publishing Restrictions</h2>
<p>Let&#8217;s take a sample item with 4 versions as an example. Versions 1, 2, and 3 are approved; version 3 is live. Version 4 is a draft and in the process of being edited. Urgently, there is a need to get version 1 live right away!</p>
<p>In the publishing restrictions dialog, uncheck versions 2, 3, and 4 from being publishable. This will mean I will end up publishing version 1.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1083" src="https://firebreaksice.com/wp-content/uploads/2017/06/rollback-1.jpg" alt="" width="532" height="535" srcset="https://firebreaksice.com/wp-content/uploads/2017/06/rollback-1.jpg 532w, https://firebreaksice.com/wp-content/uploads/2017/06/rollback-1-150x150.jpg 150w, https://firebreaksice.com/wp-content/uploads/2017/06/rollback-1-298x300.jpg 298w" sizes="auto, (max-width: 532px) 100vw, 532px" /></p>
<h2>Publishing Warnings</h2>
<p>When I stay on version 4, the warning will clearly tell me that version 1 will be published, because its the latest version that I am allowing to be published based on the above restrictions.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1084" src="https://firebreaksice.com/wp-content/uploads/2017/06/rollback-2.jpg" alt="" width="728" height="228" srcset="https://firebreaksice.com/wp-content/uploads/2017/06/rollback-2.jpg 728w, https://firebreaksice.com/wp-content/uploads/2017/06/rollback-2-300x94.jpg 300w" sizes="auto, (max-width: 728px) 100vw, 728px" /></p>
<p>If I flip to version 1 you will not see that same warning because I am actually on the version that is allowed to be published.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1085" src="https://firebreaksice.com/wp-content/uploads/2017/06/rollback-3.jpg" alt="" width="731" height="223" srcset="https://firebreaksice.com/wp-content/uploads/2017/06/rollback-3.jpg 731w, https://firebreaksice.com/wp-content/uploads/2017/06/rollback-3-300x92.jpg 300w" sizes="auto, (max-width: 731px) 100vw, 731px" /></p>
<p>The next step is to publish and version 1 is now live. You&#8217;ve just successfully rolled back to that version of content on the live site. The later versions (2-4) still exist for an audit trail if you need them in the future.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Sitecore Predefined Rules for Geolocation Conditions</title>
		<link>https://firebreaksice.com/sitecore-predefined-rules-geolocation-conditions/</link>
		
		<dc:creator><![CDATA[Mark Ursino]]></dc:creator>
		<pubDate>Fri, 31 Mar 2017 17:23:17 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<guid isPermaLink="false">http://firebreaksice.com/?p=1071</guid>

					<description><![CDATA[Learn how to build re-usable composite conditions in Sitecore as Predefined Rules.]]></description>
										<content:encoded><![CDATA[<p>I was recently working with a project team to define an approach to personalize content based on the region of visitors. When you think &#8220;region of the visitor&#8221; you may be thinking about the <code>Region</code> attribute from Sitecore Geolocation data. For this particular Sitecore site our client has their own definitions of what regions are. The client is a Massachusetts-only company and wants to target content across four types of areas of the state, or what they call regions to them: Coastal, City, Rural, Suburb. The key is that they have specific zip codes to map to these four regions. Let&#8217;s figure out how we can make this work without any custom code.</p>
<h2>Approach</h2>
<p>The general approach is to build four predefined conditions in Sitecore that we can use as our four region conditions. Think of Sitecore &#8220;predefined rules&#8221; as complicated composite rules that you might re-use over and over with a friendly name. By creating these once, we can apply them in any case where we have a rules field (e.g. personalization).</p>
<h2>Create the Predefined Condition</h2>
<ol>
<li>Navigate to <strong>Marketing Control Panel &gt; Personalization &gt; Predefined Rules</strong></li>
<li>Create a predefined rule for each of the four region scenarios, like in the image below:</li>
</ol>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1072" src="https://firebreaksice.com/wp-content/uploads/2017/03/rules1.png" alt="" width="350" height="679" srcset="https://firebreaksice.com/wp-content/uploads/2017/03/rules1.png 350w, https://firebreaksice.com/wp-content/uploads/2017/03/rules1-155x300.png 155w" sizes="auto, (max-width: 350px) 100vw, 350px" /></p>
<p>In each predefined rule you can populate the rules field with all the inner composite details with the zip codes. In this case the regions have many zip codes, but this content population effort in the rule is a one-time pain we deal with up front. The image below shows just two zip codes but you can build the rule up as big as you need with all of the possible zips.<br />
<strong>Note</strong>: Sitecore&#8217;s geolocation data captures zip code in the <code>Postal Code</code> attribute.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1073" src="https://firebreaksice.com/wp-content/uploads/2017/03/rules2.png" alt="" width="307" height="388" srcset="https://firebreaksice.com/wp-content/uploads/2017/03/rules2.png 307w, https://firebreaksice.com/wp-content/uploads/2017/03/rules2-237x300.png 237w" sizes="auto, (max-width: 307px) 100vw, 307px" /></p>
<h2>Use the Predefined Conditions for Personalization</h2>
<p>So how do we make use of these composite rules we painstakingly populated with hundreds of zip codes?</p>
<p>When you personalize a rendering, there&#8217;s a condition to select where a specific predefined rule evaluates to true:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1074" src="https://firebreaksice.com/wp-content/uploads/2017/03/rules3.png" alt="" width="252" height="195" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1075" src="https://firebreaksice.com/wp-content/uploads/2017/03/rules4.png" alt="" width="263" height="145" /></p>
<p>In the dialog you would select one of the four predefined rules you created for this personalization scenario:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1076" src="https://firebreaksice.com/wp-content/uploads/2017/03/rules5.png" alt="" width="279" height="242" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1077" src="https://firebreaksice.com/wp-content/uploads/2017/03/rules6.png" alt="" width="241" height="154" /></p>
<p>Now you can set a unique data source based on this region and re-use these rules over and over without having to type in all of the zip codes on multiple pages.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Troubleshooting Sitecore Indexing Issues</title>
		<link>https://firebreaksice.com/troubleshooting-sitecore-indexing-issues/</link>
					<comments>https://firebreaksice.com/troubleshooting-sitecore-indexing-issues/#comments</comments>
		
		<dc:creator><![CDATA[Mark Ursino]]></dc:creator>
		<pubDate>Tue, 07 Feb 2017 19:28:12 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<guid isPermaLink="false">http://firebreaksice.com/?p=1051</guid>

					<description><![CDATA[Learn some tips and tricks to troubleshoot indexing issues with Sitecore.]]></description>
										<content:encoded><![CDATA[<p>Not another one of these posts &#8212; troubleshooting indexing issues with Sitecore?! Well, I wanted to quickly provide some guidance on ways to troubleshoot indexing. Read on to learn a bit about indexing and things to look out for as you troubleshoot issues.</p>
<h2>Indexing Strategies</h2>
<p>Part of the indexing configuration in Sitecore includes <a href="https://doc.sitecore.net/sitecore_experience_platform/setting_up_and_maintaining/search_and_indexing/indexing/index_update_strategies" target="_blank">indexing strategies</a> that you select from. These are C# classes that run at indexing time based on how you want the system to behave. The default strategy in a stock instance for the &#8220;web&#8221; database is <code>onPublishEndAsync</code>. This strategy uses the <a href="https://www.youtube.com/watch?v=7qkDc6W0OMs" target="_blank">event queue</a> to subscribe to the <code>publish:end</code> event. When raised, it triggers an incremental index update (i.e. not a full index rebuild but small deltas directly on the index). So how does this actually work to update the index? If you&#8217;re having indexing issues with this strategy then continue reading.</p>
<h2>EQStamp</h2>
<p>The event queue keeps a record of events fired on instances of Sitecore. Each instance polls the queue to check for changes. The <code>onPublishEndAsync</code> strategy first finds the <code>EQStamp</code> property for the Sitecore instance in the Core database&#8217;s <code>Properties</code> table. The format for the <code>Key</code> is <code>EQStamp_&lt;instance name&gt;</code> and the value is a sequentially updated decimal.</p>
<p>The strategy then finds all records in the event queue that are remote (i.e. fired by another instance such as a CM) and have occurred since the <code>EQStamp</code>. It does this by scanning the records and comparing the <code>Stamp</code> column (in <code>EventQueue</code>) to the <code>EQStamp</code> (in <code>Properties</code>). That said, the <code>Stamp</code> column is in hexadecimal format, so it needs to convert to decimal to compare these values.</p>
<h2>Compare EQStamp and Stamp</h2>
<p>How does this help you? To troubleshoot indexing issues, clear your event queue table contents and delete any <code>EQStamp</code> values in <code>Properties</code>. A simple query like this will do:</p>
<pre>
DELETE FROM Properties WHERE [Key] LIKE 'EQStamp%'
</pre>
<p>Make some change in the CMS and publish your content to web. This will fire events and seed the event queue with some data. Next, get the most recent events like so:</p>
<pre>
SELECT * FROM EventQueue ORDER BY Created DESC
</pre>
<p>Next, open up Google (you may have heard of it) and convert the latest value of the <code>Stamp</code> column to decimal (e.g. search for <strong>0x3B64 to decimal</strong>). Now compare this value to the <code>EQStamp</code>. If its greater than <code>EQStamp</code> then this record in the queue has not been processed. If it equals the <code>EQStamp</code> then Sitecore has processed the event and should update the index.</p>
<h2>Things to consider</h2>
<p>If the queue isn&#8217;t being processed based on the data from above, make sure you don&#8217;t have any errors in the logs. You can also increase the logging verbosity to get more intel on possible issues:</p>
<pre>
&lt;log4net&gt;
  &lt;logger name="Sitecore.Diagnostics.Crawling" additivity="false"&gt;
    &lt;level value="<strong>DEBUG</strong>" /&gt;
    &lt;appender-ref ref="CrawlingLogFileAppender" /&gt;
  &lt;/logger&gt;
&lt;log4net&gt;
</pre>
<p>As well as <code>&lt;events timingLevel="high"&gt;</code></p>
<p>Additionally, make sure your versions of Sitecore match between instances. It sounds silly, but this happened to me before where a CM and CD were off by a minor revision and indexing failed to work properly.</p>
<p>Finally, another way to peek in on what&#8217;s going on is to use <a href="https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx" target="_blank">Microsoft&#8217;s Process Monitor</a> and sniff activity from <code>w3wp</code>. Fire it up, go to Filter > Filter, and add <strong>Process Name</strong> <em>contains</em> w3wp.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://firebreaksice.com/troubleshooting-sitecore-indexing-issues/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Configure Sitecore&#8217;s Mongo Client to use SSL</title>
		<link>https://firebreaksice.com/configure-sitecores-mongo-client-use-ssl/</link>
					<comments>https://firebreaksice.com/configure-sitecores-mongo-client-use-ssl/#comments</comments>
		
		<dc:creator><![CDATA[Mark Ursino]]></dc:creator>
		<pubDate>Mon, 16 May 2016 18:16:23 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<guid isPermaLink="false">http://firebreaksice.com/?p=1026</guid>

					<description><![CDATA[Learn how to tap into Sitecore's MongoDB C# driver client creation to inject a client certificate for SSL.]]></description>
										<content:encoded><![CDATA[<p>Many production-facing Sitecore implementations have requirements to use SSL, and this should apply to the use of xDB as well. Since xDB is built on MongoDB, its important to be able to leverage MongoDB data connections with the use of SSL. This blog post explains how you can ensure (with minimal code) the MongoDB C# driver client object is created with a client certificate for SSL.</p>
<p>Out of the box Sitecore creates an instance of the MongoDB C# driver as the client to allow the Sitecore application to interact and communicate with MongoDB. This occurs in <code>Sitecore.Analytics.MongoDb.dll</code> in the class <code>Sitecore.Analytics.Data.DataAccess.MongoDb.MongoDbDriver</code>. The constructor creates a MongoDB client from the URL settings via the connection string. That said, if you have a MongoDB enterprise client certificate, you need to ensure Sitecore creates the client in C# with that certificate. Luckily Sitecore has thought of this and exposed a pipeline to update the MongoDB client settings before it constructs the client object. Here&#8217;s the relevant code snippet directly from Sitecore&#8217;s DLL:</p>
<p><script src="https://gist.github.com/mursino/44d88246e72a96c87597c3b6b7e6089e.js"></script></p>
<p>So to tap into this and update the settings we need to run a processor in that pipeline. The pipeline appears to have no processors out of the box according to its config file (<code>App_Config\Include\Sitecore.Analytics.MongoDb.config</code>):</p>
<p><script src="https://gist.github.com/mursino/f8351f796414b7216e4a3b77232fa99a.js"></script></p>
<p>Let&#8217;s tap in and add our client certificate settings via the <code>updateMongoDriverSettings</code> pipeline.</p>
<p>The MongoDB C# driver <a href="http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/ssl/#mongoclientsettings" target="_blank">documentation to update the client setting with the certificate info</a> indicates the following sample code snippet:</p>
<p><script src="https://gist.github.com/mursino/bfe3add0b785d4db78881da32ec96c82.js"></script></p>
<p>So we can write our corresponding pipeline processor like this:</p>
<p><script src="https://gist.github.com/mursino/abc651f96b87dc7cc4bf3087825bba2c.js"></script></p>
<p>Now we can obviously abstract the two hard-coded strings for &#8220;client.pfx&#8221; and &#8220;mySuperSecretPassword&#8221; and expose them in a config setting. Also note that the pipeline processor base class exposes an abstract method <code>UpdateSettings(UpdateMongoDriverSettingsArgs args)</code> that you will want to override in the processor (rather than implementing <code>Process(...)</code>).</p>
<p>And that&#8217;s about all you need. With minimal code and config changes you can ensure the MongoDB C# client object respects the necessary certificate that the server expects.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://firebreaksice.com/configure-sitecores-mongo-client-use-ssl/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Sitecore Patchable Ignore Lists</title>
		<link>https://firebreaksice.com/sitecore-patchable-ignore-lists/</link>
					<comments>https://firebreaksice.com/sitecore-patchable-ignore-lists/#comments</comments>
		
		<dc:creator><![CDATA[Mark Ursino]]></dc:creator>
		<pubDate>Tue, 12 Apr 2016 14:00:40 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<guid isPermaLink="false">http://firebreaksice.com/?p=990</guid>

					<description><![CDATA[Learn how to patch in routes for Sitecore to ignore with a simple pipeline processor.]]></description>
										<content:encoded><![CDATA[<p>Sitecore hijacks requests as they comes through the application via the <code>httpRequestBegin</code> pipeline. In order to serve a resource outside of the Sitecore pipeline, you need to abandon the Sitecore context. Sitecore achieves this by allowing you to add the route to ignore to the <strong>IgnoreUrlPrefixes</strong> setting. This blog post shows a way to support patchable ignore paths so you don&#8217;t need to copy the existing setting to add to it.</p>
<p>Let&#8217;s think of a quick example of the concern: you want to ignore the Sitecore pipeline for requests to <code>/foo</code>, <code>/bar</code>, and <code>/baz</code>. The way I would have done this before was to patch the Sitecore setting with a copy of the old one and added my new route(s) at the end, roughly like so:</p>
<p><script src="https://gist.github.com/mursino/3a67312663127368a0549632bd0b1241.js"></script></p>
<p>So instead, I&#8217;ve created a new pipeline processor that comes after the built-in one (which will support the existing native <strong>IgnoreUrlPrefixes</strong> setting) and will allow you to add each path via its own XML config node. The advantage here is you can patch and continue to patch on without needing to copy the existing values. Here&#8217;s the final patch config to load my new processor with two sample paths to ignore:</p>
<p><script src="https://gist.github.com/mursino/4ab1287b54dc1933d6a734ff04a25aa4.js"></script></p>
<p>So not only will the original list of paths be ignored, now we&#8217;ve added <code>/foo</code> and <code>/bar</code> to the list.</p>
<p>Here&#8217; an example on another patch patching in a third value to ignore:</p>
<p><script src="https://gist.github.com/mursino/b5f499497075f2243ffc30ab1489259e.js"></script></p>
<p>Here&#8217;s the source code for the processor:</p>
<p><script src="https://gist.github.com/mursino/714de6a3d948837bfb098d44432c7316.js"></script></p>
<h2>Marketplace Module &#038; Source</h2>
<p>This is now available on the <a href="https://marketplace.sitecore.net/Modules/P/Patchable_Ignore_List.aspx" target="_blank">Sitecore Marketplace as a module</a>.</p>
<p>Additionally, the <a href="https://github.com/mursino/Sitecore.PatchableIgnoreList" target="_blank">source code is on GitHub</a>.</p>
<p><strong>Update</strong>: in the process of putting this on the Marketplace I found out that <a href="http://www.awareweb.com/awareblog/12-14-15-patchableignorelist" target="_blank">Ben Golden has a similar solution with the exact same name</a> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://firebreaksice.com/sitecore-patchable-ignore-lists/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Sitecore Rendering Datasource Locations</title>
		<link>https://firebreaksice.com/sitecore-rendering-datasource-locations/</link>
					<comments>https://firebreaksice.com/sitecore-rendering-datasource-locations/#comments</comments>
		
		<dc:creator><![CDATA[Mark Ursino]]></dc:creator>
		<pubDate>Tue, 05 Apr 2016 18:33:24 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<guid isPermaLink="false">http://firebreaksice.com/?p=988</guid>

					<description><![CDATA[Learn how to leverage multiple types of paths and queries to scale your rendering datasource locations for a complex content architecture.]]></description>
										<content:encoded><![CDATA[<p>There are a number of ways we can define the root location for data sources of our renderings. I&#8217;m going to use an example below of a multi-site solution within a large organization that make heavy use of <a href="https://firebreaksice.com/using-the-datasource-field-with-sitecore-sublayouts/">data sources</a> for page content &#8211; a key concept to take advantage of all the Sitecore goodness such as personalization and <a href="https://firebreaksice.com/sitecore-8-content-testing-via-workflow/">multivariate testing</a>. Consider the following content architecture in Sitecore:</p>
<ul>
<li>An global organization-level shared content repository: content here can be shared across all sites/brands within the Sitecore application</li>
<li>A site-level shared content repository: content here can be shared across all pages of this site</li>
<li>A page-level content folder: content here is specific to the page</li>
</ul>
<p><img loading="lazy" decoding="async" width="235" height="317" src="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-1.jpg" class="alignnone size-full wp-image-991" srcset="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-1.jpg 235w, https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-1-222x300.jpg 222w" sizes="auto, (max-width: 235px) 100vw, 235px" /></p>
<p>The rendering now needs to know how to get these three locations when resolving the datasource locations for the pop-up dialog. Luckily, the <code>GetRenderingDatasource</code> pipeline has a nifty <code>GetDatasourceLocation</code> processor that makes this very easy. It has built-in support for queries and static paths with a pipe delimiter between locations. Let&#8217;s take them one at a time.</p>
<p>First, find the &#8220;Datasource Location&#8221; field on the rendering definition item:</p>
<p><img loading="lazy" decoding="async" width="322" height="103" src="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-2.jpg" class="alignnone size-full wp-image-992" srcset="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-2.jpg 322w, https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-2-300x96.jpg 300w" sizes="auto, (max-width: 322px) 100vw, 322px" /></p>
<p>Now let&#8217;s populate the global, site-scoped, and page-scoped paths.</p>
<p>The global query is pretty easy and can be a static path. Just make sure you associate the necessary access rights to disable deleting or renaming of these global folders:</p>
<p>The path is:<br />
<code>/sitecore/content/Global Shared Content/Global Carousels</code></p>
<p><img loading="lazy" decoding="async" width="357" height="105" src="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-3.jpg" class="alignnone size-full wp-image-993" srcset="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-3.jpg 357w, https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-3-300x88.jpg 300w" sizes="auto, (max-width: 357px) 100vw, 357px" /></p>
<p>The site-specific query requires an XPath query to find the closest ancestor of the &#8220;Site&#8221; type, and traverses down the hierarchy from there.</p>
<p>The query is:<br />
<code>query:./ancestor-or-self::*[@@templatename='Site']/Shared Content/Site Carousels</code></p>
<p><img loading="lazy" decoding="async" width="798" height="102" src="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-4.jpg" class="alignnone size-full wp-image-994" srcset="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-4.jpg 798w, https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-4-300x38.jpg 300w, https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-4-768x98.jpg 768w" sizes="auto, (max-width: 798px) 100vw, 798px" /></p>
<p>Don&#8217;t forget the pipe (&#8220;|&#8221;) delimiter!</p>
<p>Finally, the page-specific query requires a basic dot-notation query to traverse down the hierarchy of the current item/page.</p>
<p>The query is:<br />
<code>./Page Content/Page Carousels</code></p>
<p><img loading="lazy" decoding="async" width="970" height="107" src="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-5.jpg" class="alignnone size-full wp-image-995" srcset="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-5.jpg 970w, https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-5-300x33.jpg 300w, https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-5-768x85.jpg 768w" sizes="auto, (max-width: 970px) 100vw, 970px" /></p>
<p>The final value for all three locations is:<br />
<code>/sitecore/content/Global Shared Content/Global Carousels|query:./ancestor-or-self::*[@@templatename='Site']/Shared Content/Site Carousels|./Page Content/Page Carousels</code></p>
<p>Now when we launch the content dialog it provides access to all three locations, no code required!</p>
<p><img loading="lazy" decoding="async" width="516" height="375" src="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-6.jpg" class="alignnone size-full wp-image-999" srcset="https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-6.jpg 516w, https://firebreaksice.com/wp-content/uploads/2016/04/ds-locations-6-300x218.jpg 300w" sizes="auto, (max-width: 516px) 100vw, 516px" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://firebreaksice.com/sitecore-rendering-datasource-locations/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>Handle URLs for Sitecore Folder Items</title>
		<link>https://firebreaksice.com/handle-urls-for-sitecore-folder-items/</link>
					<comments>https://firebreaksice.com/handle-urls-for-sitecore-folder-items/#comments</comments>
		
		<dc:creator><![CDATA[Mark Ursino]]></dc:creator>
		<pubDate>Mon, 07 Dec 2015 16:36:53 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<guid isPermaLink="false">http://firebreaksice.com/?p=971</guid>

					<description><![CDATA[Learn how to easily handle URLs for folder items within a Sitecore page hierarchy.]]></description>
										<content:encoded><![CDATA[<p>Richard Seal recently wrote <a href="http://www.sitecorenutsbolts.net/2015/11/30/Securing-the-Assets-data-folder/" target="_blank">a blog post</a> about how to secure data source items and folders under content pages within the content tree. The TL;DR of his post is that any folders and data source items in the content hierarchy under the home page would technically resolve to item URLs, however because they don&#8217;t have any presentation set they will generate a Layout Not Found page. The proposed solution was to use a pipeline processor to catch any items that are not pages based on a <strong>Resolve to Url</strong> checkbox. First, I want to explain an old solution I used to use for this that may now be better solved via the pipeline processor (a great idea!), and secondly I want to propose an improvement to the processor to avoid a checkbox for determining if an item is a page or not.</p>
<h2>The <em>Redirect to Parent Page</em> Component</h2>
<p>Prior to reading Richard&#8217;s blog post I had always solved similar issues with a unique UI component called <em><strong>Redirect to Parent Page</strong></em>. The items in question to use it on would be data source folder items like the &#8220;Assets&#8221; folder in Richard&#8217;s post, item bucket folder items generated by Sitecore, or even manually generated folders under pages (e.g. year, month, and day folders with News Mover before item buckets came out). For any of the above items&#8217; standard values I would add a layout and apply the <em><strong>Redirect to Parent Page</strong></em> component to any placeholder. The <em><strong>Redirect to Parent Page</strong></em> component would check to see if the current item is a page and if not, loop up the hierarchy until it finds a page. E.g.</p>
<p>[csharp]<br />
Item item = Sitecore.Context.Item;</p>
<p>// add additional checks so there&#8217;s no infinite loop &#8211; e.g. look for the root item<br />
while(String.IsNullOrEmpty(item.Fields[Sitecore.FieldIDs.LayoutField].Value)<br />
{<br />
  item = item.Parent;<br />
}</p>
<p>Response.Redirect(LinkManager.GetItemUrl(item));<br />
[/csharp]</p>
<p>So if I have a page such as http://www.mysite.com/news/2015/12/01/some-page and I trim back the URL to http://www.mysite.com/news/2015/12/01/ the site would redirect to the closest parent page which may be the news landing page (http://www.mysite.com/news/).</p>
<p>Not only does this work for folders in the page hierarchy, but it can also be applied to data source content items in a folder under a page like in the Assets folder mentioned in Richard&#8217;s post.</p>
<h2>Improving the None Page Pipeline Processor</h2>
<p>Now taking the processor approach to this, it solves the problem of needing to assign a layout and the UI component to the standard values of any non-page items. That definitely saves time. But the next challenge is that pesky little <strong>Resolve to Url</strong> checkbox. Rather than rely on a checkbox to determine this and using standard values to set it, why not just see if the item is a page? Using the same code I have above, its possible to update the processor to check if the item has any presentation set and if not, redirect to the closest parent page. That said, the best idea is not to actually redirect, because in the end redirecting is telling the browser and search engines that this was a page and is temporarily or permanently being redirected. Instead, the best solution is to send a 404 status code to the browser. This can be achieved via the following simple code split across two processors:</p>
<p>[csharp]</p>
<p>// in the same processor in Richard&#8217;s post add a custom 404 flag to the current request<br />
HttpContext.Current.Items[&quot;404&quot;] = true;</p>
<p>[/csharp]</p>
<p>Then in the <code>httpRequestProcessed</code> pipeline, patch in the following code to respond to the request and set the 404 status code if need be:</p>
<p>[csharp]</p>
<p>var status = HttpContext.Current.Items[&quot;404&quot;];</p>
<p>if (status == null || !(bool)status)<br />
  return;</p>
<p>HttpContext.Current.Response.StatusCode = 404;<br />
HttpContext.Current.Response.TrySkipIisCustomErrors = true;</p>
<p>[/csharp]</p>
]]></content:encoded>
					
					<wfw:commentRss>https://firebreaksice.com/handle-urls-for-sitecore-folder-items/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Sitecore 8 Content Testing via Workflow</title>
		<link>https://firebreaksice.com/sitecore-8-content-testing-via-workflow/</link>
		
		<dc:creator><![CDATA[Mark Ursino]]></dc:creator>
		<pubDate>Tue, 12 May 2015 22:00:49 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<guid isPermaLink="false">http://firebreaksice.com/?p=913</guid>

					<description><![CDATA[Learn all about the changes to multivariate content testing introduced in Sitecore 8.]]></description>
										<content:encoded><![CDATA[<p>Sitecore 8 introduces the ability to manage changes to the presentation layer via workflow. This opens up a whole new world for managing personalization and multivariate testing scenarios via native CMS workflow. Sitecore 8&#8217;s out-of-the-box Sample Workflow builds upon prior versions with the added ability to <a title="Click here to learn about the workflow approval enhancements." href="https://doc.sitecore.net/products/sitecore%20experience%20platform/content%20testing/adding%20content%20testing%20to%20a%20workflow" target="_blank">approve content in workflow with a MV test or approve and skip the test</a>. Approving with the test will launch a preview dialog to see what the test may introduce. Approving without the test will remove the MV test from the presentation of the page. This is useful as an approver if you accept the original content but don&#8217;t feel an MV test should be published live. This blog post covers how to get started with content testing via workflow.</p>
<h2>Versioned Layouts as the Foundation</h2>
<p>The primary driving factor that allows content authors to now implement multivariate testing and personalization changes via workflow is the addition of <a title="Click here to learn more about versioned layouts." href="https://doc.sitecore.net/products/sitecore%20experience%20platform/versioned%20layouts/use%20versioned%20layouts" target="_blank">versioned layouts</a>. Prior to Sitecore 8, the presentation settings for a given content page were stored in a shared built-in <strong><code>"__Renderings"</code></strong> field. As a shared field, there is only one value across languages and numbered versions. This means a presentation layer change (e.g. adding a new component) to version 80 in the Spanish language of an item would also reflect on version 20 in the English language of the same item. Sitecore 8 maintains the existing shared <strong><code>"__Renderings"</code></strong> field but <a title="Click here to learn more about the API changes." href="https://doc.sitecore.net/products/sitecore%20experience%20platform/versioned%20layouts/the%20versioned%20layout%20api%20changes" target="_blank">introduces a new versioned <strong><code>"__Final Renderings"</code></strong> field</a>.</p>
<p><a href="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-1.jpg"><img loading="lazy" decoding="async" class="alignnone wp-image-923 size-full" src="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-1.jpg" alt="sc8-mv-workflow-1" width="501" height="326" srcset="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-1.jpg 501w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-1-300x195.jpg 300w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-1-100x65.jpg 100w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-1-150x98.jpg 150w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-1-200x130.jpg 200w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-1-450x293.jpg 450w" sizes="auto, (max-width: 501px) 100vw, 501px" /></a></p>
<p>Presentation changes that are global and apply to all languages and numbered versions are made to the existing shared field, and new language and numbered version specific changes are applied to the new versioned <strong><code>"__Final Renderings"</code></strong> field. This is where multivariate tests come in with workflow since versions can have different values.</p>
<p>Now that you have a background understanding of how this is possible, let&#8217;s create some variations of content that we can test with.</p>
<h2>Create Content Variations</h2>
<p>Before you create your test, create a few variations of content that we will test. Ensure your solution it setup to use <a href="https://firebreaksice.com/using-the-datasource-field-with-sitecore-sublayouts/">data sources for passing content to the UI</a>.</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-924 size-full" src="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-2.jpg" alt="sc8-mv-workflow-2" width="171" height="78" srcset="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-2.jpg 171w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-2-100x46.jpg 100w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-2-150x68.jpg 150w" sizes="auto, (max-width: 171px) 100vw, 171px" /></p>
<p>Now that we have variations of content, let&#8217;s assign a test and push the changes through workflow.</p>
<h2>Configure a Test and Submit into Workflow</h2>
<p>Let&#8217;s now go ahead and set a presentation component to be tested and assign our content variations. In the Layout Details, select a component and click Test, then provide the variations of content. In the screenshot below I&#8217;m showing this via the Content Editor however you can also configure tests via the Experience Editor.</p>
<p><a href="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-3.jpg"><img loading="lazy" decoding="async" class="alignnone wp-image-925 size-full" src="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-3.jpg" alt="sc8-mv-workflow-3" width="510" height="444" srcset="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-3.jpg 510w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-3-300x261.jpg 300w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-3-100x87.jpg 100w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-3-150x131.jpg 150w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-3-200x174.jpg 200w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-3-450x392.jpg 450w" sizes="auto, (max-width: 510px) 100vw, 510px" /></a></p>
<p>&nbsp;</p>
<p>Set the data source for the original version and create a test variation with another data source. Like personalization, you can also hide the component via the <strong>Hide Component</strong> checkbox or swap it with another via the <strong>Enable variation of component design</strong> checkbox.</p>
<p><a href="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-4.jpg"><img loading="lazy" decoding="async" class="alignnone wp-image-926 size-full" src="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-4.jpg" alt="sc8-mv-workflow-4" width="517" height="709" srcset="https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-4.jpg 517w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-4-219x300.jpg 219w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-4-100x137.jpg 100w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-4-150x206.jpg 150w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-4-200x274.jpg 200w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-4-300x411.jpg 300w, https://firebreaksice.com/wp-content/uploads/2015/04/sc8-mv-workflow-4-450x617.jpg 450w" sizes="auto, (max-width: 517px) 100vw, 517px" /></a></p>
<h2>Approve, Preview and Start the Test</h2>
<p>As an approver, let&#8217;s approve the content item with the test. This launches the <strong>Preview and start test</strong> dialog to show what the variations may do to the experience.</p>
<p><a href="https://firebreaksice.com/wp-content/uploads/2015/05/sc8-mv-workflow-5.jpg"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-950" src="https://firebreaksice.com/wp-content/uploads/2015/05/sc8-mv-workflow-5.jpg" alt="sc8-mv-workflow-5" width="616" height="668" srcset="https://firebreaksice.com/wp-content/uploads/2015/05/sc8-mv-workflow-5.jpg 616w, https://firebreaksice.com/wp-content/uploads/2015/05/sc8-mv-workflow-5-277x300.jpg 277w, https://firebreaksice.com/wp-content/uploads/2015/05/sc8-mv-workflow-5-100x108.jpg 100w, https://firebreaksice.com/wp-content/uploads/2015/05/sc8-mv-workflow-5-150x163.jpg 150w, https://firebreaksice.com/wp-content/uploads/2015/05/sc8-mv-workflow-5-200x217.jpg 200w, https://firebreaksice.com/wp-content/uploads/2015/05/sc8-mv-workflow-5-300x325.jpg 300w, https://firebreaksice.com/wp-content/uploads/2015/05/sc8-mv-workflow-5-450x488.jpg 450w, https://firebreaksice.com/wp-content/uploads/2015/05/sc8-mv-workflow-5-600x651.jpg 600w" sizes="auto, (max-width: 616px) 100vw, 616px" /></a></p>
<p><strong>NOTE</strong>: if you don&#8217;t have a MV test configured on your page prior to submitting the content item through workflow, the approval state will NOT provide Approve with Test and Approve without Test actions. Since no MV test is setup, it will simply provide an Approve action which is the equivalent of Approve without Test. So make sure you configure your MV test in the draft state (or a prior state to the &#8220;with or without test approvals&#8221;).</p>
<p>As you can see in the screenshot above, it will run preview mode and show an image of what each experience looks like to the visitors. If you swap or hide a component you will see those changes. If you adjust content in the component you will also see that. Sitecore will also tell you how many experiences will show on the site and the estimated number of visits required to select a winner.</p>
<p>When you are ready, click the <strong>Start test</strong> button to finally approve the content and start the test.</p>
<p>If you&#8217;re interested in reading more, Sitecore has the following references docs that may be helpful as well:</p>
<ul>
<li><a href="https://doc.sitecore.net/products/sitecore%20experience%20platform/content%20testing/start%20a%20basic%20content%20test" target="_blank">Start a Basic Content Test</a></li>
<li><a href="https://doc.sitecore.net/products/sitecore%20experience%20platform/content%20testing/start%20an%20advanced%20content%20test" target="_blank">Start an Advanced Content Test</a></li>
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Sitecore Synonym Search with Lucene</title>
		<link>https://firebreaksice.com/sitecore-synonym-search-with-lucene/</link>
					<comments>https://firebreaksice.com/sitecore-synonym-search-with-lucene/#comments</comments>
		
		<dc:creator><![CDATA[Mark Ursino]]></dc:creator>
		<pubDate>Thu, 07 May 2015 14:17:17 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<guid isPermaLink="false">http://firebreaksice.com/?p=938</guid>

					<description><![CDATA[Learn how to configure synonym search with the Sitecore Content Search API.]]></description>
										<content:encoded><![CDATA[<p>Sitecore&#8217;s Content Search API comes configured with the standard analyzer by default, however its possible to configure a synonym analyzer if you need this functionality (i.e. searching for a synonym of a word in content finds that result). If you&#8217;re not sure what an analyzer is, <a href="https://www.sitecore.net/learn/blogs/technical-blogs/getting-to-know-sitecore/posts/2013/07/understanding-analyzers-and-sitecore-7.aspx" target="_blank">head over to Adam Conn&#8217;s blog</a> to understand it because its a key component of how both indexing and searching work.</p>
<p>Sitecore ships with its own implementation of a synonym analyzer: <code>Sitecore.ContentSearch.LuceneProvider.Analyzers.SynonymAnalyzer</code>. As you can see in Adam&#8217;s post referenced above, this analyzer uses the same standard tokenizer as the standard analyzer, and also leverages the same lowercase and stop filters to rule out case and stop words from searches. The key to the synonym analyzer is providing it a list of synonyms, which need to be set in your own custom XML file. The reason for this is that Sitecore includes its own synonym engine implementation that uses XML files to store the synonym mappings.</p>
<h2>Configuring the Synonym Analyzer</h2>
<p>In <code>Sitecore.ContentSearch.Lucene.DefaultIndexConfiguration.config</code> (or you can patch the patch), change the inner <code>defaultAnalyzer</code> parameter reference from the standard analyzer to the synonym analyzer:</p>
<p>[xml]<br />
&lt;analyzer type=&quot;Sitecore.ContentSearch.LuceneProvider.Analyzers.PerExecutionContextAnalyzer, Sitecore.ContentSearch.LuceneProvider&quot;&gt;<br />
  &lt;param desc=&quot;defaultAnalyzer&quot; type=&quot;Sitecore.ContentSearch.LuceneProvider.Analyzers.DefaultPerFieldAnalyzer, Sitecore.ContentSearch.LuceneProvider&quot;&gt;<br />
    &lt;param desc=&quot;defaultAnalyzer&quot; type=&quot;Sitecore.ContentSearch.LuceneProvider.Analyzers.SynonymAnalyzer, Sitecore.ContentSearch.LuceneProvider&quot;&gt;<br />
[/xml]</p>
<p>Now unlike the standard analyzer, the synonym analyzer requires an implementation of an <code>ISynonymEngine</code> as its parameter:</p>
<p>[xml]<br />
&lt;param hint=&quot;engine&quot; type=&quot;Sitecore.ContentSearch.LuceneProvider.Analyzers.XmlSynonymEngine, Sitecore.ContentSearch.LuceneProvider&quot;&gt;<br />
[/xml]</p>
<p>Sitecore&#8217;s implementation of that engine is able to read from XML files, and its requires a path to the XML file as its only parameter:</p>
<p>[xml]<br />
&lt;param hint=&quot;xmlSynonymFilePath&quot;&gt;C:\inetpub\wwwroot\yoursite\Data\synonyms.xml&lt;/param&gt;<br />
[/xml]</p>
<p>Putting it all together:</p>
<p>[xml]<br />
&lt;analyzer type=&quot;Sitecore.ContentSearch.LuceneProvider.Analyzers.PerExecutionContextAnalyzer, Sitecore.ContentSearch.LuceneProvider&quot;&gt;<br />
  &lt;param desc=&quot;defaultAnalyzer&quot; type=&quot;Sitecore.ContentSearch.LuceneProvider.Analyzers.DefaultPerFieldAnalyzer, Sitecore.ContentSearch.LuceneProvider&quot;&gt;<br />
    &lt;param desc=&quot;defaultAnalyzer&quot; type=&quot;Sitecore.ContentSearch.LuceneProvider.Analyzers.SynonymAnalyzer, Sitecore.ContentSearch.LuceneProvider&quot;&gt;<br />
	  &lt;param hint=&quot;engine&quot; type=&quot;Sitecore.ContentSearch.LuceneProvider.Analyzers.XmlSynonymEngine, Sitecore.ContentSearch.LuceneProvider&quot;&gt;<br />
	    &lt;param hint=&quot;xmlSynonymFilePath&quot;&gt;C:\inetpub\wwwroot\yoursite\Data\synonyms.xml&lt;/param&gt;<br />
	  &lt;/param&gt;<br />
    &lt;/param&gt;<br />
  &lt;/param&gt;<br />
[/xml]</p>
<h2>Defining Synonyms in XML</h2>
<p>Now that you have the synonym analyzer configured to use your custom XML file, you need to use the following basic XML structure:</p>
<p>[xml]<br />
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;<br />
&lt;synonyms&gt;<br />
  &lt;group&gt;<br />
    &lt;syn&gt;fast&lt;/syn&gt;<br />
    &lt;syn&gt;quick&lt;/syn&gt;<br />
    &lt;syn&gt;rapid&lt;/syn&gt;<br />
  &lt;/group&gt;<br />
  &lt;group&gt;<br />
    &lt;syn&gt;slow&lt;/syn&gt;<br />
    &lt;syn&gt;decrease&lt;/syn&gt;<br />
  &lt;/group&gt;<br />
  &lt;group&gt;<br />
    &lt;syn&gt;google&lt;/syn&gt;<br />
    &lt;syn&gt;search&lt;/syn&gt;<br />
  &lt;/group&gt;<br />
  &lt;group&gt;<br />
    &lt;syn&gt;check&lt;/syn&gt;<br />
    &lt;syn&gt;lookup&lt;/syn&gt;<br />
    &lt;syn&gt;look&lt;/syn&gt;<br />
  &lt;/group&gt;<br />
&lt;/synonyms&gt;<br />
[/xml]</p>
<p>All terms listed in the same group are synonyms of each other. So for example, if a content item has the word &#8220;quick&#8221; in its CMS content but you search for the word &#8220;rapid&#8221; you will get that content item as a result.</p>
<h2>Understanding the Full Context of the Analyzer Configuration</h2>
<p>If you want to understand how this little piece fits into the overarching analyzer configuration, its actually quite impressive how Sitecore has abstracted so much to be configured:</p>
<ol>
<li>The overarching <code>&lt;analyzer&gt;</code> is the <code>PerExecutionContextAnalyzer</code> which is described on the <a href="http://www.sitecore.net/learn/blogs/technical-blogs/sitecore-7-development-team/posts/2013/08/execution-contexts-explained.aspx" target="_blank">Sitecore 7 Dev blog</a>. Its essentially a overarching &#8220;switcher analyzer&#8221; that allows a separate analyzer to be used per context.</li>
<li>That analyzer takes a default analyzer and a mapping which can map unique analyzers per culture (also described in the same post above). If the culture matches a mapped analyzer it will use it, otherwise it will fall back to the default analyzer.</li>
<li>The default analyzer is the <code>DefaultPerFieldAnalyzer</code> which looks at the same config file below for field-specific analyzers in the <code>&lt;fieldMap&gt;</code> section.</li>
<li>It too has a default analyzer in the case that an individual field doesn&#8217;t have a specific analyzer set. This default analyzer is now our new <code>SynonymAnalyzer</code> which is the final fall back scenario.</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://firebreaksice.com/sitecore-synonym-search-with-lucene/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
	</channel>
</rss>
