tag:blogger.com,1999:blog-47047044870408802402024-03-12T21:14:47.054-04:00Craig on SitecoreArchitecting Sitecore like it's my job.Unknownnoreply@blogger.comBlogger39125tag:blogger.com,1999:blog-4704704487040880240.post-5379722910722566942023-11-28T20:11:00.034-05:002023-11-28T22:26:46.327-05:00Should I Stay or Should I Go? Why not both?: Planning your Sitecore XM Cloud Migration<head>
<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBpi3SHpN4Y8XFF8K_sHuCRq-HA2HOiXTBfRnbf1ZPJIkCIJqDTk8SMnuHFWhOt0o6yQ6QX0cbxcdHCExCsJSBgi7rXUCOFroEcjcPR9KKqRTJyBncEZ2FmAbcUFkLW7kKmvEvbtBmP8AOyBJxWzYaKkdw5SGI08UYaZSjp1_oDUrzXF66HYFfSbGs/s1024/planning-your-sitecore-xm-cloud-migration.jpg" name="twitter:image"></meta>
</head>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBpi3SHpN4Y8XFF8K_sHuCRq-HA2HOiXTBfRnbf1ZPJIkCIJqDTk8SMnuHFWhOt0o6yQ6QX0cbxcdHCExCsJSBgi7rXUCOFroEcjcPR9KKqRTJyBncEZ2FmAbcUFkLW7kKmvEvbtBmP8AOyBJxWzYaKkdw5SGI08UYaZSjp1_oDUrzXF66HYFfSbGs/s1024/planning-your-sitecore-xm-cloud-migration.jpg" style="margin-left: 1em; margin-right: 1em;" title="Should I Stay or Should I Go? Why not both?: Planning your Sitecore XM Cloud Migration. Thanks for the image Bing AI!"><img alt="Should I Stay or Should I Go? Why not both?: Planning your Sitecore XM Cloud Migration" border="0" data-original-height="1024" data-original-width="1024" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBpi3SHpN4Y8XFF8K_sHuCRq-HA2HOiXTBfRnbf1ZPJIkCIJqDTk8SMnuHFWhOt0o6yQ6QX0cbxcdHCExCsJSBgi7rXUCOFroEcjcPR9KKqRTJyBncEZ2FmAbcUFkLW7kKmvEvbtBmP8AOyBJxWzYaKkdw5SGI08UYaZSjp1_oDUrzXF66HYFfSbGs/s320/planning-your-sitecore-xm-cloud-migration.jpg" title="Should I Stay or Should I Go? Why not both?: Planning your Sitecore XM Cloud Migration" width="320" /></a></div><br />
<br /><h3 style="text-align: left;">Should I Stay or Should I Go?</h3><div>In the <a href="https://www.craigtaylor.us/2023/10/key-considerations-before-migrating-to-sitecore-xm-cloud.html" target="_blank">last episode</a>, I discussed a crossroads decision point that businesses often find themselves in: stay with an establish platform like Sitecore XP, or migrate to Sitecore XM Cloud. Stuck between two giants in the digital platform space? What if I told you there's a third, equally formidable option? Let me introduce it: both.</div><div><br /></div><div>
<h3 style="text-align: left;">Why Not Both?</h3>
<div><div>Hear me out. Migrating to XM Cloud can be a serious undertaking. As I <a href="https://www.craigtaylor.us/2023/10/key-considerations-before-migrating-to-sitecore-xm-cloud.html" target="_blank">previously suggested</a>, in addition to re-architecting the website and every component, you may want to consider a complete redesign as well. This can be a large pill to swallow for many organizations that haven't already planned for such an expense. A 'dot' upgrade is one thing, but re-architecture, redesign, and redevelopment is much more involved.</div><div><br /></div><div>What if there was a way to migrate to XM Cloud over time as your budget and capacity allows? Well, there is. On a recently-launched client project, the client wanted to move to XM Cloud quickly, but didn't have the appropriate budget for the year and didn't want to wait for a 'big bang' at the end of long design and development cycles. As it turns out, Microsoft has a solution we can incorporate to address this issue.</div></div><div><br /></div>
<div><h3>Hello Azure Front Door, you had me at . . . Hello</h3><div><div><a href="https://azure.microsoft.com/en-us/products/frontdoor" target="_blank">Azure Front Door</a> is many things, but if you wanted to simplify it for easy comprehension: it's an entry point to your domain. When incorporated, all traffic for your domain gets routed through Azure Front Door and then rules are executed against the incoming request to match for specific patterns. The patterns to match could be from the request path, the domain, the protocol, geo-location, etc.. Actions are assigned to the rule and a match can direct traffic to multiple endpoints (origins).</div><div><br /></div><div>In the case of our client, we helped them develop a prioritized list of pages to migrate to XM Cloud immediately, and over time we will eventually migrate all approved pages to XM Cloud. The prioritization process involves determining which pages we will keep, which we will modify, and which we will eliminate from the new site. The pages that were not prioritized to move to XM Cloud will continue to live on the Sitecore XP platform as-is. In our case, we modified the XP header and footer to more closely match the header and footer of the newly-designed site to not cause total shock when navigating from XM Cloud to XP pages, but no changes are required to make the XP pages work just as they always have.</div><div><br /></div><div>When Azure Front Door fields a request for the domain, it is processed by a ruleset. Our rules were configured to look for the XM Cloud pages. If the pattern of the incoming request matches a pattern for a page on the new XM Cloud site, it is directed to the XM Cloud origin. When it does not match, Front Door passes the entire request through to the XP origin. This can all happen using the same domain name so that your users aren't confused.</div><div><br /></div><div>In this way, we have achieved running both versions of Sitecore concurrently and can complete redesign and redevelopment of the remaining portions of the site as budget and time allow!</div></div></div><div><br /></div><div><h3 style="text-align: left;">Gotchas?</h3><div>Oh yeah, there are some gotchas, of course.</div><div><br /></div><div>Depending on how many pages you want to divert to one origin or another, Azure Front Door will handle it gracefully or it will start to choke. Front Door starts to break down as you approach the limit for routing rules. (25 for Standard tier or 50 for the Premium tier) This may sound like plenty, but if you happen to have some redirects in addition to the routing, or want to handle http vs https differently, these add up quickly. What helps here is that you can apply many patterns within a single rule when matching. For example: if the rule states that anyting matching your patterns should just forward on the same request path to the origin specified, you can bundle many patterns together to perform the same action. So if you're clever with how you match and how you redirect, this may not be too much of a limitation, but it's still something to look out for.</div><div><br /></div><div>Running Sitecore XP and XM Cloud alongside each other is going to have some cost concerns. You're essentially running two websites, with two licenses, with hosting for two sites at the same time. While running both alongside each other will allow you to dip your toes in the water, you may drop your wallet in the lake too.</div><div><br /></div><h3 style="text-align: left;">Conclusion</h3><div>The decision to upgrade your Sitecore implementation to the latest version of XP or migrate to Sitecore XM Cloud is an important one. You may have thought those were the only two options, but you now you have (at least) one more option. Operating both platforms simultaneously can help get your organization moving towards the Cloud at their own pace. Understand the pros and cons of the options before jumping in is essential to ensure that you're making the right decision for your organization or client.</div></div><div><br /></div><h4 style="text-align: left;"><br /></h4></div><div><div>
<head>
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "BlogPosting",
"headline" : "Should I Stay or Should I Go? Why not both?: Planning your Sitecore XM Cloud Migration",
"image" : "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBpi3SHpN4Y8XFF8K_sHuCRq-HA2HOiXTBfRnbf1ZPJIkCIJqDTk8SMnuHFWhOt0o6yQ6QX0cbxcdHCExCsJSBgi7rXUCOFroEcjcPR9KKqRTJyBncEZ2FmAbcUFkLW7kKmvEvbtBmP8AOyBJxWzYaKkdw5SGI08UYaZSjp1_oDUrzXF66HYFfSbGs/s1024/planning-your-sitecore-xm-cloud-migration.jpg",
"url" : "https://www.craigtaylor.us/2023/11/planning-your-xm-cloud-migration.html",
"publisher": {
"@type": "Organization",
"name": "Craig Taylor",
"url": "https://www.craigtaylor.us",
"logo": {
"@type": "ImageObject",
"url": "http://www.example.com/logo.png",
"width":"400",
"height":"55"
}
},
"author" : {
"@type" : "Person",
"name" : "Craig Taylor"
},
"dateCreated" : "2023-11-28",
"datePublished" : "2023-11-28",
"dateModified" : "2023-11-28",
"inLanguage" : "en-US",
"mainEntityOfPage": "True",
"articleBody" : "Should I Stay or Should I Go?In the last episode, I discussed a crossroads decision point that businesses often find themselves in: stay with an establish platform like Sitecore XP, or migrate to Sitecore XM Cloud. Stuck between two giants? What if I told you there's a third, equally formidable option? Let me introduce it: both.Door Number Three Hear me out. Migrating to XM Cloud can be a serious undertaking. As I previously suggested, in addition to re-architecting the website and every component, you may want to consider a complete redesign as well. This can be a large pill to swallow for many organizations that haven't already planned for such an expense. A 'dot' upgrade is one thing, but re-architecture, redesign, and redevelopment is much more involved.What if there was a way to migrate XM Cloud over time as your budget and capacity allows? Well, there is. On a recently client project, the client wanted to move to XM Cloud quickly, but didn't have the appropriate budget for the year and didn't want to wait for a 'big bang' at the end of long design and development cycles. Microsoft had a solution we could incorporate.Hello Azure Front Door, you had me at . . . HelloAzure Front Door is many things, but if you wanted to simplify it for easier comprehension: it's an entry point to your domain. All traffic for your domain gets routed through Azure Front Door and then rules are executed against the request. Actions are assigned to the rule and the results can direct traffic to multiple endpoints (origins).In the case of our client, we helped them develop a prioritized list of pages to migrate to XM Cloud now, and over time we will eventually migrate all selected pages to XM Cloud. The prioritization process involves determining which pages we will keep, which we will modify, and which we will eliminate from the new site. The pages that were not prioritized continue to live on Sitecore XP as-is (with a minor tweak to more closely match the header and footer of the newly-designed site). When Azure Front Door fields a request for the domain, it is compared to the list of rules. If the pattern of the incoming request matches a pattern for a page on the new XM Cloud site, it is directed to the XM Cloud origin. When it does not match, Front Door passes the entire request through to the XP origin.In this way, we have achieved running both versions of Sitecore concurrently and can complete redesign and redevelopment of the remaining portions of the site as budget and time allows.Gotchas?Oh yeah, there are some gotchas, of course.Depending on how many pages you want to divert to one origin or another, Azure Front Door will handle it gracefully or it will start to choke. Front Door starts to break down as you approach the limit for routing rules. (25 for Standard tier or 50 for the Premium tier) This may sound like plenty, but if you happen to have some redirects, or want to handle http differently than https, these add up quickly. What helps here is that you can apply many patterns within a single rule to match your patterns. So if you're clever with how you match and how you redirect, this may not be too much of a limitation, but it's still something to look out for.Running Sitecore XP and XM Cloud alongside each other is going to have some licensing concerns. You're essentially running two websites, with two licenses, with hosting for two sites at the same time. While running both alongside each other will allow you to dip your toes in the water, you may drop your wallet in the lake too.ConclusionThe decision to upgrade your Sitecore implementation or migrate your entire site to Sitecore XM Cloud is an important one. You may have thought those were the only two options, but you now you have (at least) one more option. Operating both platforms simultaneously can help get your organization moving towards the Cloud at their own pace. Understand the pros and cons going of the options to ensure that you're making the right decision for your organization or client."
}
</script>
</head>
</div></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-61822665963325684022023-10-31T11:31:00.005-04:002023-11-28T20:12:47.019-05:00Crossroads: Animal House or Sit Tight: Key Considerations Before Migrating to Sitecore XM Cloud<head>
<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJ0CibUJhJx7gz2lJn90Z9jtSYF04D4e8Qvcqs9UIjYarWCpaW9-EE2bNaXvnry-XGFwgIgdysDJAKK0Z1l5tnb2RpY6XdAOzCUdxAH7yPdG31khzi7eIEi_CptI9w57VZQv_4DGZ8E4794Wh10hUqmSScbi86d4UWwNHsPpJivUURTK8NMLM0VTuc/s929/ivan-aleksic-8QgQnUhYs7w-unsplash.jpg" name="twitter:image"></meta>
</head>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJ0CibUJhJx7gz2lJn90Z9jtSYF04D4e8Qvcqs9UIjYarWCpaW9-EE2bNaXvnry-XGFwgIgdysDJAKK0Z1l5tnb2RpY6XdAOzCUdxAH7yPdG31khzi7eIEi_CptI9w57VZQv_4DGZ8E4794Wh10hUqmSScbi86d4UWwNHsPpJivUURTK8NMLM0VTuc/s929/ivan-aleksic-8QgQnUhYs7w-unsplash.jpg" style="margin-left: 1em; margin-right: 1em;" title="Crossroads: Animal House or Sit Tight: Key Considerations Before Migrating to Sitecore XM Cloud. Photo by Ivan Aleksic (https://unsplash.com/@ivalex) on Unsplash"><img alt="Crossroads: Animal House or Sit Tight: Key Considerations Before Migrating to Sitecore XM Cloud" border="0" data-original-height="929" data-original-width="640" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJ0CibUJhJx7gz2lJn90Z9jtSYF04D4e8Qvcqs9UIjYarWCpaW9-EE2bNaXvnry-XGFwgIgdysDJAKK0Z1l5tnb2RpY6XdAOzCUdxAH7yPdG31khzi7eIEi_CptI9w57VZQv_4DGZ8E4794Wh10hUqmSScbi86d4UWwNHsPpJivUURTK8NMLM0VTuc/s320/ivan-aleksic-8QgQnUhYs7w-unsplash.jpg" title="Crossroads: Animal House or Sit Tight: Key Considerations Before Migrating to Sitecore XM Cloud." width="220" /></a></div><br />
<br /><h3 style="text-align: left;">Crossroads</h3><div><div>As Sitecore XM Cloud gains more traction in the market, businesses often find themselves at a crossroads, contemplating a shift from established solutions like Sitecore XP to more modern platforms like Sitecore XM Cloud. While the promise of enhanced scalability, flexibility, and performance is alluring and you may want to charge in like Bluto from <i><a href="https://www.amazon.com/National-Lampoons-Animal-Widescreen-Probation/dp/B0000A02TZ/ref=sr_1_2?crid=2EG20JKP9NIV8&keywords=animal+house+movie&qid=1698764353&sprefix=animal+house+movie%252Caps%252C80&sr=8-2&_encoding=UTF8&tag=craigtfromatl-20&linkCode=ur2&linkId=227d31be6b4de99d87c05da724ea2a41&camp=1789&creative=9325" target="_blank">Animal House</a></i>, but it's crucial to tread carefully and consider various factors before making such a significant transition. </div><div><br /></div><div>Do you go ahead and go all-in on Saas and XM Cloud, or do you continue down your path of upgrades and traditional Sitecore XP? Let's explore some key considerations that can impact the success of your move to Sitecore XM Cloud.</div><div><br /></div><h4 style="text-align: left;">Cost Analysis: Licensing and Hardware</h4><div>Shifting to Sitecore XM Cloud involves not only licensing changes but also considerations regarding the underlying hardware infrastructure. Assess the financial implications of this transition by comparing licensing costs and evaluating whether your existing hardware is compatible with the cloud-based architecture. A key selling point of any SaaS platform is the savings on infrastructure, but your (or your client's) organization may have infrastructure that will continue to live on in the future platform. It's vital to have a clear understanding of the long-term cost implications and potential return on investment.</div><div><br /></div><h4 style="text-align: left;">Skillset Evaluation: Backend vs. Front-end Development</h4><div><a href="https://www.craigtaylor.us/2023/09/the-evolution-of-sitecore-development.html" target="_blank">We already discussed cheese, I mean, the rise of the Sitecore frontend developers</a>, in my last post, but Sitecore XM Cloud embraces a more modern approach, often requiring expertise in front-end technologies such as React and Next.js. Assess the skillset of the existing team; if the developers are predominantly C# backend experts, you may need to invest in upskilling or hiring front-end developers to ensure a smooth transition. Frontend tech is no joke; some might say it never was, but it's not 'just' HTML and CSS. Bridging this skills gap is critical for the successful implementation of a headless site based on Sitecore XM Cloud.</div><div><br /></div><h4 style="text-align: left;">Site Redesign Considerations</h4><div>Shifting to Sitecore XM Cloud will necessitate a reimagining of your website's architecture. The move towards a headless architecture means that every component must be re-developed to align with the new paradigm. There are ways to make this migration to headless in more of a piecemeal manner, but there are defintely cost implications. </div><div><br /></div><div>While you're at it: How's that design holding up? If you're re-developing every component, perhaps it's a chance to redesign as well. It's a chance to not only adopt a new platform but also to enhance the overall user experience with a fresh design.</div><div><br /></div><div>Evaluate whether your organization is prepared for a full site re-architecture and potential site redesign, taking into account the time, resources, and potential disruption to ongoing operations. </div><div><br /></div><h4 style="text-align: left;">Content Strategy and Migration</h4><div>Consider how your current content strategy aligns with the capabilities of Sitecore XM Cloud. The shift might require a comprehensive content migration plan, ensuring that your existing assets seamlessly integrate with the new platform. If you've made the decision to re-develop and re-design, does your content need some attention too? Plan on a comprehensive content audit to determine what content you keep, what content you update, what content you kill. Evaluate the tools and processes available for content migration and factor in the time and effort required for this crucial aspect of the transition.</div><div><br /></div><div><h3 style="text-align: left;">LET'S GO!!</h3></div><div><div class="tenor-gif-embed" data-aspect-ratio="1.75419" data-postid="14294436" data-share-method="host" data-width="100%"><a href="https://tenor.com/view/inspiration-animal-house-bluto-lets-go-lets-do-it-gif-14294436">Inspiration Animal House GIF</a>from <a href="https://tenor.com/search/inspiration-gifs">Inspiration GIFs</a></div> <script async="" src="https://tenor.com/embed.js" type="text/javascript"></script></div><div><br /></div><div>Transitioning from Sitecore XP to Sitecore XM Cloud holds the promise of a more scalable, flexible, and modern digital experience platform. However, success in this journey requires careful consideration of costs, skillset gaps, the need for a site redevelopment (and optionally, redesign), and content audit/content migration. </div><div><br /></div><div>In the end, you may decide that your organization or client is not yet prepared for the investment to move to XM Cloud and you need to sit tight. You may need more time to gain stakeholder support or budget or maybe you're considering dipping your toes into the water instead of jumping in, à la <i><a href="https://www.amazon.com/National-Lampoons-Animal-Widescreen-Probation/dp/B0000A02TZ/ref=sr_1_2?crid=2EG20JKP9NIV8&keywords=animal+house+movie&qid=1698764353&sprefix=animal+house+movie%252Caps%252C80&sr=8-2&_encoding=UTF8&tag=craigtfromatl-20&linkCode=ur2&linkId=227d31be6b4de99d87c05da724ea2a41&camp=1789&creative=9325" target="_blank">Animal House</a></i>. I suspect that all organizations will eventually be forced into the SaaS platform model to retain full support, but but by understanding and addressing these considerations thoughtfully, you can make plans for a successful quick or measured transformation that maximizes the benefits of Sitecore XM Cloud while minimizing potential challenges.</div></div><div><div>
<head>
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "BlogPosting",
"headline" : "Crossroads: Animal House or Sit Tight: Key Considerations Before Migrating to Sitecore XM Cloud",
"image" : "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJ0CibUJhJx7gz2lJn90Z9jtSYF04D4e8Qvcqs9UIjYarWCpaW9-EE2bNaXvnry-XGFwgIgdysDJAKK0Z1l5tnb2RpY6XdAOzCUdxAH7yPdG31khzi7eIEi_CptI9w57VZQv_4DGZ8E4794Wh10hUqmSScbi86d4UWwNHsPpJivUURTK8NMLM0VTuc/s929/ivan-aleksic-8QgQnUhYs7w-unsplash.jpg",
"url" : "https://www.craigtaylor.us/2023/10/key-considerations-before-migrating-to-sitecore-xm-cloud.html",
"publisher": {
"@type": "Organization",
"name": "Craig Taylor",
"url": "https://www.craigtaylor.us",
"logo": {
"@type": "ImageObject",
"url": "http://www.example.com/logo.png",
"width":"400",
"height":"55"
}
},
"author" : {
"@type" : "Person",
"name" : "Craig Taylor"
},
"dateCreated" : "2023-10-31",
"datePublished" : "2023-10-31",
"dateModified" : "2023-10-31",
"inLanguage" : "en-US",
"mainEntityOfPage": "True",
"articleBody" : "CrossroadsAs Sitecore XM Cloud gains more traction in the market, businesses often find themselves at a crossroads, contemplating a shift from established solutions like Sitecore XP to more modern platforms like Sitecore XM Cloud. While the promise of enhanced scalability, flexibility, and performance is alluring and you may want to charge in like Bluto from Animal House, but it's crucial to tread carefully and consider various factors before making such a significant transition.Do you go ahead and go all-in on Saas and XM Cloud, or do you continue down your path of upgrades and traditional Sitecore XP? Let's explore some key considerations that can impact the success of your move to Sitecore XM Cloud.Cost Analysis: Licensing and HardwareShifting to Sitecore XM Cloud involves not only licensing changes but also considerations regarding the underlying hardware infrastructure. Assess the financial implications of this transition by comparing licensing costs and evaluating whether your existing hardware is compatible with the cloud-based architecture. A key selling point of any SaaS platform is the savings on infrastructure, but your (or your client's) organization may have infrastructure that will continue to live on in the future platform. It's vital to have a clear understanding of the long-term cost implications and potential return on investment.Skillset Evaluation: Backend vs. Front-end DevelopmentWe already discussed cheese, I mean, the rise of the Sitecore frontend developers, in my last post, but Sitecore XM Cloud embraces a more modern approach, often requiring expertise in front-end technologies such as React and Next.js. Assess the skillset of the existing team; if the developers are predominantly C# backend experts, you may need to invest in upskilling or hiring front-end developers to ensure a smooth transition. Frontend tech is no joke; some might say it never was, but it's not 'just' HTML and CSS. Bridging this skills gap is critical for the successful implementation of a headless site based on Sitecore XM Cloud.Site Redesign ConsiderationsShifting to Sitecore XM Cloud will necessitate a reimagining of your website's architecture. The move towards a headless architecture means that every component must be re-developed to align with the new paradigm. There are ways to make this migration to headless in more of a piecemeal manner, but there are defintely cost implications.While you're at it: How's that design holding up? If you're re-developing every component, perhaps it's a chance to redesign as well. It's a chance to not only adopt a new platform but also to enhance the overall user experience with a fresh design.Evaluate whether your organization is prepared for a full site re-architecture and potential site redesign, taking into account the time, resources, and potential disruption to ongoing operations.Content Strategy and MigrationConsider how your current content strategy aligns with the capabilities of Sitecore XM Cloud. The shift might require a comprehensive content migration plan, ensuring that your existing assets seamlessly integrate with the new platform. If you've made the decision to re-develop and re-design, does your content need some attention too? Plan on a comprehensive content audit to determine what content you keep, what content you update, what content you kill. Evaluate the tools and processes available for content migration and factor in the time and effort required for this crucial aspect of the transition.LET'S GO!!Inspiration Animal House GIFfrom Inspiration GIFs Transitioning from Sitecore XP to Sitecore XM Cloud holds the promise of a more scalable, flexible, and modern digital experience platform. However, success in this journey requires careful consideration of costs, skillset gaps, the need for a site redevelopment (and optionally, redesign), and content audit/content migration.In the end, you may decide that your organization or client is not yet prepared for the investment to move to XM Cloud and you need to sit tight. You may need more time to gain stakeholder support or budget or maybe you're considering dipping your toes into the water instead of jumping in, à la Animal House. I suspect that all organizations will eventually be forced into the SaaS platform model to retain full support, but but by understanding and addressing these considerations thoughtfully, you can make plans for a successful quick or measured transformation that maximizes the benefits of Sitecore XM Cloud while minimizing potential challenges."
}
</script>
</head>
</div></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-20792224770843764102023-09-15T13:48:00.023-04:002023-10-26T18:53:04.210-04:00The Evolution of Sitecore Development: Embracing SaaS, Front-End Expertise, and Cheese!<head>
<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicNIAfdMwwJH5Wx-2OfOaAjwpz0IQEBkBFJssgQrq8KYKEDcFk7DBd5gOWZfevzBcV-73o3w0LhlbvEAmeAlU9ERWaVw9BPjH7JwrgBoOisUila1zR0Xfi8xd3MS1WpgoIn8IYf5yFoWP-Qh9tbXSWhXy1kkW7fBma7t6wz9ANxvGvRG2mJJe-igHk/s1024/Embrace%20the%20change%20and%20cheese.jpg" name="twitter:image"></meta>
</head>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicNIAfdMwwJH5Wx-2OfOaAjwpz0IQEBkBFJssgQrq8KYKEDcFk7DBd5gOWZfevzBcV-73o3w0LhlbvEAmeAlU9ERWaVw9BPjH7JwrgBoOisUila1zR0Xfi8xd3MS1WpgoIn8IYf5yFoWP-Qh9tbXSWhXy1kkW7fBma7t6wz9ANxvGvRG2mJJe-igHk/s1024/Embrace%20the%20change%20and%20cheese.jpg" style="margin-left: 1em; margin-right: 1em;" title="The Evolution of Sitecore Development: Embracing SaaS, Front-End Expertise, and Cheese!"><img alt="The Evolution of Sitecore Development: Embracing SaaS, Front-End Expertise, and Cheese!" border="0" data-original-height="1024" data-original-width="1024" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicNIAfdMwwJH5Wx-2OfOaAjwpz0IQEBkBFJssgQrq8KYKEDcFk7DBd5gOWZfevzBcV-73o3w0LhlbvEAmeAlU9ERWaVw9BPjH7JwrgBoOisUila1zR0Xfi8xd3MS1WpgoIn8IYf5yFoWP-Qh9tbXSWhXy1kkW7fBma7t6wz9ANxvGvRG2mJJe-igHk/w320-h320/Embrace%20the%20change%20and%20cheese.jpg" title="The Evolution of Sitecore Development: Embracing SaaS, Front-End Expertise, and Cheese!" width="320" /></a></div>
<br /><h3 style="text-align: left;">Who Moved My Cheese?!</h3>In the ever-evolving landscape of web development, platforms like Sitecore have played a pivotal role in shaping digital experiences. Traditionally, Sitecore development has relied heavily on backend (usually C#) developers to craft Sitecore solutions. However, with the advent of Sitecore XM Cloud and the shift towards a Software as a Service (SaaS) model, the dynamics of Sitecore development are undergoing a significant transformation. <div><br /></div><div>I often introduce myself as an architect that has a background in Microsoft technologies, specifically C# and Sitecore. Moving the focus of Sitecore development towards frond-end technologies sounds like I'm putting myself and other backend devs out of work, but fear not, it doesn't have to be that way. I remember a time where people thought that the introduction of Visual Studio meant that the days were numbered for developers. You may be thinking now that the same is true when we talk about the evolution of Sitecore development. (well, if you're a backend developer, that is) </div><div><br /></div><div>What does this shift mean for traditional, backend Sitecore developers, the increasing importance of frontend developers, and the shift towards a more collaborative, product-focused approach? I'm glad you asked.<div><br /></div><h3 style="text-align: left;">The Shift to Sitecore XM Cloud</h3><div><div><ol style="text-align: left;"><li>Embrace Cheese, I mean, SaaS for Scalability<br />Sitecore XM Cloud represents a shift towards a cloud-based, scalable architecture. This move not only simplifies infrastructure management (aint nobody got time for that) but also opens new doors for collaboration between backend and frontend developers. The emphasis on SaaS allows for quicker deployment, reduced maintenance overhead, and a more seamless development process.<br /><br /></li><li>The Rise of Front-End Development in Sitecore</li><ul><li>React and Next.js Integration<br />We are flipping staffing models from staffing a 'bunch' of backend developers along with a 'few' frontend developers on its head. As Sitecore (and partners) embrace a more API-first approach, the need for proficient frontend developers has become more pronounced. React and Next.js have become integral components in the Sitecore development toolkit and frontend developers now play a crucial role in shaping the user interface and optimizing the overall user experience. We aren't forgetting about the backend devs as you will see below.<br /><br /></li><li>Enhanced Content Delivery<br />With a focus on content delivery to the frontend, Sitecore developers are transitioning from being solely backend experts to becoming well-versed in frontend technologies. This shift not only empowers developers to create more interactive and dynamic user interfaces but also facilitates a more collaborative development environment.</li></ul></ol><h3 style="text-align: left;">The Changing Role of Sitecore Developers</h3><ol style="text-align: left;"><li>From Code-Centric to Product-Centric</li><ul><li>Configuring Sitecore for Frontend Integration<br />Sitecore developers are no longer just coders; they are becoming product experts who understand the intricacies of configuring Sitecore to seamlessly integrate with frontend technologies. This involves mastering the art of content organization, personalization, and API configurations to ensure a smooth flow of data between the backend and frontend.<br /><br /></li><li>Collaboration with Frontend Teams<br />The lines between backend and frontend development are blurring, and collaboration is key. Sitecore developers now work hand-in-hand with frontend teams, providing them with the necessary tools and data structures to bring digital experiences to life. We can move away from 'The front-end devs have to understand and run Sitecore on their machines' fallacy. Let's let front-end devs do what they do best. Let's let Sitecore experts do what they do best. Let's let them collaborate so they can build build great Sitecore sites. This collaboration fosters a more holistic approach to Sitecore development.</li></ul></ol></div><div><br /></div><h3 style="text-align: left;">Embrace the Cheese, I mean, Change</h3><div>The evolution of Sitecore development towards a SaaS model, particularly with Sitecore XM Cloud, marks a shift in the skills and expertise required to develop today's modern websites. While backend Sitecore developers will always be valuable, the demand for frontend developers with React and Next.js experience is on the rise. </div><div><br /></div><div>Sitecore developers are no longer confined to the backend; they are evolving into versatile product experts, bridging the gap between backend infrastructure and frontend innovation. We still need backend deveopers to help with the configuration of Sitecore, creation of Sitecore artifacts, devOps processes, integrations, search, gated content, etc. This transformation not only enhances the efficiency of development processes but also results in more dynamic and engaging digital experiences for end-users. </div><div><br /></div><div>As the world of Sitecore development continues to evolve, embracing this change is essential for staying at the forefront of digital innovation.</div><ol>
</ol>
<br /><h3>References:</h3><a href="https://www.amazon.com/Who-Moved-My-Cheese-Amazing/dp/0399144463/ref=sr_1_1?crid=MCDTFRN7E00P&keywords=who+moved+my+cheese&qid=1698335957&sprefix=who+moved+%252Caps%252C106&sr=8-1&_encoding=UTF8&tag=craigtfromatl-20&linkCode=ur2&linkId=bcd81b34e44e7aee5aeba115c245387a&camp=1789&creative=9325" target="_blank">Who Moved My Cheese</a> (We had a training session early in my career where we discussed this book and it's always in my head and I wonder if people look at me like I'm crazy when I mention it. The book is about embracing change. It talks about a mouse who is mad that his cheese has been moved and he can't let it go. Instead of focusing on that, embrace the change and learn how to operate while your cheese is in a new location. I hope this helps to explain why I keep referring to "cheese" in this post.)<br />
<br />
<br />
<head>
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "BlogPosting",
"headline" : "The Evolution of Sitecore Development: Embracing SaaS, Front-End Expertise, and Cheese!",
"image" : "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicNIAfdMwwJH5Wx-2OfOaAjwpz0IQEBkBFJssgQrq8KYKEDcFk7DBd5gOWZfevzBcV-73o3w0LhlbvEAmeAlU9ERWaVw9BPjH7JwrgBoOisUila1zR0Xfi8xd3MS1WpgoIn8IYf5yFoWP-Qh9tbXSWhXy1kkW7fBma7t6wz9ANxvGvRG2mJJe-igHk/s1024/Embrace%20the%20change%20and%20cheese.jpg",
"url" : "https://www.craigtaylor.us/2023/09/the-evolution-of-sitecore-development.html",
"publisher": {
"@type": "Organization",
"name": "Craig Taylor",
"url": "https://www.craigtaylor.us",
"logo": {
"@type": "ImageObject",
"url": "http://www.example.com/logo.png",
"width":"400",
"height":"55"
}
},
"author" : {
"@type" : "Person",
"name" : "Craig Taylor"
},
"dateCreated" : "2023-09-15",
"datePublished" : "2023-09-15",
"dateModified" : "2023-09-15",
"inLanguage" : "en-US",
"mainEntityOfPage": "True",
"articleBody" : "Who Moved My Cheese?!In the ever-evolving landscape of web development, platforms like Sitecore have played a pivotal role in shaping digital experiences. Traditionally, Sitecore development heavily relied on backend (usually C#) developers to craft Sitecore solutions. However, with the advent of Sitecore XM Cloud and the shift towards a Software as a Service (SaaS) model, the dynamics of Sitecore development are undergoing a significant transformation.I often introduce myself as an architect that has a background in Microsoft technologies, specifically C# and Sitecore. Moving the focus of Sitecore development towards frond-end technologies sounds like I'm putting myself and other backend devs out out work, but fear not, it doesn't have to be that way. I remember a time where people thought that the introduction of Visual Studio meant that the days were numbered for developers. You may be thinking now that the same is true when we talk about the evolution of Sitecore development. (well, if you're a backend developer, that is) What does this shift mean for traditional, backend Sitecore developers, the increasing importance of frontend developers, and the shift towards a more collaborative, product-focused approach? I'm glad you asked.The Shift to Sitecore XM CloudEmbrace Cheese, I mean, SaaS for ScalabilitySitecore XM Cloud represents a shift towards a cloud-based, scalable architecture. This move not only simplifies infrastructure management (aint nobody got time for that) but also opens new doors for collaboration between backend and frontend developers. The emphasis on SaaS allows for quicker deployment, reduced maintenance overhead, and a more seamless development process.The Rise of Front-End Development in SitecoreReact and Next.js IntegrationWe are flipping staffing models from staffing a 'bunch' of backend developers along with a 'few' frontend developers on its head. As Sitecore (and partners) embrace a more API-first approach, the need for proficient frontend developers has become more pronounced.React and Next.js have become integral components in the Sitecore development toolkit and frontend developers now play a crucial role in shaping the user interface and optimizing the overall user experience. We aren't forgetting about the backend devs as you will see below.Enhanced Content DeliveryWith a focus on content delivery to the frontend, Sitecore developers are transitioning from being solely backend experts to becoming well-versed in frontend technologies. This shift not only empowers developers to create more interactive and dynamic user interfaces but also facilitates a more collaborative development environment.The Changing Role of Sitecore DevelopersFrom Code-Centric to Product-CentricConfiguring Sitecore for Frontend IntegrationSitecore developers are no longer just coders; they are becoming product experts who understand the intricacies of configuring Sitecore to seamlessly integrate with frontend technologies. This involves mastering the art of content organization, personalization, and API configurations to ensure a smooth flow of data between the backend and frontend.Collaboration with Frontend TeamsThe lines between backend and frontend development are blurring, and collaboration is key. Sitecore developers now work hand-in-hand with frontend teams, providing them with the necessary tools and data structures to bring digital experiences to life. We can move away from 'The front-end devs have to understand and run Sitecore on their machines' fallacy. Let's let front-end devs do what they do best. Let's let Sitecore experts do what they do best. Let's let them collaborate so they can build build great Sitecore sites. This collaboration fosters a more holistic approach to Sitecore development.Embrace the Cheese, I mean, ChangeThe evolution of Sitecore development towards a SaaS model, particularly with Sitecore XM Cloud, marks a shift in the skills and expertise required to develop today's modern websites. While backend Sitecore developers will always be valuable, the demand for frontend developers with React and Next.js experience is on the rise.Sitecore developers are no longer confined to the backend; they are evolving into versatile product experts, bridging the gap between backend infrastructure and frontend innovation. We still need backend deveopers to help with the configuration of Sitecore, creation of Sitecore artifacts, devOps processes, integrations, search, gated content, etc. This transformation not only enhances the efficiency of development processes but also results in more dynamic and engaging digital experiences for end-users.As the world of Sitecore development continues to evolve, embracing this change is essential for staying at the forefront of digital innovation.References:Who Moved My Cheese (We had a training session early in my career where we discussed this book and it's always in my head and I wonder if people look at me like I'm crazy when I mention it. The book is about embracing change. It talks about a mouse who is mad that his cheese has been moved and he can't let it go. Instead of focusing on that, embrace the change and learn how to operate while your cheese is in a new location. I hope this helps to explain why I keep referring to cheese in this post.)"
}
</script>
</head>
</div></div>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4704704487040880240.post-3814028153772645172019-11-01T15:39:00.003-04:002019-11-01T16:22:47.839-04:00Syncing TDS content with Sitecore and the Field Content Does Not Match Content-Length Error<head>
<meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv0En0vW9FENxeS7dvO2UFe0eul__EW8MSMzblfeb4OwYOIFWsCI9Efh4X0Sgh534K5Q8LZgtEglKjFMrKDYUecIO1UvQATU98O242GwuW12z0OZ_WhCc4geSlpjLur5FGSSm41uDLmA/s1600/syncing.png" />
</head>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv0En0vW9FENxeS7dvO2UFe0eul__EW8MSMzblfeb4OwYOIFWsCI9Efh4X0Sgh534K5Q8LZgtEglKjFMrKDYUecIO1UvQATU98O242GwuW12z0OZ_WhCc4geSlpjLur5FGSSm41uDLmA/s1600/syncing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Syncing TDS content with Sitecore and the Field Content Does Not Match Content-Length Error"><img alt="Syncing TDS content with Sitecore and the Field Content Does Not Match Content-Length Error" border="0" data-original-height="640" data-original-width="640" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv0En0vW9FENxeS7dvO2UFe0eul__EW8MSMzblfeb4OwYOIFWsCI9Efh4X0Sgh534K5Q8LZgtEglKjFMrKDYUecIO1UvQATU98O242GwuW12z0OZ_WhCc4geSlpjLur5FGSSm41uDLmA/s320/syncing.png" width="320" /></a></div>
So I recently ran into an issue on a new-to-me project. The solution was already created, the project team had moved on to other projects and I was tasked with getting a new team ready to make some enhancements. While attempting to sync my Sitecore content with my local instance, I received a TDS error stating:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguvJooN73S1B6noZOKq2IPFvc3yB0cqj6yDMKEKYqFd_VbJ9gZFJ2V_qJ4j6aXRa-HiaQdTl68tpquaiFo74a0eTAGUaBTrFjmBd3OyvqfAwAS36sy-_PBkRoL5yls-C6NZdLHmXAFxw/s1600/TDS_Error.png" imageanchor="1" title="TDS Content Length Error"><img alt="TDS Content Length Error" border="0" data-original-height="271" data-original-width="472" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguvJooN73S1B6noZOKq2IPFvc3yB0cqj6yDMKEKYqFd_VbJ9gZFJ2V_qJ4j6aXRa-HiaQdTl68tpquaiFo74a0eTAGUaBTrFjmBd3OyvqfAwAS36sy-_PBkRoL5yls-C6NZdLHmXAFxw/s1600/TDS_Error.png" /></a></div>
<br />
<script src="https://gist.github.com/craigtfromatl/970945cac8e84600670d34f473bec37a.js"></script><br />
This is a known issue when working with TDS and git and the solution to correcting this has been provided earlier by others <a href="https://medium.com/sitecore-tips-tricks/deploying-sitecore-items-with-git-and-tds-f6a47605d1b4" target="_blank">here</a> and <a href="https://www.coreysmith.co/hedgehog-tds-field-content-does-not-match-content-length" target="_blank">here</a>. In summary, the solution is to update the .gitattributes file by adding a line with the following:<br />
<br />
<script src="https://gist.github.com/craigtfromatl/575f6ff79c8ef47296145fdfb57fdf50.js"></script><br />
This works great going forward, but doesn't address the issue you already have. As both articles mention, the solution is to delete your local TDS files and re-sync. For my situation, this doesn't work as I don't have the items in my local instance yet and deleting the items on disk would just lose them forever.<br />
<br />
The solve is rather manual in nature, but here is what I did:<br />
<br />
<ol>
<li style="padding-bottom: 10px;">Attempt to sync TDS with Sitecore and make note of all the items that have the error. In my example, I'm only showing a single line, but you may have many. (as I did before I took this screenshot)<br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF8LcA4Xf8mYSayIWH_YyV1AADAhUmvFNKVkezKZX23wFvLvnP1xxUWfSgfFw6Sbb-VgBBtoqy5atQDx06XbB7e7ZLnONwyngOuDc8_dIzwI9bEwbSEB8GTZ3g7cNj6W8R1YUIG6_EaA/s1600/Sync_View.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="TDS Sync View"><img alt="TDS Sync View" border="0" data-original-height="546" data-original-width="990" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF8LcA4Xf8mYSayIWH_YyV1AADAhUmvFNKVkezKZX23wFvLvnP1xxUWfSgfFw6Sbb-VgBBtoqy5atQDx06XbB7e7ZLnONwyngOuDc8_dIzwI9bEwbSEB8GTZ3g7cNj6W8R1YUIG6_EaA/s320/Sync_View.png" width="320" /></a></div>
</li>
<li style="padding-bottom: 10px;">Open the .item file in a text editor.</li>
<li style="padding-bottom: 10px;">Take note of the template type of the item and create a new item in Sitecore with the same type. (making sure to create the item with the same name/path as in the item file)</li>
<li style="padding-bottom: 10px;">Copy the relevant fields from the .item file and paste them into the proper fields in your new Sitecore item. In my case, I have an "Action" template item and only care about "Type", "Parameters" and "Security" fields. (Note: You don't have to worry about every field, but you should take care to bring over the important fields to your application. You can usually ignore fields like "_sortorder", "__owner", "__created", etc.)<br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiraZFkdt5ahc9ij3nIPzk3mfB1U-toOW45ypymCTwuLjSXS1YVB7w_kfhCBNieakNJuv6uQmLmCby7G-MpdA9zLrg4cnLuNvQ2Y_T7bghd958pDIm8PzjE4NBJjCGVf7cM7PhzxO9l_w/s1600/Item_View_Redacted.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Item View"><img alt="Item View" border="0" data-original-height="562" data-original-width="703" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiraZFkdt5ahc9ij3nIPzk3mfB1U-toOW45ypymCTwuLjSXS1YVB7w_kfhCBNieakNJuv6uQmLmCby7G-MpdA9zLrg4cnLuNvQ2Y_T7bghd958pDIm8PzjE4NBJjCGVf7cM7PhzxO9l_w/s320/Item_View_Redacted.png" width="320" /></a></div>
</li>
<li style="padding-bottom: 10px;">Save your Sitecore item.</li>
<li style="padding-bottom: 10px;">Sync your TDS item to Sitecore from Visual Studio.</li>
</ol>
<br />
Your error is now gone and you can continue on your way. As mentioned, this can become an extremely tedious process depending on how many items and how many fields you have on your items, but in my case, was a necessary evil. Someone smarter than me could probably develop a script of some kind to address the error on a larger scale, but I'll leave that to the aforementioned smarter people.<br />
<br />
<div>
<h3>
References:</h3>
Deploying Sitecore Items with Git and TDS (Hans Léautaud from 2014): <a href="https://medium.com/sitecore-tips-tricks/deploying-sitecore-items-with-git-and-tds-f6a47605d1b4" target="_blank">https://medium.com/sitecore-tips-tricks/deploying-sitecore-items-with-git-and-tds-f6a47605d1b4</a><br />
<br />
Hedgehog TDS - Field Content Does Not Match Content-Length (Corey Smith from 2016): <a href="https://www.coreysmith.co/hedgehog-tds-field-content-does-not-match-content-length/" target="_blank">https://www.coreysmith.co/hedgehog-tds-field-content-does-not-match-content-length/</a></div>
<head>
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "BlogPosting",
"headline" : "Syncing TDS content with Sitecore and the Field Content Does Not Match Content-Length Error",
"image" : "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv0En0vW9FENxeS7dvO2UFe0eul__EW8MSMzblfeb4OwYOIFWsCI9Efh4X0Sgh534K5Q8LZgtEglKjFMrKDYUecIO1UvQATU98O242GwuW12z0OZ_WhCc4geSlpjLur5FGSSm41uDLmA/s1600/syncing.png",
"url" : "https://www.craigtaylor.us/2019/11/syncing-tds-content-with-sitecore-error.html",
"publisher": {
"@type": "Organization",
"name": "Craig Taylor",
"url": "https://www.craigtaylor.us",
"logo": {
"@type": "ImageObject",
"url": "http://www.example.com/logo.png",
"width":"400",
"height":"55"
}
},
"author" : {
"@type" : "Person",
"name" : "Craig Taylor"
},
"dateCreated" : "2019-11-01",
"datePublished" : "2019-11-01",
"dateModified" : "2019-11-01",
"inLanguage" : "en-US",
"mainEntityOfPage": "True",
"articleBody" : "So I recently ran into an issue on a new-to-me project. The solution was already created, the project team had moved on to other projects and I was tasked with getting a new team ready to make some enhancements. While attempting to sync my Sitecore content with my local instance, I received a TDS error stating:<BR/>\n<BR/>\n<DIV class=\"separator\" style=\"clear: both; text-align: center;\">\n<A href=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguvJooN73S1B6noZOKq2IPFvc3yB0cqj6yDMKEKYqFd_VbJ9gZFJ2V_qJ4j6aXRa-HiaQdTl68tpquaiFo74a0eTAGUaBTrFjmBd3OyvqfAwAS36sy-_PBkRoL5yls-C6NZdLHmXAFxw/s1600/TDS_Error.png\" imageanchor=\"1\" title=\"TDS Content Length Error\" class=\"fancy\" data-fancybox-group=\"gallery\"><IMG alt=\"TDS Content Length Error\" border=\"0\" data-original-height=\"271\" data-original-width=\"472\" src=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguvJooN73S1B6noZOKq2IPFvc3yB0cqj6yDMKEKYqFd_VbJ9gZFJ2V_qJ4j6aXRa-HiaQdTl68tpquaiFo74a0eTAGUaBTrFjmBd3OyvqfAwAS36sy-_PBkRoL5yls-C6NZdLHmXAFxw/s1600/TDS_Error.png\"/></A></DIV>\n<BR/>\n<DIV id=\"gist99210248\" class=\"gist\">\n <DIV class=\"gist-file\">\n <DIV class=\"gist-data\">\n <DIV class=\"js-gist-file-update-container js-task-list-container file-box\">\n <DIV id=\"file-content-length-error-txt\" class=\"file\">\n \n\n <DIV itemprop=\"text\" class=\"Box-body p-0 blob-wrapper data type-text \">\n \n<TABLE class=\"highlight tab-size js-file-line-container\" data-tab-size=\"8\">\n <TBODY><TR>\n <TD id=\"file-content-length-error-txt-L1\" class=\"blob-num js-line-number\" data-line-number=\"1\"></TD>\n <TD id=\"file-content-length-error-txt-LC1\" class=\"blob-code blob-code-inner js-file-line\">An exception occurred while updating the sitecore item xxx. Error reading item: xxx Length of field content does not match the content-length attribute.</TD>\n </TR>\n</TBODY></TABLE>\n\n\n </DIV>\n\n </DIV>\n</DIV>\n\n </DIV>\n <DIV class=\"gist-meta\">\n <A href=\"https://gist.github.com/craigtfromatl/970945cac8e84600670d34f473bec37a/raw/1309623658c2deb23bf3142e3c0111e1781471cf/content-length-error.txt\" style=\"float:right\">view raw</A>\n <A href=\"https://gist.github.com/craigtfromatl/970945cac8e84600670d34f473bec37a#file-content-length-error-txt\">content-length-error.txt</A>\n hosted with ❤ by <A href=\"https://github.com\">GitHub</A>\n </DIV>\n </DIV>\n</DIV>\n<BR/>\nThis is a known issue when working with TDS and git and the solution to correcting this has been provided earlier by others <A href=\"https://medium.com/sitecore-tips-tricks/deploying-sitecore-items-with-git-and-tds-f6a47605d1b4\" target=\"_blank\">here</A> and <A href=\"https://www.coreysmith.co/hedgehog-tds-field-content-does-not-match-content-length\" target=\"_blank\">here</A>. In summary, the solution is to update the .gitattributes file by adding a line with the following:<BR/>\n<BR/>\n<DIV id=\"gist99210274\" class=\"gist\">\n <DIV class=\"gist-file\">\n <DIV class=\"gist-data\">\n <DIV class=\"js-gist-file-update-container js-task-list-container file-box\">\n <DIV id=\"file-item-txt\" class=\"file\">\n \n\n <DIV itemprop=\"text\" class=\"Box-body p-0 blob-wrapper data type-text \">\n \n<TABLE class=\"highlight tab-size js-file-line-container\" data-tab-size=\"8\">\n <TBODY><TR>\n <TD id=\"file-item-txt-L1\" class=\"blob-num js-line-number\" data-line-number=\"1\"></TD>\n <TD id=\"file-item-txt-LC1\" class=\"blob-code blob-code-inner js-file-line\">*.item -text</TD>\n </TR>\n</TBODY></TABLE>\n\n\n </DIV>\n\n </DIV>\n</DIV>\n\n </DIV>\n <DIV class=\"gist-meta\">\n <A href=\"https://gist.github.com/craigtfromatl/575f6ff79c8ef47296145fdfb57fdf50/raw/7bb15c8f13fb9d6ca27c0b81b246965e3e0c5f68/item.txt\" style=\"float:right\">view raw</A>\n <A href=\"https://gist.github.com/craigtfromatl/575f6ff79c8ef47296145fdfb57fdf50#file-item-txt\">item.txt</A>\n hosted with ❤ by <A href=\"https://github.com\">GitHub</A>\n </DIV>\n </DIV>\n</DIV>\n<BR/>\nThis works great going forward, but doesn't address the issue you already have. As both articles mention, the solution is to delete your local TDS files and re-sync. For my situation, this doesn't work as I don't have the items in my local instance yet and deleting the items on disk would just lose them forever.<BR/>\n<BR/>\nThe solve is rather manual in nature, but here is what I did:<BR/>\n<BR/>\n<OL>\n<LI style=\"padding-bottom: 10px;\">Attempt to sync TDS with Sitecore and make note of all the items that have the error. In my example, I'm only showing a single line, but you may have many. (as I did before I took this screenshot)<BR/><BR/>\n\n<DIV class=\"separator\" style=\"clear: both; text-align: center;\">\n<A href=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF8LcA4Xf8mYSayIWH_YyV1AADAhUmvFNKVkezKZX23wFvLvnP1xxUWfSgfFw6Sbb-VgBBtoqy5atQDx06XbB7e7ZLnONwyngOuDc8_dIzwI9bEwbSEB8GTZ3g7cNj6W8R1YUIG6_EaA/s1600/Sync_View.png\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\" title=\"TDS Sync View\" class=\"fancy\" data-fancybox-group=\"gallery\"><IMG alt=\"TDS Sync View\" border=\"0\" data-original-height=\"546\" data-original-width=\"990\" height=\"176\" src=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF8LcA4Xf8mYSayIWH_YyV1AADAhUmvFNKVkezKZX23wFvLvnP1xxUWfSgfFw6Sbb-VgBBtoqy5atQDx06XbB7e7ZLnONwyngOuDc8_dIzwI9bEwbSEB8GTZ3g7cNj6W8R1YUIG6_EaA/s320/Sync_View.png\" width=\"320\"/></A></DIV>\n</LI>\n<LI style=\"padding-bottom: 10px;\">Open the .item file in a text editor.</LI>\n<LI style=\"padding-bottom: 10px;\">Take note of the template type of the item and create a new item in Sitecore with the same type. (making sure to create the item with the same name/path as in the item file)</LI>\n<LI style=\"padding-bottom: 10px;\">Copy the relevant fields from the .item file and paste them into the proper fields in your new Sitecore item. In my case, I have an "Action" template item and only care about "Type", "Parameters" and "Security" fields. (Note: You don't have to worry about every field, but you should take care to bring over the important fields to your application. You can usually ignore fields like "_sortorder", "__owner", "__created", etc.)<BR/><BR/>\n\n<DIV class=\"separator\" style=\"clear: both; text-align: center;\">\n<A href=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiraZFkdt5ahc9ij3nIPzk3mfB1U-toOW45ypymCTwuLjSXS1YVB7w_kfhCBNieakNJuv6uQmLmCby7G-MpdA9zLrg4cnLuNvQ2Y_T7bghd958pDIm8PzjE4NBJjCGVf7cM7PhzxO9l_w/s1600/Item_View_Redacted.png\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\" title=\"Item View\" class=\"fancy\" data-fancybox-group=\"gallery\"><IMG alt=\"Item View\" border=\"0\" data-original-height=\"562\" data-original-width=\"703\" height=\"255\" src=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiraZFkdt5ahc9ij3nIPzk3mfB1U-toOW45ypymCTwuLjSXS1YVB7w_kfhCBNieakNJuv6uQmLmCby7G-MpdA9zLrg4cnLuNvQ2Y_T7bghd958pDIm8PzjE4NBJjCGVf7cM7PhzxO9l_w/s320/Item_View_Redacted.png\" width=\"320\"/></A></DIV>\n</LI>\n<LI style=\"padding-bottom: 10px;\">Save your Sitecore item.</LI>\n<LI style=\"padding-bottom: 10px;\">Sync your TDS item to Sitecore from Visual Studio.</LI>\n</OL>\n<BR/>\nYour error is now gone and you can continue on your way. As mentioned, this can become an extremely tedious process depending on how many items and how many fields you have on your items, but in my case, was a necessary evil. Someone smarter than me could probably develop a script of some kind to address the error on a larger scale, but I'll leave that to the aforementioned smarter people.<BR/>\n<BR/>\n<DIV>\n<H3>\nReferences:</H3>\nDeploying Sitecore Items with Git and TDS (Hans Léautaud from 2014): <A href=\"https://medium.com/sitecore-tips-tricks/deploying-sitecore-items-with-git-and-tds-f6a47605d1b4\" target=\"_blank\">https://medium.com/sitecore-tips-tricks/deploying-sitecore-items-with-git-and-tds-f6a47605d1b4</A><BR/>\n<BR/>\nHedgehog TDS - Field Content Does Not Match Content-Length (Corey Smith from"
}
</script>
</head>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-70376420743021655342019-09-10T13:07:00.001-04:002019-10-16T15:28:52.085-04:00Sitecore Roles PaaS Solr Connectivity<head>
<meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8PIq6LpJGB66M1SqTe8B-YfnFgRnvW2RK8ZvpqyTXycuETn7nuXplq6BxceJUYlQtQ1Enohyxhl3un5viABQjmpi4Uh59vTYuA1UUWMevupU32fmMWMLJCzHhcx1e78OTgG5rYiY9xg/s1600/sitecoresolr.jpg" />
</head>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8PIq6LpJGB66M1SqTe8B-YfnFgRnvW2RK8ZvpqyTXycuETn7nuXplq6BxceJUYlQtQ1Enohyxhl3un5viABQjmpi4Uh59vTYuA1UUWMevupU32fmMWMLJCzHhcx1e78OTgG5rYiY9xg/s1600/sitecoresolr.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Sitecore Roles PaaS Solr Connectivity"><img alt="Sitecore Roles PaaS Solr Connectivity" border="0" data-original-height="620" data-original-width="620" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8PIq6LpJGB66M1SqTe8B-YfnFgRnvW2RK8ZvpqyTXycuETn7nuXplq6BxceJUYlQtQ1Enohyxhl3un5viABQjmpi4Uh59vTYuA1UUWMevupU32fmMWMLJCzHhcx1e78OTgG5rYiY9xg/s320/sitecoresolr.jpg" width="320" /></a></div>
<br />
Here's a quick one for everyone. I recently provisioned a full Sitecore XP 9.0.1 environment in Azure PaaS. The only exception to this is a VM that is running Solr. I was getting a lot of errors in Application Insights about xConnect not being able to connect to the Solr server. I suspected that I was missing a <a href="https://docs.microsoft.com/en-us/azure/app-service/app-service-hybrid-connections" target="_blank">hybrid connection</a> somewhere, but wasn't sure which role was missing it.<br />
<br />
I couldn't find a list from Sitecore's <a href="https://doc.sitecore.com/developers/90/platform-administration-and-architecture/en/walkthrough--setting-up-solr.html" target="_blank">documentation</a> of all the roles that need to access Solr. I know that I could look for the "ContentSearch.Solr.ServiceBaseAddress" setting to find all references to my Solr server, so I downloaded all the config files from each Sitecore role and found the one I was missing (xConnect Search). I added the hybrid connection to the Solr server to my xConnect Search App Service and was back to running with no exceptions again!<br />
<br />
Note: The "ContentSearch.Solr.ServiceBaseAddress" setting was removed in Sitecore 9.0.2 and is now in the "solr.search" connection string.<br />
<br />
For reference, here are the 5 roles that should be able to communicate with Solr:<br />
<br />
<ul>
<li>Content Management</li>
<li>Content Delivery</li>
<li>Processing</li>
<li>Reporting</li>
<li>xConnect Search</li>
</ul>
<br />
<div>
<h3>
References:</h3>
Walkthrough - Install/Configure Solr: <a href="https://doc.sitecore.com/developers/90/platform-administration-and-architecture/en/walkthrough--setting-up-solr.html" target="_blank">https://doc.sitecore.com/developers/90/platform-administration-and-architecture/en/walkthrough--setting-up-solr.html</a><br />
<br />
Azure Hybrid Connections: <a href="https://docs.microsoft.com/en-us/azure/app-service/app-service-hybrid-connections" target="_blank">https://docs.microsoft.com/en-us/azure/app-service/app-service-hybrid-connections</a></div>
<head>
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "BlogPosting",
"headline" : "Sitecore Roles PaaS Solr Connectivity",
"image" : "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8PIq6LpJGB66M1SqTe8B-YfnFgRnvW2RK8ZvpqyTXycuETn7nuXplq6BxceJUYlQtQ1Enohyxhl3un5viABQjmpi4Uh59vTYuA1UUWMevupU32fmMWMLJCzHhcx1e78OTgG5rYiY9xg/s320/sitecoresolr.jpg",
"url" : "https://www.craigtaylor.us/2019/09/sitecore-roles-paas-solr-connectivity.html",
"publisher": {
"@type": "Organization",
"name": "Craig Taylor",
"url": "https://www.craigtaylor.us",
"logo": {
"@type": "ImageObject",
"url": "http://www.example.com/logo.png",
"width":"400",
"height":"55"
}
},
"author" : {
"@type" : "Person",
"name" : "Craig Taylor"
},
"dateCreated" : "2019-09-10",
"datePublished" : "2019-09-10",
"dateModified" : "2019-10-16",
"inLanguage" : "en-US",
"mainEntityOfPage": "True",
"articleBody" : "Here's a quick one for everyone. I recently provisioned a full Sitecore XP 9.0.1 environment in Azure PaaS. The only exception to this is a VM that is running Solr. I was getting a lot of errors in Application Insights about xConnect not being able to connect to the Solr server. I suspected that I was missing a <A href=\"https://docs.microsoft.com/en-us/azure/app-service/app-service-hybrid-connections\" target=\"_blank\">hybrid connection</A> somewhere, but wasn't sure which role was missing it.<BR/>\n<BR/>\nI couldn't find a list from Sitecore's <A href=\"https://doc.sitecore.com/developers/90/platform-administration-and-architecture/en/walkthrough--setting-up-solr.html\" target=\"_blank\">documentation</A> of all the roles that need to access Solr. I know that I could look for the "ContentSearch.Solr.ServiceBaseAddress" setting to find all references to my Solr server, so I downloaded all the config files from each Sitecore role and found the one I was missing (xConnect Search). I added the hybrid connection to the Solr server to my xConnect Search App Service and was back to running with no exceptions again!<BR/>\n<BR/>\nNote: The "ContentSearch.Solr.ServiceBaseAddress" setting was removed in Sitecore 9.0.2 and is now in the "solr.search" connection string.<BR/>\n<BR/>\nFor reference, here are the 5 roles that should be able to communicate with Solr:<BR/>\n<BR/>\n<UL>\n<LI>Content Management</LI>\n<LI>Content Delivery</LI>\n<LI>Processing</LI>\n<LI>Reporting</LI>\n<LI>xConnect Search</LI>\n</UL>\n<BR/>\n<DIV>\n<H3>\nReferences:</H3>\nWalkthrough - Install/Configure Solr: <A href=\"https://doc.sitecore.com/developers/90/platform-administration-and-architecture/en/walkthrough--setting-up-solr.html\" target=\"_blank\">https://doc.sitecore.com/developers/90/platform-administration-and-architecture/en/walkthrough--setting-up-solr.html</A><BR/>\n<BR/>\nAzure Hybrid Connections"
}
</script>
</head>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-255584653151322442019-04-12T10:13:00.002-04:002019-04-12T10:14:46.024-04:00Limit TreelistEx Selections to X Number of Items<head>
<meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4BkRRDHQ51ayZhS1tDWlNz05xA9lGM7e1wg_tIpzPlTW3efGFpeiwBCpsLFVyysz1Z9nTgvB8XpQ0dbz_ivBlasU4LszK4vuXdpGbrd5W3v3_tuILtsuKIP5JH7ysTiZDOdlg0EfW5A/s1600/SitecoreItemLimit.png" />
</head>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4BkRRDHQ51ayZhS1tDWlNz05xA9lGM7e1wg_tIpzPlTW3efGFpeiwBCpsLFVyysz1Z9nTgvB8XpQ0dbz_ivBlasU4LszK4vuXdpGbrd5W3v3_tuILtsuKIP5JH7ysTiZDOdlg0EfW5A/s1600/SitecoreItemLimit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Sitecore Item Limit"><img alt="Sitecore Item Limit" border="0" data-original-height="640" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4BkRRDHQ51ayZhS1tDWlNz05xA9lGM7e1wg_tIpzPlTW3efGFpeiwBCpsLFVyysz1Z9nTgvB8XpQ0dbz_ivBlasU4LszK4vuXdpGbrd5W3v3_tuILtsuKIP5JH7ysTiZDOdlg0EfW5A/s320/SitecoreItemLimit.png" /></a></div>
<br />
I recently had a requirement to limit the content author's ability to select items. In this case, they were only allowed to select two items. I love using "TreeListEx" and therefore selected that field type. I knew that I could set validation on fields and went about looking for the built-in validator that would limit the number of selections. . . I didn't find it.<br />
<br />
While I was surprised to not find this validator, I thought that surely, someone else smarter than me had mentioned it on the interwebs; I was not disappointed. A quick search yielded a <a href="https://sitecore.stackexchange.com/questions/1016/what-fieldtype-should-i-use-to-select-one-item-from-a-bucket" target="_blank">StackOverflow post</a> about it that cited a <a href="http://www.benramey.com/2012/06/12/limit-selected-items-on-sitecore-multilist-field/" target="_blank">blog post</a>. In summary, apply a Regex value to the "Validation" field of your field. (Add a helpful "ValidationText" message while you're at it.)<br />
<br />
I dutifully copied and pasted the Regex expression into my field and was a little surprised to see an error message while testing the validator:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG9W2tDP4QkT_QcYxzxinRhzfatpREM2k7Lmvxx_EomqEKyW1MgwADKceegJQu2iBHxE1EksgmaXnRhDzZZviwAQq5eoC8N-6uDj7W2v4a11uk40AkYJFwrYULfmSI1BLb2r_viKRrsw/s1600/ValidationError.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Sitecore Validation Error"><img alt="Sitecore Validation Error" border="0" data-original-height="218" data-original-width="639" height="109" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG9W2tDP4QkT_QcYxzxinRhzfatpREM2k7Lmvxx_EomqEKyW1MgwADKceegJQu2iBHxE1EksgmaXnRhDzZZviwAQq5eoC8N-6uDj7W2v4a11uk40AkYJFwrYULfmSI1BLb2r_viKRrsw/s320/ValidationError.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
Well, that didn't go as expected. After a bit of Internet sleuthing on the error, I found that there might be a character (or "characters") in the string that needs to be escaped. I simply changed "^({[^}]+}|?){0,2}$" to "^(\{[^}]+\}|\?){0,2}$" (included the escaping 'backslashes' before the curly brackets and question mark) and was on my way!<br />
<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnr10T3LKEBv7EtbSbVzjXydv7asqHQtDS_W708YlgqFp_bbrWZ-p_BLg2BHjtowFf8UTDSTQhICTF2gf7i4QpbKMzFRM8kip0kR0cQTYMN0i2yykAhefCtdwoCvP53NeT2D-jbYWQdQ/s1600/ValidationWorking.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Sitecore Validation Working"><img alt="Sitecore Validation Working" border="0" data-original-height="207" data-original-width="442" height="149" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnr10T3LKEBv7EtbSbVzjXydv7asqHQtDS_W708YlgqFp_bbrWZ-p_BLg2BHjtowFf8UTDSTQhICTF2gf7i4QpbKMzFRM8kip0kR0cQTYMN0i2yykAhefCtdwoCvP53NeT2D-jbYWQdQ/s320/ValidationWorking.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
<b>Update</b>: And of course as I'm finalizing the research for this post, I see that Ben *actually* did solve this and it can be seen in the screenshot he included, but the Regex text in his post didn't include the escape characters</div>
<br/>
<div>
<h3>
References:</h3>
Stack Overflow Post: <a href="https://sitecore.stackexchange.com/questions/1016/what-fieldtype-should-i-use-to-select-one-item-from-a-bucket" target="_blank">https://sitecore.stackexchange.com/questions/1016/what-fieldtype-should-i-use-to-select-one-item-from-a-bucket</a><br />
Ben Ramey's blog post cited in the SO post: <a href="http://www.benramey.com/2012/06/12/limit-selected-items-on-sitecore-multilist-field/" target="_blank">http://www.benramey.com/2012/06/12/limit-selected-items-on-sitecore-multilist-field/</a></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-4869156524373433592018-11-27T07:24:00.004-05:002018-11-27T07:24:45.236-05:00Sitecore CD Hardening via Release Deployments<head>
<meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmYWwzVVHE97g0BHKB-X43Ve3-3VsmH5vZEtFEbzQgC6OIasJu9j9Qo7oluUR5jmkzEdZd6claoLu42xmsXTu7zE9ZgvJlAyVEsTJPbRE8ADWI1JfIERNIyXaLbEtj42DyDJEyXE6rdw/s1600/SitecoreSecurity.jpg" />
</head>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmYWwzVVHE97g0BHKB-X43Ve3-3VsmH5vZEtFEbzQgC6OIasJu9j9Qo7oluUR5jmkzEdZd6claoLu42xmsXTu7zE9ZgvJlAyVEsTJPbRE8ADWI1JfIERNIyXaLbEtj42DyDJEyXE6rdw/s1600/SitecoreSecurity.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Sitecore CD Hardening via Release Deployments"><img alt="Sitecore CD Hardening via Release Deployments" border="0" data-original-height="426" data-original-width="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmYWwzVVHE97g0BHKB-X43Ve3-3VsmH5vZEtFEbzQgC6OIasJu9j9Qo7oluUR5jmkzEdZd6claoLu42xmsXTu7zE9ZgvJlAyVEsTJPbRE8ADWI1JfIERNIyXaLbEtj42DyDJEyXE6rdw/s320/SitecoreSecurity.jpg" /></a></div>
<br />
Security hardening on your CD servers is an absolute must. It should not be an afterthought and you should address it early so that you're not trying to cram it in just before go-live.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
In the days before automated deployments, CD hardening would involve manually manipulating the IIS folder level permissions on each CD server in your environments. With automated deployments, we can make this much easier!</div>
<br />
<h3>
Which Sitecore Version are We Deploying?</h3>
Take note of which version of Sitecore you are working with. Prior to Sitecore 8.2, Update 3, you are still limited to manipulating IIS folder level permissions. You can also handle this with configuration, but that's outside the scope of this post. With Sitecore 8.2, Update 3 and newer, we have the option of changing the forms authentication mode in order to secure the server.<br />
<br />
<h3>
Disable Forms Authentication</h3>
The simple way to disable access to your Sitecore interface is to change the authentication mode from "Forms" to "None" in your web.config:<br />
<br />
<script src="https://gist.github.com/craigtfromatl/c94e0564a95603f0fff9846606296757.js"></script><br />
Easy enough to do on each of your CD servers, right? But we want to automate that with our deployments.<br />
<br />
<h3>
Azure Devops and Web.config Tranforms</h3>
Using a web.config transform, we can target the "authentication" node and change the value to "None." <br />
<br />
<i>What about local development though? </i> <br />
<br />
When developing locally, you can use the "Debug" solution configuration that lets the web.config use the "Forms" setting when developing locally. This is exactly how Sitecore ships out of the box.<br />
<br />
Use the "Release" solution configuration to set a transform on that element to change it to a token value. Note: This assumes you are using the "Release" configuration when building your solution in Azure Devops (was VSTS). <br />
<br />
<i>Why a token value instead of just setting it to "None"? </i><br />
<br />
We are utilizing (mostly) clean deploys. When deploying, we wipe the web root and install all of Sitecore and our custom code and configuration from scratch. Additionally, we deploy the same set of files to every server. Different values for the tokens are controlled via variables and variable groups in Azure Devops. We expect this token value to be replaced at the time the release is generated and deployed to our different environments.<br /><br/>
<h3>
Putting it Together</h3>
So, we have a Web.Release.config file in our solution that looks like this:<br />
<br />
<script src="https://gist.github.com/craigtfromatl/dbf6a9981e1dc8c3cb35495b2b5d903d.js"></script><br />
In Azure Devops, we have a Variable Group for our CM servers that has the same "#{AuthenticationMode}" token with a value of "Forms":<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiim_QN7IGymW7iIbD8NxAIWVS1MkGzuoD4rTP23aBWGZWAqoUl8_jCmBxq_srLZeSZPDng2tebLM5tfM3HRN_T1zoMCCZqgy3V7inFEwqJLLUSt1OMT_Gim47llt7kwBwWg_sTT09YWA/s1600/CM_Server_Role_Variables.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Sitecore CM Server Role Variables"><img alt="Sitecore CM Server Role Variables" border="0" data-original-height="440" data-original-width="605" height="233" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiim_QN7IGymW7iIbD8NxAIWVS1MkGzuoD4rTP23aBWGZWAqoUl8_jCmBxq_srLZeSZPDng2tebLM5tfM3HRN_T1zoMCCZqgy3V7inFEwqJLLUSt1OMT_Gim47llt7kwBwWg_sTT09YWA/s320/CM_Server_Role_Variables.png" width="320" /></a></div>
<br />
<br />
Additionally, in Azure Devops, we have another Variable Group for our CD servers that has the "#{AuthenticationMode}" token with a value of "None":<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHTeTsuQJ7k69A3t0-NgzAmseYfWEOiSJlerynMnqf1HDx0MM0VcMGvotlAMkSQYRhs5xpquV0kGIz04Xnxd7JV5JEspgLJVulxkpL6yRQfVKdINhXUr_QE_PC7IlhL0G-J6OCOjDpTg/s1600/CD_Server_Role_Variables.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Sitecore CD Server Role Variables"><img alt="Sitecore CD Server Role Variables" border="0" data-original-height="437" data-original-width="600" height="233" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHTeTsuQJ7k69A3t0-NgzAmseYfWEOiSJlerynMnqf1HDx0MM0VcMGvotlAMkSQYRhs5xpquV0kGIz04Xnxd7JV5JEspgLJVulxkpL6yRQfVKdINhXUr_QE_PC7IlhL0G-J6OCOjDpTg/s320/CD_Server_Role_Variables.png" width="320" /></a></div>
<br />
<br />
When the release is built, use the <a href="https://marketplace.visualstudio.com/items?itemName=qetza.replacetokens" target="_blank">Replace Tokens</a> task in your release definition to process all your config files and replace the tokens with values from your Azure Deveops Variables Library.<br /><br/>
<h3>
Summary</h3>
Security hardening is an important task that shouldn't be overlooked and shouldn't be pushed to the end of your development cycle. Consider security early and keep yourself and your clients out of the news.<br />
<br />
<h3>
Additional Reading</h3>
Sitecore - <a href="https://doc.sitecore.net/sitecore_experience_platform/setting_up_and_maintaining/security_hardening/configuring/deny_anonymous_users_access_to_a_folder" target="_blank">Deny anonymous users access to a folder</a><br />
<br />
Sitecore - <a href="https://doc.sitecore.net/sitecore_experience_platform/81/setting_up_and_maintaining/security_and_administration/access_rights/restrict_access_to_the_client" target="_blank">Restrict access to the client</a><br />
<br />
Visual Studio Marketplace - <a href="https://marketplace.visualstudio.com/items?itemName=qetza.replacetokens" target="_blank">Replace Tokens Task</a><br />
<div>
<br /></div>
<div>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-36529086975271839402018-01-31T10:00:00.000-05:002018-02-13T12:41:23.651-05:00Craig Taylor Wins Sitecore "Most Valuable Professional" Award<head>
<meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudPaqgig_SuDyzNzZl8-tWXdoRXGkcC6U3hpo_QWtC5e2TeloJlL_3VghJ5UBfISfjyftNCPOyuh6wRGgpO_J1qNQLhAuucNBJdnDf1oaPy-WNqboy8EzcPPxlXbZ8hjFmzA6C23BEw/s1600/MVP2018.jpg" />
</head>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudPaqgig_SuDyzNzZl8-tWXdoRXGkcC6U3hpo_QWtC5e2TeloJlL_3VghJ5UBfISfjyftNCPOyuh6wRGgpO_J1qNQLhAuucNBJdnDf1oaPy-WNqboy8EzcPPxlXbZ8hjFmzA6C23BEw/s1600/MVP2018.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Craig Taylor wins Sitecore Most Valuable Professional Award"><img alt="Craig Taylor wins Sitecore Most Valuable Professional Award" border="0" data-original-height="200" data-original-width="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjudPaqgig_SuDyzNzZl8-tWXdoRXGkcC6U3hpo_QWtC5e2TeloJlL_3VghJ5UBfISfjyftNCPOyuh6wRGgpO_J1qNQLhAuucNBJdnDf1oaPy-WNqboy8EzcPPxlXbZ8hjFmzA6C23BEw/s1600/MVP2018.jpg" /></a></div>
<br />
<strong>Atlanta, GA — January, 31st, 2018 — </strong> <strong>Craig Taylor</strong> has been named a "Most Valuable Professional (MVP)" in the Technology category by <a href="http://www.sitecore.net/" rel="noopener" target="_blank">Sitecore</a>®, the global leader in experience management software. <strong>Craig</strong> was one of only 208 Technology MVPs worldwide to be named a Sitecore MVP this year.<br /><br />
Now it its 12th year, Sitecore's MVP program recognizes individual technology, strategy, and commerce advocates who share their Sitecore passion and expertise to offer positive customer experiences that drive business results. The Sitecore MVP Award recognizes the most active Sitecore experts from around the world who participate in online and offline communities to share their knowledge with other Sitecore partners and customers.<br /><br />
<blockquote>
<em><strong>I'm truly honored that Sitecore recognized me as an MVP in the Sitecore community for the fifth straight year! I'm surrounded by some amazingly talented co-workers at Avanade and supported by an amazing Sitecore community. I feel like I'm in great company and am continually pressed to keep the high standards demonstrated by the other Sitecore MVPs. (Craig Taylor, Sitecore Architect, Avanade Inc.)</strong></em></blockquote>
<br />
"The Sitecore MVP awards recognize and honor those individuals who make substantial contributions to our loyal community of partners and customers," said Pieter Brinkman, Sitecore Senior Director of Technical Marketing. "MVPs consistently set a standard of excellence by delivering technical chops, enthusiasm, and a commitment to giving back to the Sitecore community. They truly understand and deliver on the power of the Sitecore Experience Platform to create personalized brand experiences for their consumers, driving revenue and customer loyalty."<br /><br />
The Sitecore Experience Platform™ combines web content management, omnichannel digital delivery, insights into customer activity and engagement, and strategic digital marketing tools into a single, unified platform. Sitecore Experience Commerce™ 9, <a href="https://www.sitecore.com/company/press-and-media/press-releases/2018/01/new-sitecore-experience-commerce-9-allows-brands-to-individualize-the-end-to-end-customer-experience" rel="noopener" target="_blank">released in January 2018</a>, is the only cloud-enabled platform that natively integrates content and commerce so brands can fully personalize and individualize the end-to-end shopping experience before, during, and after the transaction. Both platforms capture in real time every minute interaction—and intention—that customers and prospects have with a brand across digital and offline channels. The result is that Sitecore customers are able to use the platform to engage with prospects and customers in a highly personalized manner, earning long-term customer loyalty.<br /><br />
<blockquote>
<strong><em>Craig is a five time Sitecore Technology MVP and is a skilled, senior IT professional with over sixteen years of professional experience in Web technologies. He is an expert in architecting and leading teams in delivering Sitecore CMS solutions. Craig has a consistent record of delivering successful software implementations that are on-time and on-budget.</em></strong></blockquote>
<br />
More information can be found about the MVP Program on the Sitecore MVP site: <a href="http://www.sitecore.net/mvp" rel="noopener" target="_blank">http://www.sitecore.net/mvp </a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-85903734452224454602017-12-01T15:23:00.001-05:002017-12-05T17:20:10.748-05:00Errthing is Duplicated! (in the Sitecore content tree)<head>
<meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjD-w3m9CKDm2-l4TZ-j2JEdliUJ7KP84DBkCBMEWRgVPEsSCzo9euaxAh-KFHWFbtBXAXXJCRrt51XRljkhXNOnPQ-XADfmx_D_S97C_hcaJaEXtWApkqYS79wtQo5gd-M9PHUefPwDg/s1600/sitecore-duplication.png" />
</head>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjD-w3m9CKDm2-l4TZ-j2JEdliUJ7KP84DBkCBMEWRgVPEsSCzo9euaxAh-KFHWFbtBXAXXJCRrt51XRljkhXNOnPQ-XADfmx_D_S97C_hcaJaEXtWApkqYS79wtQo5gd-M9PHUefPwDg/s1600/sitecore-duplication.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Errthing is Duplicated! (in the Sitecore content tree)"><img alt="Errthing is Duplicated! (in the Sitecore content tree)" border="0" data-original-height="200" data-original-width="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjD-w3m9CKDm2-l4TZ-j2JEdliUJ7KP84DBkCBMEWRgVPEsSCzo9euaxAh-KFHWFbtBXAXXJCRrt51XRljkhXNOnPQ-XADfmx_D_S97C_hcaJaEXtWApkqYS79wtQo5gd-M9PHUefPwDg/s1600/sitecore-duplication.png" /></a></div>
<br />
So many Sitecores! I recently ran into something that I've never seen before. After performing a build to my local server, I noticed that I was having trouble syncing portions of my content tree via TDS and Rocks. After further investigation, I noted that every node was duplicated:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbR6UwKbfusN8vtv-l9OFsdCtA-8Zuh4ZtRbLO6QFZRhwgxiBgHpoPiDgACFtrdhWl-ejeOOmpycHkOfiLiCA6W9Gn2jmZli0QW3Io_kd_6-J3ULj_ylisdrIc4j8eKfW2QVuL7puuPg/s1600/duplicatedTree.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="You get a content, you get a content, you get a content"><img alt="You get a content, you get a content, you get a content" border="0" data-original-height="327" data-original-width="190" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbR6UwKbfusN8vtv-l9OFsdCtA-8Zuh4ZtRbLO6QFZRhwgxiBgHpoPiDgACFtrdhWl-ejeOOmpycHkOfiLiCA6W9Gn2jmZli0QW3Io_kd_6-J3ULj_ylisdrIc4j8eKfW2QVuL7puuPg/s320/duplicatedTree.png" width="185" /></a></div>
<br />
No bueno. The duplicated items had identical guids, so it's not like they were separate items. This screenshot is from Rocks, but logging into Sitecore showed me the same thing. (8.2 Update 4, btw, but this probably applies to all versions of Sitecore)<br />
<br />
I tried just about everything I could think of to resolve this. No dice. Off to the trusty Sitecore Slack channels for help!<br />
<br />
<i><b>Side note: </b>The Sitecore community is awesome! You've instantly got an army of Sitecore enthusiasts willing to help you through any roadblocks you may face. At times it seems like there are so many places to keep track of, but when you need them, you're glad they're there. How to connect with the community: <a href="https://sitecore.stackexchange.com/questions/1689/how-can-i-connect-with-the-sitecore-community" target="_blank">https://sitecore.stackexchange.com/questions/1689/how-can-i-connect-with-the-sitecore-community</a></i><br />
<br />
As I initially thought this might have something to do with TDS, I tried that channel first. Using the suggestions by others on the channel I tried numerous IIS restarts, Visual Studio reboots, disabled the TDS item cache, removed TDS file caches and rebooted my VM. None of these helped my situation. I was starting to consider "nuclear" options where I would attach vanilla master database files and briefly considered "transferring items from web to master." I was not looking forward to these options and am glad I didn't get to that point.<br />
<br />
<h3>
The Fix</h3>
Fellow Sitecore MVP Kamruz Jaman (<a href="https://twitter.com/jammykam" target="_blank">@JammyKam</a>) thought this sounded like a config issue. Perhaps there were some config files were corrupt or duplicated, he thought. He suggested disabling all custom configs to rule those out. I wasn't sure what would have changed from earlier in the day when everything was working and to a bit later that evening, but I decided to delete all custom configs knowing that I could always just redeploy them.<br />
<br />
Well, I deleted the custom config files and fired Sitecore back up (after an IISreset for good measure) to check and sure enough, the duplication issue was resolved!<br />
<br />
I still didn't have my application configs now, so I followed up with re-deploying my application. Still worked, whew!<br />
<br />
<h3>
So What Busted Sitecore?</h3>
I actually haven't had a chance to get to the bottom of <b>*exactly*</b> which config broke Sitecore so hard. I think there must have been a config that somehow got duplicated (with a different name) or some cruft left over from a bad deploy that caused it to get wonky. It was definitely not a TDS problem though, just to be clear! ;) I'm just glad the solution was relatively easy.<br />
<h3>
<br />Sitecore 9 to the Rescue!</h3>
Well, 9 isn't the solution to my duplication problem, but it would have been much, much easier if I were already on 9 and could disable an entire configuration layer via the "mode=Off" setting as our hero of this story, Kamruz documents here:<br />
<a href="https://jammykam.wordpress.com/2017/10/17/rules-based-configuration/" target="_blank">https://jammykam.wordpress.com/2017/10/17/rules-based-configuration/</a><br />
<div>
<br /></div>
<div>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-68661779405419563062017-06-15T15:58:00.000-04:002017-06-15T15:59:32.856-04:00Suppress Cookies for EU Cookie Compliance<head>
<meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaQOZNeJ4FwmQfeYF0xeFbv_aWPpExzlrENiO6uRItTVduuZzUesouKnWhD9Y9kqBmRw2LtLLe0q2l-6dc_2f4C-WH1uSkD5UTkMDza5a8ZMFZmdHXbTa6quFUusv-BbGZiuSi7iV23Q/s1600/Cookies.jpg" />
</head>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaQOZNeJ4FwmQfeYF0xeFbv_aWPpExzlrENiO6uRItTVduuZzUesouKnWhD9Y9kqBmRw2LtLLe0q2l-6dc_2f4C-WH1uSkD5UTkMDza5a8ZMFZmdHXbTa6quFUusv-BbGZiuSi7iV23Q/s1600/Cookies.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Suppress Cookies for EU Cookie Compliance"><img alt="Suppress Cookies for EU Cookie Compliance" border="0" data-original-height="300" data-original-width="300" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaQOZNeJ4FwmQfeYF0xeFbv_aWPpExzlrENiO6uRItTVduuZzUesouKnWhD9Y9kqBmRw2LtLLe0q2l-6dc_2f4C-WH1uSkD5UTkMDza5a8ZMFZmdHXbTa6quFUusv-BbGZiuSi7iV23Q/s200/Cookies.jpg" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
You've probably seen this already on a number of sites, but increasingly, sites are being required to inform their visitors of the site's cookie policies. Many implementations that I've seen provide the disclaimer that cookies are being used and that by interacting with the site, the user is providing consent. My client is going a step further and requires that <b>*no*</b> cookies (except the ASP.NET session cookie) be written to the browser before the user provides consent.<br />
<br />
In the case of this client's site, this includes Sitecore's analytics tracking cookie, Sitecore's language cookie (although technically okay to emit because it's only a session cookie) and a host of other tracking cookies emitted from different renderings.<br />
<br />
In order to approach this in a way that prevents the need to edit logic across the solution, we came up with a solution that has two primary components:<br />
<br />
<ol>
<li><b>A Cookie Consent Provider</b> - This provider allows us to interface with a third party system for determining if consent is required, not required or has already been provided. Additionally, by implementing a provider, we can easily switch out to another provider at some point in the future and not have to re-write logic. </li>
<li><b>An MVC filter</b> - By creating an MVC filter that checks for consent, we can simply decorate methods in our controllers to control the emitting of code/cookies without having to affect any logic already contained in those methods.</li>
</ol>
I'll talk a bit about the primary components and then describe how they all work together to actually suppress the cookies.<br />
<br />
<div>
<h3>
Cookie Consent Provider</h3>
<div>
The provider is based on the standard Microsoft provider model. I create a base class that all providers will inherit from. In the base class, I have methods to get and set the user's consent to use cookies.</div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/craigtfromatl/29b899a837050f60de35b183b0ab27f5.js"></script></div>
<div>
I won't review the details of my provider implementation but know that it's pretty vanilla with a provider that implements the base class along with the necessary configuration elements in code and the web.config.<br />
<br />
<h3>
MVC Filter</h3>
</div>
<div>
I chose to use an "AuthorizeAttribute" filter to allow me to suppress the execution of controller methods. The authorize attribute returns a simple "true" or "false" value indicating if the calling method has the required permissions to execute.<br />
<br />
The two primary areas to concern ourselves with in the filter are the "AuthorizeCore" and "HandleUnauthorizedRequest" methods.<br />
<br />
<script src="https://gist.github.com/craigtfromatl/14cb0a8394fc7051457b94933b756656.js"></script></div>
<div>
In "AuthorizeCore", we are checking the need for consent. It returns a bool value indicating if the current request can be executed. Also note a bit of tricky logic there regarding the "InvertLogic" parameter. Basically, I have times when I need to execute the calling method when the result of the "AuthorizeCore" check is false. By passing in this parameter, I can invert the logic to return the desired results. In my case, I want to execute a controller rendering that outputs my cookie consent banner when consent is required. I can just decorate my method with the additional parameter:<br />
<br />
<script src="https://gist.github.com/craigtfromatl/e317bfcd36d3fa01f0351ba2c788a83e.js"></script><br />
In "HandleUnauthorizedRequest" (the code that is executed when "AuthorizeCore" returns "false") we are setting an AuthorizationContext Result. In my case, we wanted to output an HTML comment that indicates the calling method along with the status so that we could easily confirm that the system is functioning normally when we view the source of the page.<br />
<br />
<h3>
Putting it Together </h3>
</div>
<div>
As mentioned, the goal here is to suppress cookies from being emitted before the user has given consent. The two Sitecore-specific cookies that I am blocking are the 'analytics' and 'lang' cookies. I block these by inserting pipeline processors that check my consent provider. <br />
<br />
<span style="font-size: x-small;"><i><b>Note:</b> Always use patch include files and refrain from editing the Sitecore.config file directly. </i></span></div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/craigtfromatl/0615f68c41a4229ae19250e3e28736e3.js"></script></div>
<div>
It's also worth noting that I have a configurable 'AnalyticsCookiePrefix' parameter that I pass into the "SuppressAnalyticsCookie" processor. If the cookie name ever changes in the future, we can edit the value in config and not have to touch the code.<br />
<br />
In those processors, I make a call to the consent provider to see if I need to suppress the cookies or not. If I do, I search the current Response and remove the cookies. If consent has already been provided on a previous request, the code is skipped.<br />
<br />
<span style="font-size: x-small;"><i><b>Note:</b> <a href="https://sitecore.stackexchange.com/questions/5849/programmatically-log-visit-when-analytics-cookie-is-disabled" target="_blank">Via Sitecore.Stackexchange, it was recommended that I not disable the Tracker.</a> I disabled it anyways, because even though it might be legit to have the cookie written on the first load per EU specifications, my client's requirement was that it was not to be written at all until consent is provided. Additionally, I wanted to avoid editing the web.config file so instead of utilizing the HTTP module method, I wrote a pipeline processor. (Yeah, I know I edited the web.config with the consent provider . . . )</i></span><br />
<br />
So the processors take care of the Sitecore-specific cookies that are written. For any controller methods that end up writing scripts that emit cookies, I simply decorate the method with my Authorize Attribute override and no further code changes are required!<br />
<br /></div>
<h3>
Additional Resources</h3>
<div>
<a href="http://ec.europa.eu/ipg/basics/legal/cookies/index_en.htm" target="_blank">EU Cookie Law</a></div>
<div>
<br /></div>
<a href="https://sitecore.stackexchange.com/questions/5652/ways-to-block-sc-analytics-global-cookie-from-being-deployed" target="_blank">Ways to block SC_ANALYTICS_GLOBAL_COOKIE from being deployed</a> - Sitecore.stackexchange.com<br />
<br />
<a href="http://dotnetslackers.com/articles/designpatterns/HowToWriteAProviderModel.aspx" target="_blank">How to Write a Provider Model</a><br />
<br />
<a href="https://msdn.microsoft.com/en-us/library/gg416513(vs.98).aspx" target="_blank">MVC Filters</a></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-67113694511929658212017-05-04T14:50:00.002-04:002017-05-04T15:03:27.928-04:00Help! No one can log in!<head>
<meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEK7bVfPO1dni7_vfgTO-tnwpclj1OUG1KQWyVll_-Zuy96HOVaflVwgurzNAJbBFo9Bh7ASTxFKTRxmGcl8IYynsWq3s4HbCK1B4Kel1lPuUFGj5y-QNhJ-uxzkoA0zFMjzYaHdk3TA/s1600/broken.jpg" />
</head>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEK7bVfPO1dni7_vfgTO-tnwpclj1OUG1KQWyVll_-Zuy96HOVaflVwgurzNAJbBFo9Bh7ASTxFKTRxmGcl8IYynsWq3s4HbCK1B4Kel1lPuUFGj5y-QNhJ-uxzkoA0zFMjzYaHdk3TA/s1600/broken.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="No one can log into Sitecore; Sitecore Domain deleted. Ooops, hehe?"><img alt="No one can log into Sitecore; Sitecore Domain deleted." border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEK7bVfPO1dni7_vfgTO-tnwpclj1OUG1KQWyVll_-Zuy96HOVaflVwgurzNAJbBFo9Bh7ASTxFKTRxmGcl8IYynsWq3s4HbCK1B4Kel1lPuUFGj5y-QNhJ-uxzkoA0zFMjzYaHdk3TA/s200/broken.jpg" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Oh snap. It's Friday afternoon at the end of a long week and you get a desperate email from the client indicating that none of the logins for the Sitecore CM server work any longer. Guess I'll put down the beer from the office kegerator and go look at things. :/<br />
<br />
First up: Confirm the CD servers are still running/displaying the site. Check.<br />
<br />
Next: Is the CM server up? Check; I can see the Sitecore login screen.<br />
<br />
Next: Attempt to log into the CM with my admin account: Hmm, not able to log in.<br />
<br />
Next: RDP into the CM server to see what's going on. Able to RDP fine.<br />
<br />
Next: Look at the logs. Come across something interesting/scary:<br />
<br />
<script src="https://gist.github.com/craigtfromatl/629122b74f7380f6de462cd36e8bf938.js"></script>
<br />
<div>
Err, that doesn't look good. Someone logged into Sitecore using an admin account and managed to delete the Sitecore domain. You know, the one that <b>*all*</b> the logins are associated with. . . So now, no one can log in.<br />
<br />
Fortunately, the users themselves are not deleted when a domain is deleted. (<a href="https://doc.sitecore.net/sitecore_experience_platform/setting_up_and_maintaining/security_and_administration/users_roles_and_domains/create_and_edit_a_security_domain#_Delete_a_domain">https://doc.sitecore.net/sitecore_experience_platform/setting_up_and_maintaining/security_and_administration/users_roles_and_domains/create_and_edit_a_security_domain#_Delete_a_domain</a>)<br />
<br />
Before we get into how to solve this, let's talk about a couple of security issues here. <br />
<br />
One: It looks like users that clearly don't know what they are doing have access to an admin account where they can do very bad things. I think it should be a extremely rare exception where a content author needs this level of access. It takes longer to properly configure security so that content authors can do everything they need to do but don't have access to portions of Sitecore that they don't need, but that's how it should be done. Sometimes you can't avoid this and have to create some admin accounts for users, but as the logs show us, we don't even know where to point the finger since a 'generic' admin account was used.<br />
<br />
Two: <b>DO NOT GIVE CREDENTIALS TO GENERIC ADMIN ACCOUNTS!</b> If a user <i>'needs'</i> admin access, make the account tied to that user an admin. This would at least let us see who made the boo-boo.<br />
<br />
Okay, let's solve this.<br />
<br />
Restoring last night's database backup could be an option. (Checks with Devops) "Oh, the database backup process isn't running properly and we have no backups? Super." Side note: Well, at least we found that out now and can fix that.<br />
<br />
Somehow hacking in to the database to restore whatever was deleted could be an option. Hmm, I'm not sure I even want to go there.<br />
<br />
Recall that there is a "Domains.config" file in the "App_Config\Security" folder and that the error specifically mentioned modifying it, there might be something there. . . .<br />
<br />
After comparing the modified file to a stock Sitecore Domains.config file, it was easy to see that the only thing missing was the line that declared the "sitecore" domain:<br />
<br />
<script src="https://gist.github.com/craigtfromatl/2fcd4c8a74b1ca1194aa9a68aa42e793.js"></script>
I added that line back in and poof!: Everyone can log in again. A much easier solve than I would have thought for something that appeared to be very scary.<br />
<br />
Next step: <b>IMMEDIATELY</b> change the generic admin account credentials and let the users know that they can log in again.<br />
<br />
Now, back to that beer. . .<br />
<br />
<b>TL;DR</b>: Put the "sitecore" domain declaration back into the "Domains.config" file, drink beer.</div>
Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4704704487040880240.post-84056953543957982062017-02-28T17:42:00.000-05:002017-05-04T15:08:06.749-04:00Sitecore Server Switch<head>
<meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc_iRQv3dvTxbaPul58ga_l3IxYXF93zGyCdJIuQmeS35s4-3lDBfHNPlXp57yA3g5RMg38cfBSIDjB6DExqRnH4y1lvWwArS4pzFHtTJ16EVPqO_vQoRjWyh1uLlw0gECLCtLVIw_1A/s1600/SitecoreServerSwitch.png" />
</head>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc_iRQv3dvTxbaPul58ga_l3IxYXF93zGyCdJIuQmeS35s4-3lDBfHNPlXp57yA3g5RMg38cfBSIDjB6DExqRnH4y1lvWwArS4pzFHtTJ16EVPqO_vQoRjWyh1uLlw0gECLCtLVIw_1A/s1600/SitecoreServerSwitch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Sitecore Server Switch"><img alt="Sitecore Server Switch" border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc_iRQv3dvTxbaPul58ga_l3IxYXF93zGyCdJIuQmeS35s4-3lDBfHNPlXp57yA3g5RMg38cfBSIDjB6DExqRnH4y1lvWwArS4pzFHtTJ16EVPqO_vQoRjWyh1uLlw0gECLCtLVIw_1A/s200/SitecoreServerSwitch.png" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
One of the most time-consuming aspects of installing and configuring Sitecore is configuring the servers for their specific roles. Per <a href="http://doc.sitecore.net/" target="_blank">Sitecore documentation</a>, specific configuration files should be enabled or disabled for a Content Management (CM) server and likewise, specific files should be enabled or disabled for Content Delivery (CD) server. Failing to configure the servers for their roles can cause Sitecore to not perform as expected.<br />
<i><br /></i>
<i><span style="font-size: x-small;"><b>Note:</b> There are additional roles for server configurations such as Processing, Reporting and Publishing.</span></i><br />
<i><br /></i>
<a href="https://doc.sitecore.net/cloud/working_with_sitecore_azure/sitecore_azure_app_service_overview" target="_blank">Sitecore's ARM templates</a> look to solve this problem in that they can quickly spin up and configure a Sitecore server, but this only works when using Azure PAAS. For those not using Azure PAAS, manually adjusting the configuration files can be time consuming.<br />
<br />
<a href="https://github.com/craigtfromatl/Sitecore-Server-Switch" target="_blank">Sitecore Server Switch</a> looks to solve this issue by using PowerShell. After installing Sitecore on a server, you can run the "Sitecore_Switch_CM_CD_Lucene_Solr.ps1" script to configure a server as a CM server, as a CD server and additionally configure it to utilize either Lucene or Solr indexing.<br />
<br />
Sitecore Server Switch currently supports Sitecore 8.0 (all versions) and Sitecore 8.2 Update 2. More versions are coming soon.<br />
<br />
<h3>
Sources</h3>
<a href="https://github.com/craigtfromatl/Sitecore-Server-Switch" target="_blank">Sitecore Server Switch GitHub Source</a><br />
Sitecore Server Switch on the Sitecore Marketplace (coming soon!)<br />
<br />
<h3>
Acknowledgments</h3>
Big shout-out to Sarkis Einarsson for his PowerShell scripts that were the base of this project. (<a href="http://sitecoreunleashed.blogspot.com/2015/09/sitecore-8-toggle-cd-configuration.html" target="_blank">http://sitecoreunleashed.blogspot.com/2015/09/sitecore-8-toggle-cd-configuration.html</a>)<br />
<br />
<h3>
Additional Reading</h3>
You can also take this to the next level and automate everything. Check out <a href="https://twitter.com/Patrick_Perrone" target="_blank">Patrick Perrone's</a> work into this space with his <a href="http://sitecoreblog.patrickperrone.com/2015/07/powershell-sitecore-install-script.html" target="_blank">automation scripts</a>.<br />
<br />
<h3>
Update (03/01/2017)</h3>
And of course, how it usually happens, after writing this module and post, I came across this site that has some automation scripts for 8.2 and even includes the ability to configure additional roles: <a href="https://bitbucket.org/sitecoreautomationteam/sitecore-automation/wiki/sitecore-environment" target="_blank">https://bitbucket.org/sitecoreautomationteam/sitecore-automation/wiki/sitecore-environment</a><br />
<i><span style="font-size: x-small;"><b>Note: I have not tested this.</b></span></i><br />
<br />
And I've also been made aware of <a href="https://twitter.com/michaelwest101" target="_blank">Michael West's</a> PowerShell scripts as well: <a href="https://gist.github.com/michaellwest/d1124a459cb1fb47486f87d488ecfab8" target="_blank">https://gist.github.com/michaellwest/d1124a459cb1fb47486f87d488ecfab8</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-23362640731830241022017-02-17T10:15:00.000-05:002017-02-17T10:15:40.793-05:00Implement TDS Code Generation for a Helix Generic Repository Foundation Layer<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzD5aml1L16WXemDXeOFqzutKEy_9dqk4tXXhUiKzkws1uTIN1Q6iALyQ7tpNiMYxdlLmGpqeehhUi_8ZACxtBnxX6ndaZZdWOjIeLEe4YOjHRUPFHoMvnKQnbqFHLasVUqAJ-Ju6NWQ/s1600/Implement_TDS_Code_Generation_for_a_Helix_Generic_Repository_Foundation_Layer_square.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Implement TDS Code Generation for a Helix Generic Repository Foundation Layer"><img alt="Implement TDS Code Generation for a Helix Generic Repository Foundation Layer" border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzD5aml1L16WXemDXeOFqzutKEy_9dqk4tXXhUiKzkws1uTIN1Q6iALyQ7tpNiMYxdlLmGpqeehhUi_8ZACxtBnxX6ndaZZdWOjIeLEe4YOjHRUPFHoMvnKQnbqFHLasVUqAJ-Ju6NWQ/s200/Implement_TDS_Code_Generation_for_a_Helix_Generic_Repository_Foundation_Layer_square.png" width="200" /></a></div>
I recently sat down to implement some of the suggestions from <a href="https://twitter.com/philwicklund" target="_blank">Phil </a>and <a href="https://twitter.com/LonghornTaco" target="_blank">Jason's </a>amazing book on Sitecore development, <i><a href="http://www.apress.com/us/book/9781484222911" target="_blank">Professional Sitecore 8 Development</a></i>. I already had a few <a href="http://helix.sitecore.net/" target="_blank">Helix architecture</a> implementations under my belt, but felt like I could improve on what I had done. I think it's probably the case after each implementation that you always find things to improve on for the next implementation. In particular, I was trying to get my Helix architecture to be more consistent, efficient and repeatable.
<br />
<div>
<br />
In chapter 5 of the <i><a href="http://www.apress.com/us/book/9781484222911" target="_blank">Professional Sitecore 8 Development</a></i> book, Phil and Jason speak of improving the architectural design by using design patterns. Specifically, they recommend creating a generic repository foundation layer. One of the tools that can help accomplish this goal is <a href="http://glass.lu/" target="_blank">Glass Mapper</a>. Using Glass, we are able to let the repository remain generic and we can tell it the type of object to return at runtime. In order to constrain the generic repository, their examples set the interface of the generic repository to require that the type being passed in implements "ICmsEntity" (a separate foundation layer that is used to represent a Sitecore item)</div>
<div>
<br />
So, the "ICmsEntity" interface (code lifted directly from <i><a href="http://www.apress.com/us/book/9781484222911" target="_blank">Professional Sitecore 8 Development</a></i>) looks like this:
<script src="https://gist.github.com/craigtfromatl/1c38feb733824082db38259aee1c45da.js"></script>
</div>
<div>
And the generic repository (code lifted directly from <i><a href="http://www.apress.com/us/book/9781484222911" target="_blank">Professional Sitecore 8 Development</a></i>) looks like this:
<script src="https://gist.github.com/craigtfromatl/ea66aee6aa5816521aaa1b68c041c220.js"></script></div>
<div>
As you can see, the ICmsEntity interface is empty. It's really just a way to differentiate Sitecore items from other classes/items. What we want to do is make sure that any interfaces that we create via Glass that represent Sitecore items implement this ICmsEntity interface.<br />
<br />
The example in the book goes on to explain how you can utilize an ORM foundation layer to map to all your Sitecore objects. In my case, I'm using <a href="http://www.teamdevelopmentforsitecore.com/" target="_blank">Team Development For Sitecore</a> (TDS) and have have TDS projects generating my code within my feature layers.<br />
<br />
To utilize this generic repository and to have it incorporate the ICmsEntity interface constraint, we need to modify the code generation templates that TDS uses. This is where it gets super-easy to implement. (wait, it's supposed to be difficult, right?)<br />
<br />
First, edit the "glassv3header.tt" T4 template to import the namespace of the foundation layer that contains the ICmsEntity interface. I'll continue to use the namespaces specified in the example from the book for consistency. See line #11 below:<br />
<script src="https://gist.github.com/craigtfromatl/8e3a76269b117f46712b67782afd4655.js"></script></div>
<div>
<br />
Now, edit the "glassv3item.tt" T4 template to have the interfaces that are created implement the ICmsEntity interface. See line #8 below:<br />
<script src="https://gist.github.com/craigtfromatl/dab4e88685de9fdd29a1ceef1c84dc14.js"></script></div>
<div>
<br />
Re-generate your code and you're done! You now automatically have all your Sitecore objects implementing the ICmsEntity interface and your generic repository will be able to retrieve the proper objects.<br />
<br />
<h3>
Additional Reading/Resources</h3>
<div>
<i><a href="http://www.apress.com/us/book/9781484222911" target="_blank">Professional Sitecore 8 Development</a> </i>- You <i><b>*do*</b></i> have the book already, right??</div>
<div>
<a href="http://helix.sitecore.net/" target="_blank">Helix</a> - Helix documentation</div>
<div>
<a href="http://www.teamdevelopmentforsitecore.com/" target="_blank">Team Development For Sitecore</a> </div>
<div>
<a href="http://glass.lu/" target="_blank">Glass Mapper</a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgszviw84UD5Ntnn_GJ3Iyn3qG4EqhzmyMTolbjLPpmbsJWZM-LwYq5RP0maft4T9wbnUeysxmlMreTtkuFeud-1os0mQjWcJ2Gizq5LKa2ZFms1LCEkXiJmqWmoBEkgSeYYIKMZT-Trw/s1600/nomeme.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgszviw84UD5Ntnn_GJ3Iyn3qG4EqhzmyMTolbjLPpmbsJWZM-LwYq5RP0maft4T9wbnUeysxmlMreTtkuFeud-1os0mQjWcJ2Gizq5LKa2ZFms1LCEkXiJmqWmoBEkgSeYYIKMZT-Trw/s200/nomeme.jpg" width="200" /></a></div>
<br /></div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4704704487040880240.post-66455357148447409952017-01-23T13:19:00.000-05:002017-01-23T13:32:11.770-05:00Setting Sitecore SQL Server Database Permissions<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBf8mITl4NUPagp3ZHI2lFFI4TxXqMAYGnCBMBa0_Bl-sARajkDGpQiHB3DnTGrUjgE3npQ81leiK8sYySxKSvu5oTQ020RMaBBKVn71505Q1nv01dLw0PIHuJDumJcj7dAhn-qKHw7w/s1600/rtfm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Setting Sitecore SQL Server Database Permissions"><img alt="Setting Sitecore SQL Server Database Permissions" border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBf8mITl4NUPagp3ZHI2lFFI4TxXqMAYGnCBMBa0_Bl-sARajkDGpQiHB3DnTGrUjgE3npQ81leiK8sYySxKSvu5oTQ020RMaBBKVn71505Q1nv01dLw0PIHuJDumJcj7dAhn-qKHw7w/s200/rtfm.png" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
I recently started on a Sitecore 8.2 project and was setting the SQL Server permissions for the SQL user that I had created for Sitecore to use. The idea here is to provide <a href="https://technet.microsoft.com/en-us/library/cc700846.aspx" target="_blank">least-permissions</a> to the user so that it has enough access to work, but not so much access that it is able to do things that it should not be able to. I feel like I spent way too much time looking for the permissions that should be set. I eventually found what I was looking for in the installation guide for Sitecore! (#rtfm)<br />
<br />
In an effort to make sure this information is accessible (read: so that I find it when I forget next time), I've duplicated the content here.<br />
<div>
<br />
<h4>
For the "Master", "Web", "Sessions" and "Analytics" databases, select the following permissions:</h4>
<ul>
<li>db_datareader</li>
<li>db_datawriter</li>
<li>public </li>
</ul>
<h4>
For the Core database, select the following permissions:</h4>
<ul>
<li>db_datareader</li>
<li>db_datawriter</li>
<li>public</li>
<li>aspnet_Membership_BasicAccess</li>
<li>aspnet_Membership_FullAccess</li>
<li>aspnet_Membership_ReportingAccess</li>
<li>aspnet_Profile_BasicAccess</li>
<li>aspnet_Profile_FullAccess</li>
<li>aspnet_Profile_ReportingAccess</li>
<li>aspnet_Roles_BasicAccess</li>
<li>aspnet_Roles_FullAccess</li>
<li>aspnet_Roles_ReportingAccess</li>
</ul>
<h4>
For all databases:</h4>
</div>
<div>
In addition to assigning the proper roles to your user for the Sitecore databases, you also want to allow the user to execute stored procedures. For each database, open the "Properties" window, select "Permissions", select your user and select the "Grant" checkbox for the "Execute" permission.</div>
<div>
<br /></div>
<div>
This is all from the <a href="https://dev.sitecore.net/Downloads/Sitecore_Experience_Platform/82/Sitecore_Experience_Platform_82_Update2.aspx" target="_blank">8.2 Update 2</a> installation guide, which I can't seem to link to due to authentication requirements on <a href="http://dev.sitecore.net/">http://dev.sitecore.net</a>, but I think the permissions are the same for previous versions of Sitecore as well.</div>
<div>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-72678015511639946872016-08-11T13:16:00.000-04:002016-08-11T13:16:09.280-04:00Sitecore Config Transforms - Use Replace instead of Remove<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9XVi_TC6UD7lDjvKJjqpJFYgMhbkOYCNL0kZ160j9Iizay4hGlym7UOW6uX5rd2yHziE0i1EqeccIAHcX2sqDEEchU5naWzJe3cHp-UmR5GUf47sLxhhNcOIK42MjOR55RQsVvTWpLA/s1600/remove.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Sitecore Config Transforms - Use Replace instead of Remove"><img alt="Sitecore Config Transforms - Use Replace instead of Remove" border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9XVi_TC6UD7lDjvKJjqpJFYgMhbkOYCNL0kZ160j9Iizay4hGlym7UOW6uX5rd2yHziE0i1EqeccIAHcX2sqDEEchU5naWzJe3cHp-UmR5GUf47sLxhhNcOIK42MjOR55RQsVvTWpLA/s200/remove.jpg" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
I love config transforms. I love being able to have a single file that can be transformed for any number of my build destinations. It's much, much better than trying to maintain separate config files for each destination. Many times, I have config files that should <b>*only*</b> exist on either a CM or CD server. Originally, I used the "Remove" method to remove the entire contents of a config file like so:<br />
<br />
<script src="https://gist.github.com/craigtfromatl/152a45addb867b106c01077f2cb29192.js"></script><br />
While it doesn't technically break anything, it leads to errors in the logs on Sitecore startup that complain about "Reader is in incorrect state":<br />
<br />
<script src="https://gist.github.com/craigtfromatl/140c95cb236ca1fcf07856ecc91332b8.js"></script><br />
<div>
The fix is actually really easy. Instead of removing the entire "sitecore" node in the file, just replace it:<br />
<br />
<script src="https://gist.github.com/craigtfromatl/d04cfd08e9e8fb67d795fe58bb035d38.js"></script>
Now Sitecore be all happy.<br />
<br />
<br /></div>
<div>
</div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4704704487040880240.post-16011765499210858032016-06-28T13:41:00.000-04:002016-06-28T13:51:33.978-04:00Using Config Transforms to Manage Sitecore Indexes
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwu_t5tFYwM3WCMOjbRoOyzvLyMJygOF1NyFm2cD8FVmOhkIkQPEKQvHE9EYj8YlbJJX9DyovuGmP5fsmDNtJi81u4mSurMG7OmqopV0PgG7zKu86W_9ds9RAF64qDHbc4mO5-0kwc_A/s1600/AddTransform.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Using Config Transforms to Manage Sitecore Indexes"><img alt="Using Config Transforms to Manage Sitecore Indexes" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwu_t5tFYwM3WCMOjbRoOyzvLyMJygOF1NyFm2cD8FVmOhkIkQPEKQvHE9EYj8YlbJJX9DyovuGmP5fsmDNtJi81u4mSurMG7OmqopV0PgG7zKu86W_9ds9RAF64qDHbc4mO5-0kwc_A/s1600/AddTransform.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
In my <a href="http://www.craigtaylor.us/2016/03/solr-in-production-for-sitecore.html" target="_blank">previous post</a>, I talked about setting up your Solr indexes to use the "SwitchOnRebuildSolrSearchIndex" index type to avoid index downtime. In that post, I mentioned that I was using Config Transforms in order to manage the configuration settings across my different environments. Here's a quick example of how to set up an index for the different environments:<br />
<br /></div>
<div>
<h4>
The 'Default' or 'Standard' Index configuration that I have in my solution:</h4>
</div>
<div>
<script src="https://gist.github.com/craigtfromatl/11c6e95b1681c3a4829c40bde324d37a.js"></script></div>
What's going on?:<br />
<br />
<ul>
<li>I have separate configurations for "Web" vs "Master" databases. This configuration is for the "Web index. </li>
<li> I'm using the 'onPublishEndAsync' indexing strategy since this is my "Web" database. This tells Solt to update the index when a publish is complete.</li>
</ul>
<br />
<div>
I then "Add Transform" in Visual Studio to create the specific versions for the other environments.
<br />
<br />
<i><span style="font-size: x-small;"><b>Note:</b> In order to add the tranformations, you have to have separate solution configurations configured for each environment.</span></i><br />
<i><span style="font-size: x-small;"><br /></span></i></div>
<div>
I'll skip all my local/dev/qa/stage environments and just show what I've got for production, but note that each environment can and usually *should* have its own transformation.<br />
<br /></div>
<div>
<h4>
Production CM server configuration:</h4>
</div>
<div>
<script src="https://gist.github.com/craigtfromatl/44a22102f3b72fe21348529599b4795b.js"></script></div>
What's going on?:<br />
<br />
<ul>
<li>I tell the transform to look for all indexes in the parent config file and change the index type to "SwitchOnRebuildSolrSearchIndex." I like to keep only one index per configuration file, but if you had multiple indexes defined, this will change all of them.</li>
<li>I'm inserting the "rebuildcore" parameter into the index configuration. This is required so that Sitecore knows which Solr core to swap to after the rebuild is complete. <b>It's also very important that it goes in in the third position as Sitecore expects it there.</b></li>
</ul>
<div>
<h4>
When the transformation is applied, it looks like this:</h4>
</div>
<div>
<script src="https://gist.github.com/craigtfromatl/94864f2488caef0d98686bff2d2879cf.js"></script>
</div>
<div>
<h4>
For the Production CD server, I have the following transform:</h4>
</div>
<div>
<script src="https://gist.github.com/craigtfromatl/c84a6c39982a5c5c1ac0e5455cd8308f.js"></script>
</div>
What's going on?:<br />
<br />
<ul>
<li>As with the CM server, I'm changing the index type to "SwitchOnRebuildSolrSearchIndex", but as you will see with the next point, it doesn't really matter.</li>
<li>We are setting the index strategy to "manual." Our Solr indexes are centrally located on another server and we want the indexing to only happen once. The rebuilding of the indexes are controlled by the actions of the CM server.</li>
</ul>
Setting up different configurations based on environment is easily accomplished using config transforms. It keeps your configuration files clean and easy to manage.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQUP-i5fI9DIDGvmTx5RFpC2JlUnZ4J1PAwUH8vKgpBHRtmBJAPRRrJXWyoEs-i0dEYNnDFGGCeVXZSnzWiyhv6GDtg3G3rjVjAVwHhdBCG9BSeuhVgIuqTfYqbXCZXft55Dojdski6g/s1600/arnold.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQUP-i5fI9DIDGvmTx5RFpC2JlUnZ4J1PAwUH8vKgpBHRtmBJAPRRrJXWyoEs-i0dEYNnDFGGCeVXZSnzWiyhv6GDtg3G3rjVjAVwHhdBCG9BSeuhVgIuqTfYqbXCZXft55Dojdski6g/s320/arnold.jpg" width="320" /></a></div>
<br />
<div>
</div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4704704487040880240.post-3621921600866287162016-03-26T14:50:00.001-04:002016-05-09T20:06:03.756-04:00Solr in Production for Sitecore - SwitchOnRebuildSolrSearchIndex<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0XpNBXZU9JS-zr5gaDMQEx5RDk-9rItsOeyHJgnpv-ttBxucF-pB-CfhfTjgJLByNDswcCR_f4z-DPwk8ieHJi6YxbJBu3w3dJ447l9z1fuCR6K8IbfMeZK068CNSnx8z89casMHHEw/s1600/sitecore-solr.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Solr in Production for Sitecore - SwitchOnRebuildSolrSearchIndex"><img alt="Solr in Production for Sitecore - SwitchOnRebuildSolrSearchIndex" border="0" height="110" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0XpNBXZU9JS-zr5gaDMQEx5RDk-9rItsOeyHJgnpv-ttBxucF-pB-CfhfTjgJLByNDswcCR_f4z-DPwk8ieHJi6YxbJBu3w3dJ447l9z1fuCR6K8IbfMeZK068CNSnx8z89casMHHEw/s320/sitecore-solr.gif" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
The configuration for running Solr in your local dev environment is likely going to be different than running it in the production environment. Oftentimes, your local indexes will be configured as a type of "Sitecore.ContentSearch.SolrProvider.SolrSearchIndex" while using the "syncMaster" indexing strategy. This strategy rebuilds the index after data changes are saved in the master database. It works well locally if you want to avoid having to publish to the Web database to see your indexes update, but this doesn't work in a production environment where your Content Delivery (CD) servers don't have access to the master database. Not to mention, you don't want to be indexing content that hasn't been published yet.<br />
<br />
In a production environment, it is much more common to use the "SwitchOnRebuildSolrSearchIndex" index type while using the "onPublishEndAsync" indexing strategy. This type keeps your indexes up and running even when they are rebuilding. This is accomplished by building to a secondary index and when the rebuild is complete, Sitecore uses that index as the primary index. The rebuild is triggered when items are published to the 'Web' database. <br />
<br />
<i><span style="font-size: x-small;"><b>Note:</b> I should also note here that the CD servers should actually have their indexing strategies set to "manual" due to the Content Management (CM) server controlling when the central Solr indexes are being rebuilt . More on this below.</span></i><br />
<br />
Since I have different strategies defined for the different environments and have different build configurations in my Visual Studio solution, I utilized config transforms to allow the correct type and strategy to be used in the different environments. I'll detail these transforms in a future blog post.<br />
<br />
For this example, my local development instance has a custom index used for indexing products defined as follows:<br />
<br />
<pre class="brush:xml"> <index id="product_search_index" type="Sitecore.ContentSearch.SolrProvider.SolrSearchIndex, Sitecore.ContentSearch.SolrProvider">
<param desc="name">$(id)</param>
<param desc="core">$(id)</param>
<param desc="propertyStore" ref="contentSearch/indexConfigurations/databasePropertyStore" param1="$(id)" />
<configuration ref="contentSearch/indexConfigurations/productSearchIndexConfiguration" />
<strategies hint="list:AddStrategy">
<strategy ref="contentSearch/indexConfigurations/indexUpdateStrategies/syncMaster" />
</strategies>
<commitPolicyExecutor type="Sitecore.ContentSearch.CommitPolicyExecutor, Sitecore.ContentSearch">
<policies hint="list:AddCommitPolicy">
<policy type="Sitecore.ContentSearch.TimeIntervalCommitPolicy, Sitecore.ContentSearch" />
</policies>
</commitPolicyExecutor>
<locations hint="list:AddCrawler">
<crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
<Database>web</Database>
<Root>/sitecore/Content/Products</Root>
</crawler>
</locations>
</index></pre>
<div>
<br />
My local dev instance is a CM/CD combined instance and as you can see in my config, it uses the "Sitecore.ContentSearch.SolrProvider.SolrSearchIndex" type, with the "syncMaster" strategy on the "master" database. I can now update items and have them immediately available in my index without having to go through the trouble of publishing.<br />
<br />
When deploying to a dev, stage or prod CM server, I want to ensure that my products index is always available and only contains data that has been published. We can accomplish this with the "SwitchOnRebuildSolrSearchIndex" index type and the "onPublishEndAsync" indexing strategy. I have the following defined for a dedicated CM server:<br />
<br />
<pre class="brush:xml"> <index id="product_search_index" type="Sitecore.ContentSearch.SolrProvider.SwitchOnRebuildSorlSearchIndex, Sitecore.ContentSearch">
<param desc="name">$(id)</param>
<param desc="core">$(id)</param>
<param desc="rebuildcore">$(id)_sec</param>
<param desc="propertyStore" ref="contentSearch/indexConfigurations/databasePropertyStore" param1="$(id)" />
<configuration ref="contentSearch/indexConfigurations/productSearchIndexConfiguration" />
<strategies hint="list:AddStrategy">
<strategy ref="contentSearch/indexConfigurations/indexUpdateStrategies/onPublishEndAsync" />
</strategies>
<commitPolicyExecutor type="Sitecore.ContentSearch.CommitPolicyExecutor, Sitecore.ContentSearch">
<policies hint="list:AddCommitPolicy">
<policy type="Sitecore.ContentSearch.TimeIntervalCommitPolicy, Sitecore.ContentSearch" />
</policies>
</commitPolicyExecutor>
<locations hint="list:AddCrawler">
<crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
<Database>web</Database>
<Root>/sitecore/Content/Products</Root>
</crawler>
</locations>
</index></pre>
</div>
<ol>
</ol>
<br />
<i><span style="font-size: x-small;"><b>Note:</b> These two index configurations are shown to illustrate the process for both switching and utilizing the onPublishEndAsync strategy. In an actual production environment, you should separate your indexes so that you have one for the master database and one for the web database.</span></i><br />
<i><span style="font-size: x-small;"><br /></span></i>
The changes of note here are: <br />
<ol>
<li>The index type was changed to "Sitecore.ContentSearch.SolrProvider.SwitchOnRebuildSorlSearchIndex"</li>
<li>We added a new parameter named "rebuildcore". This tells Sitecore the name of the secondary core to utilize while building. Note that you need to have an additional core created to facilitate this.</li>
<li>The strategy has been changed to "onPublishEndAsync"</li>
<li>The "Database" we are indexing is the "Web" database.</li>
</ol>
<div>
This is a configuration for a CM server. In order to keep the CD servers from kicking off a rebuild of the indexes, you should set their index strategy type to "contentSearch/indexConfigurations/indexUpdateStrategies/manual".</div>
<div>
<br /></div>
<div>
Now, each time you publish an item, the index will be automatically updated and you don't have to worry about the rebuild time taking it offline as Sitecore will be using the secondary core you defined.</div>
<div>
<br /></div>
<h3>
Additional Reading</h3>
<div>
Explanation of the different indexing strategies by John West:<br />
<a href="http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2013/04/sitecore-7-index-update-strategies.aspx" target="_blank">http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2013/04/sitecore-7-index-update-strategies.aspx</a><br />
<br />
Switch Solr Indexes: <br />
<a href="https://doc.sitecore.net/sitecore_experience_platform/setting_up__maintaining/search_and_indexing/indexing/switch_solr_indexes" target="_blank">https://doc.sitecore.net/sitecore_experience_platform/setting_up__maintaining/search_and_indexing/indexing/switch_solr_indexes</a></div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4704704487040880240.post-19963908131820875912015-12-23T14:15:00.001-05:002015-12-23T14:20:33.211-05:00Could not create instance of type: Sitecore.ContentSearch.LuceneProvider.SwitchOnRebuildLuceneIndex. No matching constructor was found.<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhslJcBNEw7C49X-5TROELvWcbx2vXwU_F9YyW3ldTyLmcSLqKcdvG93jbzEAdZq6iQFHzB9SrgZ_wM2jX9tifRhvrBgJ0J5ir9FOCdWvvEBauwyNulZsM3MKxxm0M60iw2E0QQMh4uJA/s1600/lucene_logo_green_300.png" imageanchor="1" title="Could not create instance of type: Sitecore.ContentSearch.LuceneProvider.SwitchOnRebuildLuceneIndex. No matching constructor was found."><img alt="Could not create instance of type: Sitecore.ContentSearch.LuceneProvider.SwitchOnRebuildLuceneIndex. No matching constructor was found." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhslJcBNEw7C49X-5TROELvWcbx2vXwU_F9YyW3ldTyLmcSLqKcdvG93jbzEAdZq6iQFHzB9SrgZ_wM2jX9tifRhvrBgJ0J5ir9FOCdWvvEBauwyNulZsM3MKxxm0M60iw2E0QQMh4uJA/s400/lucene_logo_green_300.png" /></a>
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Okay, that's a long post title.<br />
<br />
While configuring a new Sitecore 8.1-Update 1 site that is using Lucene for indexing, I ran into an issue while changing all the indexes to utilize <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">SwitchOnRebuildLuceneIndex</span>. We do this to allow the system to switch indexes while the new index is rebuilding so that we don't temporarily lose access to an index while it is being rebuilt. Configuration-wise, we do this by utilizing config transforms.<br />
<br />
After building and deploying the solution locally, I was seeing the following nested exception:<br />
<br />
<pre class="brush:xml">Exception: Sitecore.Exceptions.ConfigurationException
Message: Could not create instance of type: Sitecore.ContentSearch.LuceneProvider.SwitchOnRebuildLuceneIndex. No matching constructor was found.
Source: Sitecore.Kernel
at Sitecore.Configuration.Factory.CreateFromTypeName(XmlNode configNode, String[] parameters, Boolean assert)
at Sitecore.Configuration.Factory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert, IFactoryHelper helper)
at Sitecore.Configuration.Factory.GetInnerObject(XmlNode paramNode, String[] parameters, Boolean assert)
at Sitecore.Configuration.Factory.AssignProperties(XmlNode configNode, String[] parameters, Object obj, Boolean assert, Boolean deferred, IFactoryHelper helper)
at Sitecore.Configuration.Factory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert, IFactoryHelper helper)
at Sitecore.Configuration.Factory.CreateObject(String configPath, String[] parameters, Boolean assert)
at Sitecore.ContentSearch.ContentSearchManager.get_SearchConfiguration()
at Sitecore.ContentSearch.ContentSearchManager.GetIndex(String name)
at Sitecore.Marketing.Search.CampaignDefinitionSearchProvider..ctor(String indexName)</pre>
<div>
<br />
So I had actually recently seen a very similar error while configuring some Solr indexes for a different client. From that troubleshooting experience, I knew I could crack open the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">Sitecore.ContentSearch.LuceneProvider</span> assembly to look for the constructor that was having issues.<br />
<br />
I could see that the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">SwitchOnRebuildLuceneIndex</span> constructor accepts three parameters: name, folder and propertyStore.<br />
<br />
Upon inspecting my transforms, I came across the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">Sitecore.ContentSearch.Lucene.Index.Analytics.config</span> file. This config file specifies the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">sitecore_analytics_index</span> index, and has four parameters: name, folder, propertyStore and group. This is more than the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">SwitchOnRebuildLuceneIndex</span> constructor is expecting.</div>
<div>
<ol>
</ol>
<h3>
Workaround/Fix</h3>
</div>
<div>
Don't use <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">SwitchOnRebuildLuceneIndex</span> on the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">sitecore_analytics_index</span>! Just leave it as the 'standard' type of <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">Sitecore.ContentSearch.LuceneProvider.LuceneIndex</span>.<br />
<br />
As to why this index is different, Patrick notes that the crawlers indexing the analytics data are observers and there is no need to have a secondary index. Read more in his <a href="http://sitecoreblog.patrickperrone.com/2015/03/on-secondary-thought.html" target="_blank">blog post</a>.</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-17751784079576294192015-10-22T16:32:00.000-04:002015-10-22T16:34:36.003-04:00EXM install fails when Admin user is disabled<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilqn-NY5Rg6jeB066pn1jlyoRpXWloY380XWvFKhXN4U0VVwyKLj4oKXQVduxZOmtL4Fu4gqnP_DoRUOIUaGqAbutSg5S_lm6APWFtF9B5d0vMhMXz1CoqzJj8N8-cIu6Oeu03CuQ39w/s1600/sitecore-logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="EXM Install Fails when Admin user is disabled"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilqn-NY5Rg6jeB066pn1jlyoRpXWloY380XWvFKhXN4U0VVwyKLj4oKXQVduxZOmtL4Fu4gqnP_DoRUOIUaGqAbutSg5S_lm6APWFtF9B5d0vMhMXz1CoqzJj8N8-cIu6Oeu03CuQ39w/s200/sitecore-logo.png" width="200" alt="EXM Install Fails when Admin user is disabled" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Wow, been heads-down with client work for a while and haven't had a chance to write to the 'ol blog. Glad to have some breathing room before the next project starts to get a few posts out.<br />
<br />
While installing EXM 3.0 rev. 150429 on a Sitecore 8.0 Update 3 instance for a client, we ran into an interesting issue. What is normally a pretty simple install was failing for us.<br />
<br />
We were seeing the following error:<br />
<br />
<pre class="brush:xml">ERROR Installation failed: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Sitecore.Exceptions.AccessDeniedException: Only administrators can create new domains
at Sitecore.SecurityModel.DomainManager.AddDomain(String domainName, Boolean locallyManaged)
at Sitecore.Modules.EmailCampaign.Core.InstallationPostAction.AddCommonDomain()
at Sitecore.Modules.EmailCampaign.Core.InstallationPostAction.RunPostStep()
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Sitecore.Install.Installer.ExecutePostStep(String action, IProcessingContext context)
at Sitecore.Shell.Applications.Install.Dialogs.InstallPackage.InstallPackageForm.AsyncHelper.CatchExceptions(ThreadStart start)</pre>
<div>
The "<i><b>Sitecore.Exceptions.AccessDeniedException: Only administrators can create new domains</b></i>" line really caught my eye and after poking around for a bit I discovered the issue: Sitecore was expecting the "sitecore/admin" user and we had disabled this account. Now this was done intentionally for security reasons and we created a separate account with "admin" privileges. So it appears as though the install requires that the "sitecore/admin" context is used when installing EXM. (Good thing we only disabled the user and didn't delete it!)<br />
<br /></div>
<h3>
Steps to Reproduce</h3>
<div>
<ol>
<li>Use <a href="https://marketplace.sitecore.net/modules/sitecore_instance_manager.aspx" target="_blank">SIM</a> (you <b>*are*</b> using SIM, right?) to spool up a fresh instance of 8.0 update 3.</li>
<li>Create new account and give it administrator privileges.</li>
<li>Log out of "sitecore\admin" and log in as the new admin user.</li>
<li>Disable 'old' admin account.</li>
<li>Upload and install EXM package on the CM server.</li>
<li>Note failure message.</li>
</ol>
<h3>
Workaround/Fix</h3>
</div>
<div>
Pretty straight-forward here, but install EXM under the context of the "sitecore/admin" user.</div>
<div>
<br /></div>
<div>
I reported my error and findings/workaround to Sitecore Support and they were able to confirm that this is a bug that will be resolved in a future version of EXM.</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-18923056254834971582015-06-26T15:20:00.000-04:002015-06-26T15:20:16.056-04:00Run Multiple Solr Instances for Sitecore<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2H9snOvmPq3hBXvi6sNKXaXt78lMgcUbfCCzsiSeMm4h_nr4MIaKMMg36e5PJ68REao-deuFV2D7V54yWY357F6y1ta4gdB0u9nW8Nt1l6QuqTJgtX5mQ0GBqdJsCRsj4urtJnSf_zg/s1600/solrsolr.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Solr Solr"><img alt="Run Multiple Solr Instances for Sitecore" border="0" height="80" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2H9snOvmPq3hBXvi6sNKXaXt78lMgcUbfCCzsiSeMm4h_nr4MIaKMMg36e5PJ68REao-deuFV2D7V54yWY357F6y1ta4gdB0u9nW8Nt1l6QuqTJgtX5mQ0GBqdJsCRsj4urtJnSf_zg/s320/solrsolr.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
At <a href="http://www.arke.com/" target="_blank">Arke</a>, we have recently made the switch to recommending Solr as the 'default' indexing solution for Sitecore rather than Lucene. If you're wondering which to use on your project, please see <a href="https://dev.sitecore.net/guides/the%20role%20of%20solr%20and%20search%20in%20the%20xdb#in-which-scenarios-do-i-have-to-use-Solr" target="_blank">Sitecore's document on when to use Solr</a> over Lucene.<br />
<br />
<h3>
Switching to Solr</h3>
There was a little pain involved in switching from Lucene to Solr for an active project, but luckily, my co-worker, <a href="https://twitter.com/Patrick_Perrone" target="_blank">Patrick Perrone</a> had already been down the path of getting Solr running on his Windows machine and provided an excellent step-by-step guide on how to make it work. If you haven't already, see his 3-part series on <a href="http://sitecoreblog.patrickperrone.com/2015/02/sitecore-8-solr-part-13-install-tomcat.html" target="_blank">Making Sitecore 8 and Solr Work Together</a>.<br />
<br />
Thanks to Patrick, getting Solr running was a breeze. This worked great for my active project, but now I'm starting up new projects where Solr will be the indexing mechanism from day 1. How will I separate client Solr cores from one another?<br />
<br />
<h3>
Installing Multiple Instances of Solr on your (Windows) Machine</h3>
</div>
<div>
Patrick's install guide works great when you're only going to be running a single instance of Solr, but in order to get a second instance of Solr running on my machine, I had to make some minor modifications.<br />
<br />
Note: These steps assume you already have a solr instance up and running with the proper Sitecore-generated schemas. If you haven't followed all the steps to get Solr running with Sitecore, please do those first to save a bit of configuration time on your cores later.<br />
<br />
<ol>
<li>Stop your Tomcat service.<br /><br /></li>
<li>I installed my Solr directory at <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">C:\Solr</span> and all my standard Sitecore and custom cores were then in directories under there. In order to clean things up, I created a new folder named <span style="background-color: #eeeeee; padding: 0px 5px 0px 5px;">ClientName1</span> that would now contain the cores for that client. Go ahead and create a folder named <span style="background-color: #eeeeee; padding: 0px 5px 0px 5px;">ClientName2</span> while you're here for the project you are starting up.<br /><br /></li>
<li>Once created, pull all the content from the root of <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">C:\Solr</span> into this new <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">ClientName1</span> folder.<br /><br /></li>
<li>Since the original cores were already configured to work with Sitecore, it's a simple matter of copy/pasting all the cores into a second client folder. Copy all the files from the root of <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">ClientName1</span> and paste them into <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">ClientName2.</span> At this time, you should remove any custom cores that were defined specifically for client 1. You can leave all the Sitecore cores as we're going to rebuild them as a final step anyways to get client 2 data into them. Your Solr root should now just have client folders in it, nice and clean-like.<br /><br /></li>
<li>Go into your 'Monitor Tomcat' tool and remove the <a href="http://sitecoreblog.patrickperrone.com/2015/02/sitecore-8-solr-part-23-install-solr.html" target="_blank">Java Options you set</a> as part of the initial configuration of Solr. In my case, I removed <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">Dsolr.solr.home=C:\Solr</span> This option tells Tomcat where the home Solr directory is, but it assumes there is only one instance running. Our next steps will define the multiple home directories.<br /><br /></li>
<li>Move the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">solr.war</span> file out of the root of your <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">...\Tomcat 8.0\webapps\</span> directory. In my case, I moved the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">solr.war</span> file up one directory from <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">C:\Program Files\Apache Software Foundation\Tomcat 8.0\webapps</span> to <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">C:\Program Files\Apache Software Foundation\Tomcat 8.0\</span> Having the war file in the webapps directory is another indicator to Tomcat that it's only running a single instance and it will ignore the configuration files we are going to set in the next step.<br /><br /></li>
<li>Go to your <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">\Tomcat 8.0\conf\Catalina\localhost</span> directory and create new XML config files for each client. I named mine <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">solr-<clientNameX>.xml</span> Note that this filename will be how you access your Solr cores in the browser. In this case, I'll access my two clients by <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">http://tomcat:8081/solr-clientName1</span> and <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">http://tomcat:8081/solr-clientName2</span>. You can name them whatever you like, but the contents should look like this:<br /><br />
<div>
<pre class="brush:xml"><Context docBase="C:\Program Files\Apache Software Foundation\Tomcat 8.0\solr.war" debug="0" crossContext="true" >
<Environment name="solr/home" type="java.lang.String" value="C:\solr\ClientName1" override="true" />
</Context>
</pre>
</div>
<br />Here, you are referencing the path to the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">solr.war</span> file that we moved and are setting the Solr home directory to where all your cores are for this client.</li>
<br />
<li>Copy the XML file you just created and paste it to create the XML file for <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">ClientName2.</span> Edit the file and change the path to from the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">C:\solr\ClientName1</span> directory to the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">ClientName2</span> directory.<br /><br /></li>
<li>Start your Tomcat service back up.<br /><br /></li>
<li>Navigate to <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">http://tomcat:8081/solr-clientname1</span> and <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">http://tomcat:8081/solr-clientname2</span> and verify that both instances are running. (using the port number used when configuring Solr and the file names for the XML configs you defined)<br /><br /></li>
<li>Edit your <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">ContentSearch.Solr.ServiceBaseAddress</span> setting in the <span style="background-color: #eeeeee; padding: 0px 2px 0px 2px;">Sitecore.ContentSearch.Solr.DefaultIndexConfiguration.config</span> file to point to the correct new instance of Solr.<br /><br /></li>
<li>Once running, go back to your Sitecore instances and rebuild your indexes!</li>
</ol>
You can now safely run Solr on multiple projects and have confidence that each client's cores will not be mixed up with one another.</div>
Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4704704487040880240.post-4300128110407907092015-06-18T12:41:00.001-04:002015-06-18T15:31:06.830-04:00Sitecore 8 Bug: Link Sets Anchor Target to Active Browser<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDzjsmsr8D0pfVFRaFDsadSxff_PjvlgkVUSATUCAi6tJrKxRlc13ejBk2RRq2fFh2flHT-HdpCiUG7myAl4gAKYwCrpQ4Tiez_iWZuqAeIP1BDmm8m8nGkEFh3Fwel-c78V-pCcjEZA/s1600/chain-297842_640.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Links be broke"><img alt="Links be broke" border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDzjsmsr8D0pfVFRaFDsadSxff_PjvlgkVUSATUCAi6tJrKxRlc13ejBk2RRq2fFh2flHT-HdpCiUG7myAl4gAKYwCrpQ4Tiez_iWZuqAeIP1BDmm8m8nGkEFh3Fwel-c78V-pCcjEZA/s320/chain-297842_640.png" width="320" /></a></div>
We recently ran into an issue while trying to render links set in Sitecore 8 (Update 3, to be specific). When using the "General Link" field to insert a link, we discovered that the "target" options for the link were incorrect. The options provided out of the box were "Active Browser", "Custom" and "New Browser":<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6-PxImw20SoEDnzpGsTOwxPheW5Ua9iC9ItDNvyOB0keCvTLKXpFd0po0S2kbAK74sej2dcmm4bcXWe9HlLPaR_55Wz5Exg7bAJm43uGSrr8BVPamKg3rshOdP7DkPi8LLbFVbSrnoQ/s1600/TargetOptions.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Original Link Target Options"><img alt="Original Link Target Options" border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6-PxImw20SoEDnzpGsTOwxPheW5Ua9iC9ItDNvyOB0keCvTLKXpFd0po0S2kbAK74sej2dcmm4bcXWe9HlLPaR_55Wz5Exg7bAJm43uGSrr8BVPamKg3rshOdP7DkPi8LLbFVbSrnoQ/s320/TargetOptions.png" width="192" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
One would assume that "Active Browser" would set the target of the anchor tag to "_self" or "_top" so that it opens in the same window. Unfortunately, what happens is that Sitecore literally puts "Active Browser" in the target attribute, which is not valid and ends up actually opening a new window/tab.<br />
<br /></div>
<h3>
Workaround/Fix</h3>
<div>
I opened a support ticket with Sitecore and they acknowledged this as a bug and it should be fixed in a future release.<br />
<br />
In the meantime, you can adjust the settings of the "Link Details" box to display new target options as follows:<br />
<br />
<ol>
<li>In the "Core" database, navigate to the "/sitecore/client/Applications/Dialogs/InsertLinkViaTreeDialog/PageSettings/TargetsSearchPanelConfig" item.</li>
<li>In the "Root" field of the "Filters" section, specify the "sitecore/client/Business Component Library/System/Texts/Targets" item. (default is "sitecore/client/Applications/Dialogs/InsertLinkViaTreeDialog/PageSettings/Targets")</li>
</ol>
<div>
Now, when you insert a link, you see target options that will work when rendered in the browser: "_blank", "_parent" and "_top":</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyooYKLStypUKX7Wem5lksp3IAzpwW366reHG9fhxLVSZ4qJEbHHATCLkkqmM3kVCYqrqhidy8dfd5vCflt6vRWjp7SRQjfVK3YEDvqGL3Z-dHD3oMN2JA7vX_0jhFHFz38NpUBrzNSQ/s1600/TargetOptions_fixed.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Updated Link Target Options"><img alt="Updated Link Target Options" border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyooYKLStypUKX7Wem5lksp3IAzpwW366reHG9fhxLVSZ4qJEbHHATCLkkqmM3kVCYqrqhidy8dfd5vCflt6vRWjp7SRQjfVK3YEDvqGL3Z-dHD3oMN2JA7vX_0jhFHFz38NpUBrzNSQ/s320/TargetOptions_fixed.png" width="206" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Note: If you already had links set to "Active Browser", leaving the default of "SelectTarget" will still render the target as "Active Browser." You need to open the "Insert Link" option, select "Insert" and then save the item for it to use the proper value.</div>
</div>
Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4704704487040880240.post-11033031433439939212015-05-22T10:29:00.000-04:002015-05-22T10:34:34.367-04:00Map a Drive to your Solution Folder to Avoid the File Name Length Error in TDS<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjxNBkXtkA6LiS51WW_LMDHYIW_eNclicO4IolBmlafps7zw7Fz5CiXCOMxwJdR0mLWhJ79yUAiZxprEhyphenhyphen07dy8PATA6BFPUtytJjkW7USJ8pA36G_vfGQTOi777fj_VfRLhjLhQlPbQ/s1600/centimeter-2261_1280.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Keep that length in check"><img alt="Map a Drive to your Solution Folder to Avoid the File Name Length Error in TDS" border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjxNBkXtkA6LiS51WW_LMDHYIW_eNclicO4IolBmlafps7zw7Fz5CiXCOMxwJdR0mLWhJ79yUAiZxprEhyphenhyphen07dy8PATA6BFPUtytJjkW7USJ8pA36G_vfGQTOi777fj_VfRLhjLhQlPbQ/s320/centimeter-2261_1280.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
I recently came across an <a href="http://www.hhogdev.com/blog/2015/may/tds-file-name-length-issue.aspx" target="_blank">article</a> that was posted on Twitter about overcoming the dreaded 'File Name Length Error' in Team Development for Sitecore (TDS).<br />
<br />
The article makes users aware of a built-in feature of TDS that allows you to use name aliases to overcome length issues. In my experience, this generally works, but there are always times down the road where no amount of short aliases help due to the nested structure of your Sitecore solution combined with where you save your Visual Studio solution files on your dev machine.<br />
<br />
What I like to do is map a drive to my solution files. This takes my path from "C:\Users\ctaylor\Documents\Visual Studio 2013\Projects" to "Z:\". <br />
<br />
I haven't seen the error in a while, but should I encounter it in the future, I can additionally utilize the alias feature of TDS.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-38497685546287639232015-03-28T01:34:00.004-04:002015-03-28T01:38:19.331-04:00Restore Access to an Administrator Account<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDfzSAjaIlAczWtyGvjy27kCYWZtGLuP2xju4eDR8_FAwSMyzqNT_NgsnybasX7NWeoW7ZdoJxud9aiaQWZ3fQsaNQbnk_2dzITdiY9dREE7ZnS5Bqfc1aBzhiaBkbRy-Yc1UEuAhkFQ/s1600/security-146536_640.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDfzSAjaIlAczWtyGvjy27kCYWZtGLuP2xju4eDR8_FAwSMyzqNT_NgsnybasX7NWeoW7ZdoJxud9aiaQWZ3fQsaNQbnk_2dzITdiY9dREE7ZnS5Bqfc1aBzhiaBkbRy-Yc1UEuAhkFQ/s1600/security-146536_640.png" height="320" width="229" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
For additional security, one of the first things I do when beginning work on a new Sitecore site is to remove the 'standard' "admin\b" account and instead create a new admin account with a different name (and password, of course!). After doing this recently, we ran into a problem when the password for the new account was . . . lost.<br />
<br /></div>
<h3>
Existing Functionality</h3>
<div>
There are some Sitecore tools designed to help manage accounts and access when the administrator user is unable to log in. Unfortunately, the tools both assume that the user you are using is the 'standard' "admin" account and also that you haven't lost the password, but instead have been locked out of the account. See <a href="http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2012/11/restoring-administrative-access-to-the-sitecore-aspnet-cms.aspx" target="_blank">John West's post</a> regarding some common ways to get back in.<br />
<br />
As John mentions, when the administrator password has been lost, you can simply log in with another account with administrator access in order to reset the password of the first account. In our case, we only had one administrator account and had no way to get in otherwise.<br />
<br />
The solution is to modify an existing tool.<br />
<br /></div>
<h3>
Modify the "unlock_admin.aspx" Page</h3>
<div>
The "unlock_admin.aspx" page can be found at "/sitecore/admin/unlock_admin.aspx" Unsurprisingly, the purpose of this page is to unlock the "sitecore\admin" account. What we need to do is use this page to grab our admin user and reset the password. The existing code only unlocks the locked admin account:<br />
<br /></div>
<div>
<pre class="brush:csharp">Membership.GetUser("sitecore\\admin").UnlockUser();</pre>
</div>
<div>
You can instead replace this with code that will set a password on any account in Sitecore:</div>
<br />
<div>
<pre class="brush:csharp">MembershipUser mu = Membership.GetUser("sitecore\\[Your Administrator Account]");
mu.ChangePassword(mu.ResetPassword(), "[Your New Password]");</pre>
<div>
<br />
This code takes advantage of the .NET membership provider in order to change the password of the account specified. Enable the button, view the page in the browser, click the button and you're done! The password is changed and you can now log back in! <br />
<br />
Just try not to lose the password this time.<br />
<br />
Note: As John mentions in his <a href="http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2012/11/restoring-administrative-access-to-the-sitecore-aspnet-cms.aspx" target="_blank">post</a>, always remember to go back and disable the 'unlock' button. Also, while I have provided a solution that resets an administrator account password, please don't deploy this file. It should only be used temporarily to get back into Sitecore.</div>
</div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4704704487040880240.post-22339774635942784172015-02-23T17:54:00.001-05:002015-03-28T14:41:08.299-04:00Cascading Renderings in Sitecore 8<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyligysbjm0RiLVNrllgYMrvea3P2UxolOake1iQHNHf6ECwzrjKePBysrZlfh1DUlNzXazwaQjYhjUUcSaa1xk1C-mFalGElo-QDDR3vJH1zzhbNTcTgBlHS3qmNuj-qDASiTAMeWKg/s1600/SitecoreFinalLayout.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Cascading Renderings in Sitecore 8"><img alt="Cascading Renderings in Sitecore 8" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyligysbjm0RiLVNrllgYMrvea3P2UxolOake1iQHNHf6ECwzrjKePBysrZlfh1DUlNzXazwaQjYhjUUcSaa1xk1C-mFalGElo-QDDR3vJH1zzhbNTcTgBlHS3qmNuj-qDASiTAMeWKg/s1600/SitecoreFinalLayout.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
I have a client that has a need to have managed content within their navigational menu. We were able to dynamically insert placeholders and control the datasources for the renderings inserted. When we went to another page in the site, we realized that the renderings we inserted were only associated with the original page instead of the entire site as we intended. We needed to cascade the renderings down to all the subpages.<br />
<br /></div>
<h3>
It's been done before</h3>
<div>
There are already some great starting points out there from <a href="http://sitecoreblog.alexshyba.com/2012/02/cascading-renderings-in-sitecore-page.html" target="_blank">Alex Shyba</a> and <a href="http://jockstothecore.com/cascading-mvc-renderings-in-sitecore-7/" target="_blank">Pavel Veller</a>. Alex originally wrote about it and Pavel updated the code to work with MVC. Thanks guys!<br />
<br /></div>
<h3>
One small change</h3>
<div>
With Sitecore 8 comes the idea of Versioned Layouts. Since we can now have a shared and final layout, the code should be updated to check the "FinalLayoutField" so that we have access to any renderings added using the Experience Editor.<br />
<br /></div>
<div>
<pre class="brush:csharp">Field layoutField = parent.Fields[FieldIDs.LayoutField];
</pre>
</div>
<div>
needs to be changed to:</div>
<br />
<div>
<pre class="brush:csharp">Field layoutField = parent.Fields[FieldIDs.FinalLayoutField];
</pre>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4704704487040880240.post-36264665248583115952014-12-17T02:19:00.000-05:002014-12-17T02:22:40.494-05:00Create a Custom Condition in Sitecore 7.1+<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwNPIcpnmxVOGNl1euzbvAaFdPebEx2sSoSIqp0aMT73YyVAV4mIe_6wzyqi9bQZ38a13js_8WFLKb02ZK8NomMHkTRdjyfLPD0PUQgJKmFAxHSPPaRoAavuCyUaJi0nZEW3Slj3qXsw/s1600/Show_New_Condition.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" title="Custom Sitecore Condition"><img alt="Custom Sitecore Condition" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwNPIcpnmxVOGNl1euzbvAaFdPebEx2sSoSIqp0aMT73YyVAV4mIe_6wzyqi9bQZ38a13js_8WFLKb02ZK8NomMHkTRdjyfLPD0PUQgJKmFAxHSPPaRoAavuCyUaJi0nZEW3Slj3qXsw/s1600/Show_New_Condition.png" style="width: 320px;" width="320" /></a></div>
A while back, I wrote a blog post on <a href="http://www.craigtaylor.us/2013/12/creating-http-referrer-condition.html" target="_blank">Creating an HTTP Referrer Condition</a> in Sitecore 6.6. I actually referenced that same post recently when attempting to create a custom condition in Sitecore 8. To my surprise, things have changed a bit. I had to backtrack a bit, but discovered that the process for implementing custom conditions that show under a custom section title in the personalization interface actually changed in 7.1.<br />
<br />
The process for creating the custom condition in code has remained the same, but the way in which you insert that condition into Sitecore has been updated. Let's walk through how to create and use a custom condition in Sitecore 7.1 through at least Sitecore 8.<br />
<br />
<div>
<h3>
Why Create a Custom Condition?</h3>
<div>
There are a number of built-in conditions that can be used in order to personalize Sitecore components. Sometimes however, you run across a client that has needs that extend beyond those of the pre-canned conditions.<br />
<br /></div>
<h3>
Create a new Tag</h3>
</div>
<div>
Create a new Tag item at "\sitecore\system\Settings\Rules\Definitions\Tags".<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipdKNsiJ1RpvdqBv67XKnu0oB5iulqyJ4m4wWtQp8ke-q0hz9fuW3crdNrtHHlPk29LaUQdxQPuVVbWiNh8ieEFh2dD57LODRnh0o7gfCj6u9Zjx80UEiNgLT4OWM2vQx6eaFGeNgITQ/s1600/New_Tag_Created.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Create new tag"><img alt="Create new tag" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipdKNsiJ1RpvdqBv67XKnu0oB5iulqyJ4m4wWtQp8ke-q0hz9fuW3crdNrtHHlPk29LaUQdxQPuVVbWiNh8ieEFh2dD57LODRnh0o7gfCj6u9Zjx80UEiNgLT4OWM2vQx6eaFGeNgITQ/s1600/New_Tag_Created.png" height="200" /></a></div>
<br /></div>
<div>
We will later be associating this tag with our custom Element Folder. For our purposes, I named the tag "Client Name".<br />
<br /></div>
<h3>
Add Your Tag to the Conditional Renderings</h3>
<div>
Once your tag is created, you want to associate it with the conditional renderings. This ultimately allows your custom conditions to be displayed when attempting to peronalize a component. <br />
<br />
Add the new tag to the "Default" Tag Definition item at \sitecore\System\Settings\Rules\Conditional Renderings\Tags\Default." Specifically, you want to include your tag in the "Tags" field of the "Taxonomy" section of the "Default" Tag Definition item.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU9VhFKX_cXyaBctTvF07ONp2i5IoquCMR9fYGKK5sLCyM_P1wthcm0poCQkBb3yOyZ1P5xd3yhkA35cGK3UvsrerR7T8JTK2K-Pjgww76p6iDOREkfFWVFIPEXDoyWPJJN3biJEG1Fw/s1600/Add_Tag_to_Taxonomy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Add new tag to default tag definition"><img alt="Add new tag to default tag definition" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU9VhFKX_cXyaBctTvF07ONp2i5IoquCMR9fYGKK5sLCyM_P1wthcm0poCQkBb3yOyZ1P5xd3yhkA35cGK3UvsrerR7T8JTK2K-Pjgww76p6iDOREkfFWVFIPEXDoyWPJJN3biJEG1Fw/s1600/Add_Tag_to_Taxonomy.png" height="175" width="320" /></a></div>
<br /></div>
<h3>
Create a New Element Folder</h3>
<div>
The name of your Element Folder will be the name of the grouping of conditions that you create. You can break out your conditions based on the type of condition but I find it more beneficial for clients to just create an Element Folder that is named after the name of the client. This allows the client easy access to all their custom conditions.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz3bOw9YWL9_rg4P2C8MfrxYmsYZFQe4H8Dar3buv8OaXmTibgM8Z1HWKfnsu6YSscgagCmBh44yC3ggBP5ngSXE37w_bOH8I995-vCHzEZGXFz9Rcq1QZ5RANZV3dDakylyCSxmlv8w/s1600/Tagging_Element_Folder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Create new element folder"><img alt="Create new element folder" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz3bOw9YWL9_rg4P2C8MfrxYmsYZFQe4H8Dar3buv8OaXmTibgM8Z1HWKfnsu6YSscgagCmBh44yC3ggBP5ngSXE37w_bOH8I995-vCHzEZGXFz9Rcq1QZ5RANZV3dDakylyCSxmlv8w/s1600/Tagging_Element_Folder.png" /></a></div>
<br /></div>
<div>
<div>
After creating your Element Folder, associate the Tag created earlier so that our folder will show when attempting to personalize a component.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjK0n6vPWXljcUthr398rtMg3zpBNqeF1PiWVsG35qvn_frAfkJjlqzWqJMH8GO6d6X5LZoaREj1vpnd-2zwT4eUPm44nd2ZwhYL5UnT9UOIvRXe6jQ2v3bGtJsZGr_9lZAZPqafx8oow/s1600/Tagging_Select_Default_Tag.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Select tag"><img alt="Select tag" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjK0n6vPWXljcUthr398rtMg3zpBNqeF1PiWVsG35qvn_frAfkJjlqzWqJMH8GO6d6X5LZoaREj1vpnd-2zwT4eUPm44nd2ZwhYL5UnT9UOIvRXe6jQ2v3bGtJsZGr_9lZAZPqafx8oow/s1600/Tagging_Select_Default_Tag.png" height="180" width="320" /></a></div>
<br /></div>
<div>
<h3>
Create your Condition</h3>
Once you have your Element Folder, you need to create your custom condition. As mentioned, this part remains the <a href="http://www.craigtaylor.us/2013/12/creating-http-referrer-condition.html" target="_blank">same as in previous versions</a> where you write custom code to perform some action that returns a boolean value that Sitecore can test against.<br />
<br />
Instead of duplicating this code, I'm going to create a test condition under my "Client Name" Element Folder in order to demonstrate the functionality.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5oCR6nqtQx7offhHkceS0CkP_8NqXP9f9awGbBiyFMx-7j-vegmX70xw8Mtl7vcfyXMLd5PKBHBQjnMnnJxiER0L82W_64wiqZg8jnnO5UqRR0y1FR_izBruBdHHg9rGOOkN1CqqlTw/s1600/Tagging_Test_Condition.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Create test condition"><img alt="Create test condition" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5oCR6nqtQx7offhHkceS0CkP_8NqXP9f9awGbBiyFMx-7j-vegmX70xw8Mtl7vcfyXMLd5PKBHBQjnMnnJxiER0L82W_64wiqZg8jnnO5UqRR0y1FR_izBruBdHHg9rGOOkN1CqqlTw/s1600/Tagging_Test_Condition.png" height="194" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i><br /></i></div>
<div class="separator" style="clear: both; text-align: left;">
<i><b>Note</b>: You would ordinarily have some more complex text that would allow users to select different operators to test conditions. You would also specify the type of your custom condition.</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h3>
Personalize!</h3>
</div>
</div>
<div>
We've done all the configuration work and now we just want to take advantage of the custom condition. Open the Experience/Page Editor and choose a component to personalize. After choosing "Create/edit the personalization options for this component" button, click "New Condition". Give your condition a name and select "Edit" to find the condition you created.<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwNPIcpnmxVOGNl1euzbvAaFdPebEx2sSoSIqp0aMT73YyVAV4mIe_6wzyqi9bQZ38a13js_8WFLKb02ZK8NomMHkTRdjyfLPD0PUQgJKmFAxHSPPaRoAavuCyUaJi0nZEW3Slj3qXsw/s1600/Show_New_Condition.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" title="Personalize your component"><img alt="Personalize your component" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwNPIcpnmxVOGNl1euzbvAaFdPebEx2sSoSIqp0aMT73YyVAV4mIe_6wzyqi9bQZ38a13js_8WFLKb02ZK8NomMHkTRdjyfLPD0PUQgJKmFAxHSPPaRoAavuCyUaJi0nZEW3Slj3qXsw/s1600/Show_New_Condition.png" height="229" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
And there you have it. We created a custom condition and configured Sitecore to be able to show it under a custom Element Folder so that content author have easy access to it.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<div>
</div>
</div>
Unknownnoreply@blogger.com1