Working with Media Items from code

The Media Library in Sitecore is primarily used for images and other editor-driven files, such as pdf documents etc. Media items are basically just regular items, but with a blob field that can store binary data. So this can be used for more things.

One use case can for example be storing sitemap.xml files. Those files can sometimes be quite compute intensive to render. Search engines rarely loads those, so making a scheduled background job, that runs a few times per day is more than enough. The rendered sitemap file(s) can then be stored as a media item and streamed when requested. Since they’re just regular items, you can simply make it read-only and put file permissions on it to prevent regular editors from playing with them.

“AttachStreamToMediaItem” may not do what you think it does.

Continue reading

TreeList(Ex) field type with multiple roots

The built-in Sitecore TreeList and TreeListEx field types have quite many options and can be configured to become very user friendly for authors. However, I’ve been missing a few pieces to make it even more user friendly.

One of the things I’ve been missing the most is the ability to have multiple queries in the TreeList Source field, making it possible for authors to select items from multiple roots. This could for example be the ability to select items located close to the currently edited item or items shared on a site level or items shared on a tenant level. By default, you basically have to show the entire Sitecore tree in this scenario.

So what if we could have multiple Sitecore queries specified in the template field Source value? We could make a pipe separated list of queries that would return a smaller, more user friendly set of items. This is actually already supported in Sitecore, but only in the Datasource Location of a rendering.

TreeListEx with Multiple roots
Continue reading

Editing Sitecore item from code: revision and publishing considerations

I’ve noticed some people are struggling with updating items from code and making it publish properly, with Sitecore Publish Service (SPS) in particular. So I thought I’d just share how I usually deal with some of the related issues you may run into. I’m mainly using SPS, so this post is mostly targeting that scenario, but it is probably valid for solutions using the old way of publishing as well. Nothing here is really SPS unique.

Continue reading

Field type validator for links

Today I found a missing piece in the default item tree of a Sitecore instance. I did the finding on 9.3, so this may not apply to other Sitecore versions.

Background

There are basically a few different types of validators in Sitecore.

  • Field Rules (/sitecore/system/Settings/Validation Rules/Field Rules) are assignable to individual fields on a template and validates the content of a field.
  • Item Rules (/sitecore/system/Settings/Validation Rules/Item Rules) are assignable to items, typically to a template through __Standard values, and validates the content of an item as a whole. This could be item naming, structure, combination of field values etc.
  • Field Types (/sitecore/system/Settings/Validation Rules/Field Types) are Field Rules that apply to all instances of a field type. This could for example be validating URLs of all link fields in all items in the entire database.
  • Global Rules (/sitecore/system/Settings/Validation Rules/Global Rules) are Item Rules that apply to all items in the entire database.

The missing piece

There are two very similar field types in Sitecore: “General Link” and “General Link with search”. Internally they work exactly the same. It’s basically just the UI that’s slightly different. In most scenarios, I’d say the later one is preferred.

However, the Field Types validators only contains a “General Link” item. There is no “General Link with search” item, so no field type validators will be executed when you use this field type.

It’s a simple fix though. Just duplicate the “General Link” item and name it “General Link with search” and you’ll get validation rules on that field type as well. If you use both those field types in your solution, remember to keep those validator settings in sync.

No dots in Sitecore commands

Creating Sitecore commands is a powerful way to add additional functionality into a Sitecore solution. Commands are typically triggered by a Sitecore editor from the UI. It can be a ribbon button, a context menu or something else. The button/action fires a command name that is routed to a class inheriting the Command base class. This routing is typically defined in the commands section in the Sitecore config:

<configuration>
  <sitecore>
    <commands>
      <command name="nameofcommand" type="namespace.class, assembly" />
    </commands>
  </sitecore>
</configuration>

The command names are usually grouped, such as item:open, item:preview and so on. I like to include the project name I’m working on, or something in all my command names, so that I can easily distinguish my commands from Sitecore commands or commands provided by third party modules.

Today I found that command names cannot contain dots. If the command name contains a dot, it causes a JavaScript exception in the Sitecore UI and the command fails. So basically you can’t create a command like myproject:item.cleanup or myproject.item:cleanup. But a command names like myproject:item:cleanup will work just fine.

Sitecore Content Editor depends on the Referer http header

My today’s Sitecore discovery was that the Sitecore Content Editor have code that is dependent on what’s sent in the Referer header. (Yes, it’s incorrectly spelled in the HTTP standard.)

TL;DR: Set “Referrer-Policy” to “same-origin”. Most other sensible configurations will break Sitecore.

I’ve been working on a project where I found that the content search functionality didn’t work properly in the Content Editor. I found that search results were not limited to the scope of the context item, i.e. results from the entire database was always returned. I also found that no matter how I configured my custom facets, only the global facet where used.

I was just about to file a support ticket for this, and decided to reproduce this in a clean solution and found that it worked just as expected. So obviously we had done something in our solution that broke it. So I started to remove all our own config files, starting with content search related files, but I couldn’t get it working unless I did a full reset of my local development environment. So something fishy was going on here.

So I hocked up the symbol server in dotPeek and started debugging. Soon I found that the FacetSearcher.GetFacets() always returned just the global facet regardless if I had local facets. This was due to the startLocationItem variable always being the Sitecore root item. Strange…

Digging deeper, I eventually found that the SearchHttpTaskAsyncHandler have a LocationFilter property that reads an id parameter from the query string of the referrer header. If the id parameter wasn’t present, it would just use the Sitecore root item id.

So now I knew the probable cause of this. And yes, we’ve tried to follow most web security best practices in this project, so we had opted for setting the Referrer-Policy http header to strict-origin. This basically means that just the domain name would be sent in the Referer header. Not path nor query string.

So the takeaway from this is to set the Referrer-Policy header to same-origin on the CM role. Never set it to anything that disallows sending the query string to the origin site, i.e. don’t use no-referrer, origin or strict-origin.

But if I removed all we’ve followed most security best practices, such as using proper CSP headers etc. So in this solution we had the Referrer-Policy header set to strict-origin. I.e. the visiting browser would basically just send the domain name and not the path or query string.

Looking a bit deeper in the Sitecore assemblies, it turns out there’s quite many usages of request.UrlReferrer.

An important breaking change in Sitecore Item DisplayName

Sitecore has been using the unversioned standard field “__Display name” along with the built-in “Name” for as long as I can remember. Basically, the item Name is similar to a shared field and is limited to small set of characters. An item name can basically be A-Z, a-z, 9-0, space and a few special characters, such as underscore (_), dash (-), dollar-sign ($). It may also be a single star (*).

Since the Name is very limited, the __Display name fields allows users give item more user friendly names. Since it’s persisted in an unversioned field, it also allows for translation. The Sitecore.Data.Items.Item class has a convenience read-only DisplayName property that returns the content of the __Display name field, if set, otherwise it fallbacks on the item Name. This principle is used basically everywhere in Sitecore. It’s used when rendering the item tree, as link text on rendered links and so on.

In Sitecore 9.2 (I believe), Sitecore made a small, but very important breaking change on how the Display Name works. I can’t recall seeing this change been noted in any release notes either, but I might have missed it.

Update: I realize I’ll need to keep updating to this post as I receive more input. I’ll keep them the bottom of the post.

Continue reading

Why TDS may want to sync non-existing item versions

I recently ran into a strange issue where I noticed TDS wanted to sync a lot of item versions that didn’t exist. It took me a while before I nailed what was actually causing this. In the example below, the “Home” item only have a “en” language version. There is no version on the other languages. Still, TDS wants to serialize many more languages.

If I serialize this item into disk, it indeed adds all these versions as well.

Note: This is not a problem with TDS itself. It’s a consequence of a faulty database.

Continue reading

Sitecore “Switchers”

Sitecore has tons of “Switchers” that are pretty useful in many scenarios. You’re probably familiar with a few of them, such as EditContext, SecurityDisabler and LanguageSwitcher. Others are less known but very valuable when needed.

Switchers temporary puts Sitecore in a different mode for a piece of code and then restores it to its previous mode when done. A typical usage would look something like this:

using (new LanguageSwitcher(lang)) {
  // perform custom operations on "lang" instead of the context language
}

I made a list of common, and not so common switchers. Hope you find some of them useful.

Continue reading

Improved Sitecore Links Database provider

I have a somewhat love and hate relationship to the Sitecore Links Database. It’s really useful in some scenarios, especially in scenarios such as integrations, batch operations etc., where a Solr index or similar might not accurate enough. The Links Database has also caused me many performance headaches over the years due to some issues with its implementation.

The main problem with the default Links Database Provider is that it performs multiple small synchronous SQL “insert” and “delete” operations in the database. As the Sitecore databases grows, so does the Links table. With many insert/delete operations, the table indexes becomes very fragmented and it slows down the system. The application performance may also be quite heavily effected if latencies to SQL Server is increased.

I’ve had on my radar for a few years to write a new one. Finally I made some time to improve the implementation a bit and put it on GitHub.

Continue reading

Generating predictive Sitecore ID’s

Sitecore ID’s, or Guids, are many times great as content can be created in different places and be moved between databases without facing the risk of colliding id’s. When integrating stuff into Sitecore, you may need to represent some data as Items. When you author new content in Sitecore that references such imported data, it suddenly becomes a bit trickier to move data between instances etc. You’d basically have to transfer all the integrated data as well to ensure data consistency. It also removes the ability to just remove integrated data and re-run the process, as it would generate new IDs.

So what if we could integrate data from an external source and represent it as items with a predictive Sitecore ID? I.e. give each item a unique ID that won’t collide with anything else, but will always become the same every time the process is run in every system.

Continue reading

Dealing with Solr Managed Schema through Sitecore config files

When working with Content Search and Solr in Sitecore, it’s quite common that a field needs to be managed in both Sitecore and Solr. It can for example be a computed field or a basic field where you want specific field processing etc. where you need to slightly change the Solr schema. Having the configuration for such scenario split in two places can be quite annoying.

I while ago, I wrote a small module that’ll let you put your Solr Managed Schema configuration as part of the standard Sitecore configuration. This gives a better overview and configuration that plays together, stays together.

The module adds a new <solrManagedSchema> section in the contentSearch/indexConfiguration-section. The content of this section is almost identical to what you’d put in the Solr schema. The only difference is that fields, field types, dynamic fields and copy-fields are grouped separately with a Sitecore “hint” attribute.

Let’s describe the benefits of this with an example. Let’s say you need a computed field returning a set decimal numbers, like a set of variant specs etc. You’d obviously need the computed field class itself, but you’d also need to do a type match (because list of floats are not within the default mapping) and you’d need to modify the schema to support fields with multiple floats. The configuration could end up something like this:

Continue reading

Sitecore Azure Blob Storage module findings

A few years ago, I wrote about storing Sitecore binaries in an external blob storage service instead of having them in the database. You can read more about it here and the code is available on GitHub. It has several benefits and it works great! I’ve used this implementation in production on large scale solutions for many years.

In Sitecore 9.3, Sitecore introduced its own Azure Blob Storage module, that uses the same principles. Sitecore also slightly changed how databases are configured, so my old module works up to 9.2 as it is right now.

Since Sitecore supports for their own module, it makes sense to use that one instead of running a custom one. However, in true Sitecore spirit, the module was released without testing, so beware of the findings below before using it:

Update: Sitecore have issued a cumulative update to Sitecore 9.3 that addresses the two major faults described in this post. Make sure you have SC Hotfix 415404-1 or later installed.

Continue reading

Prevent Sitecore editors playing around with rendering cache options

Caching of renderings is a vital part of good performing Sitecore websites. Getting all the settings right aren’t trivial and it’s really only the developers of components that knows the details about how each component can be cached. Therefore caching options are typically managed on the rendering items and kept serialized together with solution source.

However, rendering cache options can also be set on a rendering in the layouts field when it’s used on a page. This is done in the “Control Properties” dialog. Personally I’ve never found a use case where this is needed, but the option is there.

Whether a user has access to the rendering parameters in the “Control Properties” dialog is controlled by “write” access to the Standard Rendering parameters template’s standard value. Sigh!

Continue reading

Faster indexing in Sitecore

Sitecore indexes is very powerful for getting various items fast, especially when they are located in various places. There are also some pitfalls that one needs to be aware of. This post covers methods that could be considered in some scenarios. In this post I’ll describe how I reduced indexing time from around three hours down to two minutes for a specific scenario.

Continue reading

Installing Content Hub CMP connector to Sitecore CM having Publish Service installed

There is a dll version conflict for Polly.dll between Sitecore CMP connector and Sitecore Publish Service 4.1.0. The Publishing Service Module comes with Polly.dll version 5.9.0 and the Sitecore Connect for CMP 1.0.0 comes with Polly 6.0.1. This will cause Sitecore CM to stop working during the CMP install, if the SPS module is already in the system.

Update: As Sitecore 9.3 and SPS 4.2.0 was just released a few hours after writing this post, I noticed this applies to that version as well. SPS module 9.3 also comes with Polly 5.9.0.

Update 2: After some help from Sitecore Support and some additional adjustments, I got the following solution to work on my machine:

Keep you 5.9.0 version of Polly.dll in the bin folder. Create a cmp sub folder (bin/cmp) and put the 6.0.1 version of Polly.dll in that folder. Then add the following to your web.config assembly binding section:

<dependentAssembly>
   <assemblyIdentity name="Polly" publicKeyToken="c8a3ffc3f8f825cc" />
   <codeBase version="5.9.0.0" href="bin\Polly.dll" />
   <codeBase version="6.0.0.0" href="bin\cmp\Polly.dll" />
   <codeBase version="6.0.1.0" href="bin\cmp\Polly.dll" />
</dependentAssembly>

I don’t think the 5.9.0.0 binding is really needed, but I found in my logs that the CMP connector was trying to load both 6.0.0.0 and 6.0.1.0.

The easy fix for this is to add assembly redirects into the web.config file before installing the connector and keep the old file: Update: It turned out I tricked myself. I thought I got everything working, but the CMP connector throws exceptions in the log while importing content from Content Hub.

<dependentAssembly>
  <assemblyIdentity name="Polly" /><!-- publicKeyToken="c8a3ffc3f8f825cc" -->
  <bindingRedirect oldVersion="5.8.0.0-6.0.1.0" newVersion="5.9.0.0"/>
</dependentAssembly>

As described in this stackoverflow post, it’s not possible to do assembly redirect between assemblies with different public keys. Polly 5.9 doesn’t have a public key (i.e. it’s null), so at least I couldn’t make binding work to the newer 6.0 version.

As of writing this, I don’t have a solution to this problem. I’m currently awaiting an answer from Sitecore if CMP and SPS can live together or not.

Improving Sitecore code quality with ReSharper External Annotations

I guess most of us Sitecore developers are familiar with the JetBrains ReSharper plugin for Visual Studio. The tool actually made me accept moving from the Java/IntelliJ IDEA world to the .Net/Visual Studio world many many years ago and I’m still on the Idea keyboard shortcut scheme.

Besides all the nice refactoring tools, code hints etc that comes with ReSharper, it also comes with a framework for annotating code with attributes. One can argue if this should be used or not in your own code, but it opens for a really nice way for improving code quality when working with external libraries.

As Sitecore has grown over the years, the API becomes larger and larger and there are sometimes multiple ways of achieving the same thing. Sometimes the API is a bit ambiguous to new developers and some operations should be avoided from a performance perspective etc. With ReSharper External Annotations we can give developers code hints and feedback directly in Visual Studio when using the Sitecore API in a way that may not be intended.

Continue reading