Tuesday, November 20, 2018

Thank You Community Leaders 2018

Another year to be thankful. There are so many people in the community that I learned from this past year. I appreciate the time and energy they invest into me and others that I thought recognizing them would be appropriate.

My wife and I celebrated the birth of our first baby (Bella). Was so awesome to be gifted with a baby onsie for Bella. She loved it!


Community Members

Below are some people I had the opportunity to learn more about this year.


  • Corey Smith - I really enjoy talking with this smart guy about Sitecore and SXA. I recall a phone call we once had about something I had been working on; so encouraging to hear his feedback. He too shared some really cool things with me and the community. His contributions to JSS have been phenomenal. One time he even shaved his mustache off for the benefit of a beloved community member. I look forward to seeing him succeed in 2019. 
    No mustache.
  • Una Verhoeven - What a renaissance woman! She achieved just about all the community badges possible in 2018. Exciting that she was honored with the MVP award this year. I look forward to hearing about her new job in 2019 and celebrating her new achievements. 
    Enjoying her vacation, not thinking about work.
  • Saad Ansari - Sitecore Sam has been so helpful this year. Nice to see someone invest time in crafting quality blog posts (with nice imagery). Always finds an opportunity to help answer questions. What a great future MVP. 
    Actual photo of Saad.
  • Neil Shack - One of the best examples of a generous person. He was handing out this super cool book of Sitecore tips like it was candy. So good. Was great getting to visit with him again at the Sitecore Symposium. Not a bad housemate either!
    Thomas holding the book. Neil on the right.
Some other community members that I appreciate were shared in this previous post. Please read about it and tell them how much of a positive impact they had on you.

Final Thoughts

I encourage you to show your appreciation for those that have really helped you. Consider recommending those same people for Sitecore MVP. Also, try not to DM those people on Slack for support; stick to the group channels and only shift to the DM when they invite you to do so.

Monday, November 5, 2018

Override SXA Environment Site Resolver

In this very short post I demonstrate how to override the EnvironmentSiteResolver included with SXA to remove the use of fast queries.

This was tested on Sitecore 8.2.7 and SXA 1.7.0. Most of this is copied from the SXA library Sitecore.XA.Foundation.Multisite. I changed ResolveAllSites to call the local function GetContentItemsOfTemplate instead of the extension method. Then GetContentItemsOfTemplate calls the link database for items.

Thank you to my friend Corey Smith for his help in cleaning up the copy/paste mess that was in my initial version.

44644 13:45:34 WARN [Unicorn] A Fast Query was performed and Unicorn had one or more configurations enabled that used Transparent Sync. Fast Query is not supported with Transparent Sync. Either stop using Fast Query (it's generally regarded as a bad idea in almost every circumstance), or disable Transparent Sync for all configurations.
44644 13:45:34 WARN [Unicorn] The Fast Query was: //*[@@templateid = '{EDA823FC-BC7E-4EF6-B498-CD09EC6FDAEF}']
44644 13:45:34 WARN [Unicorn] The call stack that made the Fast Query was: at Unicorn.Data.DataProvider.UnicornSqlServerDataProvider.QueryFast(String query, CallContext context)
at Sitecore.Data.DataProviders.DataProvider.SelectIDs(String query, CallContext context, DataProviderCollection providers)
at Sitecore.Data.DataManager.SelectItems(String query, Boolean& processed)
at Sitecore.Data.DataManager.SelectItems(String query)
at Sitecore.Data.DefaultDatabase.SelectItems(String query)
at Scms.Foundation.Multisite.SiteResolvers.ScmsEnvironmentSitesResolver.<GetContentItemsOfTemplate>d__4.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Scms.Foundation.Multisite.SiteResolvers.ScmsEnvironmentSitesResolver.ResolveAllSites(Database database)
at Sitecore.XA.Foundation.Multisite.Providers.SxaSiteProvider.GetSiteList()
at Sitecore.XA.Foundation.Multisite.Providers.SxaSiteProvider.InitializeSites()
at Sitecore.XA.Foundation.Multisite.Providers.SxaSiteProvider.GetSites()
at System.Linq.Enumerable.<SelectManyIterator>d__17`2.MoveNext()
at Sitecore.Sites.SiteCollection.AddRange(IEnumerable`1 sites)
at Sitecore.Sites.SitecoreSiteProvider.GetSites()
at Sitecore.Sites.DefaultSiteContextFactory.GetSites()
at Sitecore.XA.Foundation.Multisite.SiteInfoResolver.get_Sites()
at Sitecore.XA.Feature.Search.Pipelines.Initialize.InitializeRouting.Process(PipelineArgs args)
at (Object , Object )
...
using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Data.Managers;
using Sitecore.Data.Templates;
using Sitecore.Diagnostics;
using Sitecore.XA.Foundation.Multisite;
using Sitecore.XA.Foundation.Multisite.Comparers;
using Sitecore.XA.Foundation.Multisite.SiteResolvers;
namespace Scms.Foundation.Multisite.SiteResolvers
{
public class ScmsEnvironmentSitesResolver : IEnvironmentSitesResolver
{
private readonly IEnvironmentSitesResolver _environmentSitesResolver;
public ScmsEnvironmentSitesResolver(IEnvironmentSitesResolver environmentSitesResolver)
{
_environmentSitesResolver = environmentSitesResolver;
}
public IList<Item> ResolveAllSites(Database database)
{
var objList = (database != null ? GetContentItemsOfTemplate(database, Templates.SiteDefinition.ID).ToList() : null) ??
new List<Item>();
objList.Sort(new TreeOrderComparer());
return objList;
}
public IList<Item> ResolveEnvironmentSites(List<Item> sites, string environment)
{
return _environmentSitesResolver.ResolveEnvironmentSites(sites, environment);
}
public string GetActiveEnvironment()
{
return _environmentSitesResolver.GetActiveEnvironment();
}
public IList<string> ResolveEnvironments(IEnumerable<Item> sites)
{
return _environmentSitesResolver.ResolveEnvironments(sites); ;
}
public static IEnumerable<Item> GetContentItemsOfTemplate(Database database, ID templateId)
{
if (database == null) yield break;
var selectedTemplate = TemplateManager.GetTemplate(templateId, database);
if (selectedTemplate == null) yield break;
var descendants = selectedTemplate.GetDescendants();
var templateArray = new Template[1]
{
selectedTemplate
};
var templates = descendants.Concat(templateArray);
var watch = new System.Diagnostics.Stopwatch();
watch.Start();
var linkDb = Globals.LinkDatabase;
foreach (var template in templates)
{
var templateItem = database.GetItem(template.ID);
var items = linkDb.GetReferrers(templateItem)
.Select(link => link.GetSourceItem());
foreach (var item in items.Where(item => item.Paths.IsContentItem)) yield return item;
}
watch.Stop();
Log.Info($"Completed loading sites in {watch.ElapsedMilliseconds} ms.", typeof(ScmsEnvironmentSitesResolver));
}
}
}
using Microsoft.Extensions.DependencyInjection;
using Scms.Foundation.Multisite.SiteResolvers;
using Sitecore.DependencyInjection;
using Sitecore.XA.Foundation.Multisite;
using Sitecore.XA.Foundation.Multisite.SiteResolvers;
namespace Scms.Foundation.Multisite.Pipelines.IoC
{
public class RegisterServices : IServicesConfigurator
{
public void Configure(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<IEnvironmentSitesResolver, ScmsEnvironmentSitesResolver>(sp =>
{
var innerResolver = new EnvironmentSitesResolver();
return new ScmsEnvironmentSitesResolver(innerResolver);
});
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<services>
<configurator type="Scms.Foundation.Multisite.Pipelines.IoC.RegisterServices, Scms.Foundation.Multisite"/>
<register serviceType="Sitecore.XA.Foundation.Multisite.SiteResolvers.IEnvironmentSitesResolver, Sitecore.XA.Foundation.Multisite"
implementationType="Sitecore.XA.Foundation.Multisite.SiteResolvers.EnvironmentSitesResolver, Sitecore.XA.Foundation.Multisite" lifetime="Singleton">
<patch:delete />
</register>
</services>
</sitecore>
</configuration>