Rise of the Unicorn Transformers

Rise of the Unicorn Transformers

Before time began, there was…the Cube. We know not where it comes from, only that it holds the power to create worlds and fill them with life. That is how our race was born. For a time we lived in harmony, but like all great power, some wanted it for good…others for evil.

Wait a minute. That’s not it.

Meet something brand new however, please welcome a new addition to the Unicorn and Rainbow Family: Field Transformers. Well Field Transforms, I get carried away.

Here’s the TL;DR. Sometimes a config snippet speaks louder than a thousand words.

What is it?

It’s like this.


- These transforms ONLY APPLY to what gets deserialized into Sitecore. Field values on disk/serialized datastore remain complete - respecting only the Rainbow field filter settings


Example: "-title, -text, +ApiUrl[{$apiUrlToken$}]" => All fields get deployed as normal, except "title" and "text". And "ApiUrl" gets a forced value.
Example: "!title, -text" => "Title" gets reset (to standard value), "Text" gets ignored.
Example: "?title, ?text" => ALL fields gets deployed, but fields "Title" and "Text" will only get their value deployed if target field value is empty
Example: "?title, ?text, !apiUrl" => As above, but field "apiUrl" is reset

"!field" => Reset this field unconditionally
"-field" => Ignore this field unconditionally
"?field" => Deploy this field if it has no value in target data store (Sitecore)
"+field[value]" => Force a new value into this field on target data store (Sitecore)
";field" => Force a "Lorem ipsum dolor" value into the field
":field" => Force a longer Lorem ipsum based HTML string into the field (around 2075 characters of Lorem Ipsum, broken up with <p> into sentences).
"$field[settingName]" => Grab the value of the Sitecore Setting `settingName` and force it as a value
<predicate fieldTransforms=";Title,:Text,!Include In Sitemap,+Api Endpoint[{$apiEndPoint$}],?Default Product">
<include name="Sample Data" database="master" path="/sitecore/content/global/sample" fieldTransforms="-Title" /> /* Predicate transforms apply, but "Title" gets ignored on this include definition */

<!-- Clear Workflow fields on local development environments, but force a specific state upstream -->
<include role:require="Standalone" name="Sample Data" database="master" path="/sitecore/content/global/sample" fieldTransforms="!Workflow,!Workflow State" />
<include role:require="ContentManagement" name="Sample Data" database="master" path="/sitecore/content/global/sample" fieldTransforms="+Workflow[{2DE02B52-B95F-404A-A955-C36B290F1B57}],+Workflow State[{5ACE9C7F-8A18-4C77-BC30-03BE5A40E6B6}]"/>

But what is it?

It’s a quality of life enhancemment. While I do not encourage it, I’ve often been met with questions like these:

  • “How can I prevent just this field being deployed?”
  • “How can I make sure this configuration value doesn’t get reset to development settings on each sync?”
  • “How can I make sure this field value doesn’t overwrite what the Content Editors entered?”

If you’ve been asked (or asked) any of these yourself, this is for you.

The intended use-case(s)

  • Keeping certain fields under Source Control, but not letting them “bleed” across to other developers. For instance “Workflow” and “Workflow State”.
  • When deploying content (example content or otherwise) to an upstream environment, an easy way to ensure a specific workflow and state is set/reset on the content items.
  • When deploying, make sure certain field values are only updated if they do not hold active content on the target environment.
  • A way to inject configuration values into Sitecore field values, for use in CI and CD pipelines.

And then you tell me. There are likely tonnes of ways people would want to use this feature, more than I’ve considered. I’ve just provided some new tools - I’ll leave it to you, how to best use them.

Cool. So how do I use it?

Your <predicate> and <include> nodes now accept a new optional attribute; fieldTransforms. I wanted to keep the configuration very light weight and reasonably intuitive, so that’s all you get. At least for now. If the feature takes off, I’ll look into making something more plug-able and expandable.

Field Transforms only affect what gets written into Sitecore. All other operations remain the same - they do not affect what gets written to disk, they do not affect FieldFilter definitions. This is simply a value-replacer on the pipeline between Filesystem and Sitecore.

Example 1

<predicate fieldTransforms="-Title,-Text">
<include name="Content" database="master" path="/sitecore/content/home" />

For all <include>, never deploy the fields Title and Text to Sitecore. Well technically to the sourceDataStore, but this will be Sitecore for 99.99% of you.

Example 2

<predicate fieldTransforms="-Title,-Text">
<include name="Content" database="master" path="/sitecore/content/home" fieldTransforms="+Title[My Forced Title Value]" />

As Example 1, but the "Content" <include> overrides the <predicate> and forces a value "My Forced Field Value" into the Title field.

Example 3

<include name="Content" database="master" path="/sitecore/content/home" fieldTransforms="+Title[My Forced Title Value]" />

As Example 2, but this time there is no <predicate> field transform. All fields will operate as normal, except Title which will get a forced value of "My Forced Title Value".

Nice. What field transforms are available?

Bit of a mixed pot, really.

  • -: Never deploy this field
  • ?: Only deploy this field if there is no value (can be standard value however) in the target field
  • !: Always reset this field (to standard value)

These are the 3 I probably see being most useful. But it doesn’t stop here.

  • ;: Forces the value ""Lorem ipsum dolor"" into the field
  • :: Forces a much longer (2075-ish characters) Lorem Ipsum string into the field (with <p> tags)
  • +[val]: Forces "val" into the field. E.g. +Title[Optimus Prime] will force the value "Optimus Prime" into the Title field.
  • $[setting]: Forces the value of Sitecore.Configuration.Settings.GetSetting("setting") into the field.

Intended use-case for +[val] could be for your build pipelines; e.g. +My Super Service EndPoint[${superServiceEndpoint}] wil force the value of ${superServiceEndpoint} into the field. Assumption being that you’ve run something like a token replacer in your build pipeline and replaced the actual value in the Unicorn configuration file.

Caveats, and gotchas

So here’s the tool. How you use it, is up to you. But be aware of some (perhaps obivous) caveats.

  • It won’t work with Transparent Sync. Transparent Sync never actually writes anything to Sitecore and therefore won’t ever pass by these Field Transforms.
  • If you force a field value (e.g. with + or $) on a versioned field - the field value will get forced onto all versions of the field. All versions, all languages.
  • It does work with Dilithium
  • Remember; it Field Transforms ONLY apply to field values being written to Sitecore. Everything serializes as before - yaml files are not affected by these transforms.

Can I get it now?

Yes. Yes you can. At the time of this writing, Rainbow 2.1.0-pre1 and Unicorn 4.1.0-pre1 have been pushed to NuGet. I still consider it a pre-release until a few more people have had a chance to take it out for a spin.

Please join our Slack Community at https://sitecore.chat/ and join the #unicorn channel if you’re taking this out for a spin. Would love to hear your thoughts and get your feedback.