Experience Sitecore! | Martin Miles on Sitecore

Experience Sitecore!

Martin Miles on Sitecore

Creating a custom rendering variant section to render element with background image

Note! The code used in this post can be cloned from GitHib repository: SXA.Foundation.Variants

I am working on a rendering variant, and was looking on getting an element with background image from Sitecore, something similar to this:

<div style="background-image: url(/-/media/Project/Tenant/Platform/Some-image-from-Sitecore.jpg)">
    <div>... some rendering variant fields here</div>
</div>
There is way to achieve that by placing container rendering, as it has an option of picking up a background image:


However, even it may bring desired result, having container it is not the best and simplest from structuring point of view as it creates plenty of nesting element and image comes not at the top of them, not to say that it is not editors friendly and have to mess with placeholder settings. ideally, I wanted something like Section which in fact is just a div container to store other variant fields, but with style attribute stating background image. Okay, since I found nothing, I can implement that with a new variant field.

Since Section seems to be the best option, let's just clone and extend it. To start with, I copy VariantSection template into my tenant templates folder under foundation, and name it Image Section. I add just one ImageFieldName field of type image to the newly created template, that will be a reference to background image. So far, so good.

Then I run /sitecore/admin/showconfig.aspx in order to investigate what logic is involved into processing sections and find these 2 processors, one for parser:

<parseVariantFields patch:source="Sitecore.XA.Foundation.RenderingVariants.config">
  <processor type="Sitecore.XA.Foundation.RenderingVariants.Pipelines.ParseVariantFields.ParseSection, Sitecore.XA.Foundation.RenderingVariants" resolve="true"/>
</parseVariantFields>
and another - for renderer:
<renderVariantField patch:source="Sitecore.XA.Foundation.RenderingVariants.config">
  <processor type="Sitecore.XA.Foundation.RenderingVariants.Pipelines.RenderVariantField.RenderSection, Sitecore.XA.Foundation.RenderingVariants" resolve="true"/>
</renderVariantField>

With JetBrains dotPeek, it becomes fairly easy to find the code and extend it. Based on what I found, I create 3 new classes to implement parser, renderer and also the model itself:


I extend section variant field with one extra Single-Line Text field, stating which field from the context item should contain image. Also, I am referencing my new template created earlier. Here's the code:

using System.Collections.Generic;
using Sitecore.Data.Items;
using Sitecore.XA.Foundation.Variants.Abstractions.Fields;
using Sitecore.XA.Foundation.RenderingVariants.Fields;

namespace Platform.Foundation.Variants.Pipelines.VariantFields
{
    public class VariantImageSection : RenderingVariantFieldBase
    {
        public VariantImageSection(Item variantItem) : base(variantItem)
        {
        }

        public static string DisplayName => "Image Section";

        public IEnumerable<BaseVariantField> SectionFields { get; set; }

        public string ImageFieldName { get; set; }

        public string LinkField { get; set; }

        public bool IsLink { get; set; }
    }
}

and now implement parser. Please pay attention that since we duplicated the template, fields for Image section will have new IDs, so we will also re-reference Tag, CssClass and IsLink fields from our static constants class, where we keep all the IDs:

using System.Collections.Generic;
using Sitecore.Data;
using Sitecore.DependencyInjection;
using Sitecore.XA.Foundation.SitecoreExtensions.Extensions;
using Sitecore.XA.Foundation.Variants.Abstractions.Pipelines.ParseVariantFields;
using Sitecore.XA.Foundation.Variants.Abstractions.Services;

namespace Platform.Foundation.Variants.Pipelines.VariantFields
{
    public class ParseImageSection : ParseVariantFieldProcessor
    {
        public override ID SupportedTemplateId => Constants.RenderingVariants.Fields.VariantImageSection;

        public override void TranslateField(ParseVariantFieldArgs args)
        {
            ParseVariantFieldArgs variantFieldArgs = args;

            var variantSection = new VariantImageSection(args.VariantItem);
            variantSection.ItemName = args.VariantItem.Name;
            variantSection.Tag = args.VariantItem.Fields[Constants.RenderingVariants.Fields.Tag].GetEnumValue();
            variantSection.CssClass = args.VariantItem[Constants.RenderingVariants.Fields.CssClass];
            variantSection.ImageFieldName = args.VariantItem[Constants.RenderingVariants.Fields.ImageField];
            variantSection.LinkField = args.VariantRootItem[Sitecore.XA.Foundation.Variants.Abstractions.Templates.IVariantDefinition.Fields.LinkField];
            variantSection.IsLink = args.VariantItem[Constants.RenderingVariants.Fields.IsLink] == "1";

            variantSection.SectionFields = args.VariantItem.Children.Count > 0 
                ? ((IVariantFieldParser)ServiceLocator.ServiceProvider.GetService(typeof(IVariantFieldParser))).ParseVariantFields(args.VariantItem, args.VariantRootItem, false) 
                : new List<Sitecore.XA.Foundation.Variants.Abstractions.Fields.BaseVariantField>();

            variantFieldArgs.TranslatedField = variantSection;
        }
    }
}

Now we implement renderer logic. What I am doing below, is getting a field name of a context item, where image supposed to be, and then generate a URL for that media item (in case field is valid and media item indeed presents there), further down this URL is being appended our section element (remember, you may select any tag, not just div) as a background image style attribute:

using System;
using System.Web.UI.HtmlControls;
using Sitecore.Data.Fields;
using Sitecore.Pipelines;
using Sitecore.Resources.Media;
using Sitecore.XA.Foundation.RenderingVariants.Pipelines.RenderVariantField;
using Sitecore.XA.Foundation.Variants.Abstractions.Fields;
using Sitecore.XA.Foundation.Variants.Abstractions.Models;
using Sitecore.XA.Foundation.Variants.Abstractions.Pipelines.RenderVariantField;

namespace Platform.Foundation.Variants.Pipelines.VariantFields
{
    public class RenderImageSection : RenderRenderingVariantFieldProcessor
    {
        public override Type SupportedType => typeof(VariantImageSection);

        public override RendererMode RendererMode => RendererMode.Html;

        public override void RenderField(RenderVariantFieldArgs args)
        {
            string styleInlineValue = String.Empty;
            var variantField = args.VariantField as VariantImageSection;

            if (!string.IsNullOrWhiteSpace(variantField?.ImageFieldName) && args.Item != null)
            {
                ImageField imgField = args.Item.Fields[variantField.ImageFieldName];
                if (imgField != null)
                {
                    string url = MediaManager.GetMediaUrl(imgField.MediaItem);
                    styleInlineValue = $"background-image: url({url})";
                }
            }

            var tag = new HtmlGenericControl(string.IsNullOrWhiteSpace(variantField.Tag) ? "div" : variantField.Tag);

            if (styleInlineValue.Length > 0)
            {
                tag.Attributes.Add("style", styleInlineValue);
            }

            AddClass(tag, variantField.CssClass);
            AddWrapperDataAttributes(variantField, args, tag);

            foreach (BaseVariantField sectionField in variantField.SectionFields)
            {
                var variantFieldArgs = new RenderVariantFieldArgs
                {
                    VariantField = sectionField,
                    Item = args.Item,
                    HtmlHelper = args.HtmlHelper,
                    IsControlEditable = args.IsControlEditable,
                    IsFromComposite = args.IsFromComposite,
                    RendererMode = args.RendererMode,
                    Model = args.Model
                };

                CorePipeline.Run("renderVariantField", variantFieldArgs);

                if (variantFieldArgs.ResultControl != null)
                {
                    tag.Controls.Add(variantFieldArgs.ResultControl);
                }
            }

            args.ResultControl = variantField.IsLink ? InsertHyperLink(tag, args.Item, variantField.LinkAttributes, variantField.LinkField, false, args.HrefOverrideFunc) : tag;
            args.Result = RenderControl(args.ResultControl);
        }
    }
}

Once done, create a patch configuration file and reference new processors: parser and renderer:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <parseVariantFields>
        <processor type="Platform.Foundation.Variants.Pipelines.VariantFields.ParseImageSection, Platform.Foundation.Variants" resolve="true"/>
      </parseVariantFields>
      <renderVariantField>
        <processor type="Platform.Foundation.Variants.Pipelines.VariantFields.RenderImageSection, Platform.Foundation.Variants" resolve="true"/>
      </renderVariantField>
    </pipelines>
  </sitecore>
</configuration>

The code above requires you to reference Sitecore.XA.Foundation.RenderingVariants, Sitecore.XA.Foundation.SitecoreExtensions and Sitecore.XA.Foundation.Variants.Abstractions libraries.

Another thing you will need to provide is adding insert options. I do not cover it as it is quite obvious. Finally, you'll be able to use your new rendering variant field:


with


which renders the following output and allows child / nested elements, as normal section would do:


This explains how one can easily extend existing rendering variant fields and provide any custom output without lengthy process of creating a custom component in SXA.

Rule missing OOB in Sitecore, where the Experience Editor is in editing mode

I was playing with SXA and wanted to have a custom element within a rendering variant that identifies current control presents on a page, otherwise it is being invisible. Looking for such a rule I suddenly realised it is not there, so had to create my custom one. I am sharing it just in case it might be useful to someone looking for a similar solution.

So, as per Rules Engine Cookbook, you create a tag, custom condition and relevant element for it:


The code is simple.

public class IsExperienceEditorEditing<T> : StringOperatorCondition<T> where T : RuleContext
{
    public int Value { get; set; }
    protected override bool Execute(T ruleContext)
    {
        return Sitecore.Context.PageMode.IsExperienceEditorEditing;
    }
}

Also, working with SXA aligned with Helix principles, it would make sense to create a foundation module for custom rules, drop the above class inside as well as serialization for newly created tag and elements:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:unicorn="http://www.sitecore.net/xmlconfig/unicorn/">
  <sitecore unicorn:require="On">
    <unicorn>
      <configurations>
        <configuration name="Foundation.Rules" description="Foundation Rules" extends="Helix.Foundation">
          <predicate type="Unicorn.Predicates.SerializationPresetPredicate, Unicorn" singleInstance="true">
            <include name="$(layer).$(module).Tags" database="master" path="/sitecore/system/Settings/Rules/Definitions/Tags/Experience Editor" />
            <include name="$(layer).$(module).Elements" database="master" path="/sitecore/system/Settings/Rules/Definitions/Elements/Experience Editor" />
          </predicate>
        </configuration>
      </configurations>
    </unicorn>
  </sitecore>
</configuration>
So now I can have an element withing rendering variant that is shown only when in editing mode:

Hope you find this helpful!

Quick tip: using rules engine for SXA rendering variants

I working on a rendering variant in order to implement a component similar to the one below:


The component should display a heading title, followed by a list of promo blocks leading to the other pages. What is important here, is that different page types can be assigned into given component, of course they all do implement _Promotable interface template that has fields allowing them being promoted through this component. So far, so good.

But notice, each promo block has its type in left top corner painted into appropriate color. The values of it (article, topic, blog) are actually types of the pages, they do not present in generic _Promotable interface template, but do match template names, so why not to expose template names for these fields?

The easiest way of doing that is to create a label for each of the page type and assign it corresponding CSS class to display in appropriate color. 


Then we may use built in Rules Engine in order to create a rules for each of these page type labels to be shown only if the item template matches given page type. Here's how it looks in Content Editor:


Note! If you cannot access your condition through SXA built-in Rule Engine, you need to assign tag to Conditional Renderings tags (/sitecore/system/Settings/Rules/Conditional Renderings):


Also, there is another way of achieving the same goat - using NVelocity templates: create a Variant Template field and expose current template name:


That will also work since type badge matches name of page template in our case, but will need some extra work to wire up CSS class, that should derive from template name in this or that way.

SXA built-in token tools to be used with rendering variant templates

Note! The code used in this post can be cloned from GitHib repository: SXA.Foundation.Variants

You might came across Variant Template Field when going through rendering variants insert options and wondered, what is that? Variant Template Field is a special field that uses NVelocity templates (supported by Sitecore.NVelocity.dll) in order to render the value.


One of the MVPs - Michael West - has briefly mentioned built-in token tools coming with SXA. I decided to take a look on these tools. I found them in Sitecore.XA.Foundation.Variants.Abstractions.dll under Sitecore.XA.Foundation.Variants.Abstractions.NVelocityExtensions namespace. Here's their code:

public class DateTool
{
    public string Format(DateTime dateTime, string format) => dateTime.ToString(format);

    public string Format(string dateTimeString, string format)
    {
        DateTime time = DateUtil.IsoDateToDateTime(dateTimeString, DateTime.MinValue);
        if (time != DateTime.MinValue)
        {
            return time.ToString(format);
        }
        return dateTimeString;
    }
}

and

public sealed class NumberTool
{
    public string Format(double value, string format) => value.ToString(format, CultureInfo.InvariantCulture);
    public string Format(int value, string format) => value.ToString(format, CultureInfo.InvariantCulture);
    public string Format(float value, string format) => value.ToString(format, CultureInfo.InvariantCulture);
}

DateTool is used internally by another field type - VariantDateField, that's how it works. Let's say I have a template:


and it renders to: 


But you may also use it from templates (since it is already mapped) for example combining with your custom tools (not just this one line):


resulting with:


It is also briefly mentioned in the official documentation.

Configuring search for SXA 1.8

I was following the official guidance, so dropped search box component to my header and configured search results parameter. Then created page /search and dropped search results on it. Tested and got an exception (from logs):

14260 17:31:37 ERROR Unable to connect to [https://localhost:8983/solr], Core: [sitecore_sxa_master_index]
Exception: SolrNet.Exceptions.SolrConnectionException
Message: 
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Error 404 Not Found</title>
<h2>HTTP ERROR 404</h2>
<p>Problem accessing /solr/sitecore_sxa_master_index/schema. Reason:
</p><pre>Not Found</pre><p></p>

Source: SolrNet
   at SolrNet.Impl.SolrConnection.Get(String relativeUrl, IEnumerable`1 parameters)
   at Sitecore.ContentSearch.SolrNetExtension.Impl.SolrBasicServerEx`1.GetSchema(String collection)
   at Sitecore.ContentSearch.SolrProvider.SolrSearchIndex.InitializeSchema()
   at Sitecore.ContentSearch.SolrProvider.SolrSearchIndex.InitializeSolr()

Nested Exception
Exception: System.Net.WebException
Message: The remote server returned an error: (404) Not Found.
Source: System
   at System.Net.HttpWebRequest.GetResponse()
   at HttpWebAdapters.Adapters.HttpWebRequestAdapter.GetResponse()
   at SolrNet.Impl.SolrConnection.GetResponse(IHttpWebRequest request)
   at SolrNet.Impl.SolrConnection.Get(String relativeUrl, IEnumerable`1 parameters)
14260 17:31:37 ERROR Unable to connect to [https://localhost:8983/solr], Core: [sitecore_sxa_web_index]

Exception: SolrNet.Exceptions.SolrConnectionException

Obviously, my SXA indexes got misconfigured, and Sitecore Indexing manager showed nothing there. I identified a responsible config file: App_Config/Modules/SXA/Z.Foundation.Overrides/Sitecore.XA.Foundation.Search.Solr.config - it adds two SXA-related indexes as below (irrelevant lines skipped):

<index id="sitecore_sxa_master_index">
  <param desc="name">$(id)</param>
  <param desc="core">$(id)</param>
</index>

I tried populating schema:


 But got such an exception:


Looking at Solr I've noticed that all my cores are prefixed (ie. Platform_master_index) by the installation, so obviously there are no such cores (ie. sitecore_sxa_master_index). Indexing Manager claims these as "never run". I decided to collocate SXA indexes within cores for corresponding databases, along with traditional non-SXA indexes.  So that both indexes sitecore_master_index and sitecore_sxa_mater_index will reside within Platform_master_index core.

So I ended up making this patch Foundation.ContentSearch.config:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:search="http://www.sitecore.net/xmlconfig/search/">
  <sitecore search:require="solr">
    <contentSearch>
      <configuration type="Sitecore.ContentSearch.ContentSearchConfiguration, Sitecore.ContentSearch">
        <indexes hint="list:AddIndex">
          <index id="sitecore_sxa_master_index" type="Sitecore.ContentSearch.SolrProvider.SolrSearchIndex, Sitecore.ContentSearch.SolrProvider" role:require="Standalone or Reporting or ContentManagement or Processing">
            <param desc="core" patch:instead="param[@desc='core']">Platform_master_index</param>
          </index>
          <index id="sitecore_sxa_web_index" type="Sitecore.ContentSearch.SolrProvider.SolrSearchIndex, Sitecore.ContentSearch.SolrProvider" role:require="Standalone or ContentDelivery or ContentManagement or Reporting">
            <param desc="core" patch:instead="param[@desc='core']">Platform_web_index</param>
          </index>
        </indexes>
      </configuration>
    </contentSearch>
  </sitecore>
</configuration>

Once patch applied, I've re-populated schema again and it worked and after refreshing the page search box worked well, including predictive search!

Which certificates (and where to) got installed with Sitecore 9.1?

Upon the new clean installation, Sitecore 9.1 puts the following certificates (as per below example of habitat project hostnames):

1. Current User\Personal - nothing



2. Current User\Intermediate Certification Authorities - SIF

  • Sitecore Install Framework / Sitecore Install Framework



3. Local Computer\Personal - xConnect and Identity Server

  • habitat_xconnect.dev.local / DO_NOT_TRUST_SitecoreRootCert
  • habitat_IdentityServer.dev.local / DO_NOT_TRUST_SitecoreRootCert


4. Local Computer\Intermediate Certification Authorities - Sitecore and SIF

  • DO_NOT_TRUST_SitecoreRootCert / DO_NOT_TRUST_SitecoreRootCert
  • Sitecore Install Framework / Sitecore Install Framework


Hope this helps!

Sitecore Discussion Club - December 2018

People sometimes ask me, what is Sitecore Discussion Club and how it differs from Sitecore user groups. Well, I have covered plenty of times and also got some description on Sitecore Discussion Club website. But this time I made a panoramic 360-degree video, showing how it looks like (the first part with presentations). This time there were slightly fewer people than usual, which created even more cozy and friendly atmosphere.

On a desktop/laptop please use the arrows at the top left corner to rotate all around, or simply drag the video canvas with the mouse. For mobiles - just rotate your screen around and video flow will adjust to your movements.


Thanks to the members attending Sitecore Discussion Club!

SXA tokens for datasource queries

Just a cheat sheet for myself to have them here all in one place so that I bookmark this URL and don't waste time digging out all sorts of documentation in order to find the right one. Taken out from here and here.

Available tokens:

  • $compatibleThemes - path to all themes
  • $theme - currently used theme
  • $pageDesigns - root of page designs
  • $partialDesigns - root of partial designs
  • $currenttemplate - name of the current template
  • $tenant - path to the current tenant
  • $site - path to the current site
  • $home - path to the current site start item (Home)
  • $templates - path to the current sitetemplates
  • $siteMedia - path to Virtual Media folder located under site
  • $sharedSites - for multiroot fields, resovles shared site for current tenant.
Custom tokens can be defined by adding an additional processor to resolveTokens pipeline.

Some samples
Children of the current pagequery:.//*
Home item of the current sitequery:$home
Parent item of the current pagequery:..
Parent of the parent item of the current pagequery:../..
Every item under site home pagequery:$home//*
Every item under site home page with additional sorting appliedquery:$home//*[@@name='News']
All items of the Page template under the current itemquery:..//*[@@templatename='Page']
All items of the Page template under the Home item of the current site       query:$site/*[@@name='Home']//*[@@templatename='Page']

Other examples met in projects per field types

Droptree
query:$site
query:$site/Data/Authors
query:$site/*[@@templatename='Presentation']/*[@@templatename='Partial Designs']
Datasource=/sitecore/system/Marketing Control Panel/Outcomes&IncludeTemplatesForSelection=outcome definition&AllowMultipleSelection=no
DataSource=/sitecore/system/Settings/Security/Profiles/Habitat/UserProfile&DatabaseName=core

Droplink
query:$site
code:Sitecore.XA.Foundation.Variants.Abstractions.DataSource.AvailableRenderingVariants, Sitecore.XA.Foundation.Variants.Abstractions
query:$compatibleThemes
query:$site/Settings/Scopes//*[@@templateid='{8B649372-CC12-4F31-802A-8C3B3D09BB3F}']|$sharedSites/Settings/Scopes//*[@@templateid='{8B649372-CC12-4F31-802A-8C3B3D09BB3F}']
query:$pageDesigns//*[@@templatename='Page Design']
query:/sitecore/system/Settings/Foundation/Experience Accelerator/Rendering Variants/Rendering Variants/*[@@templatename='Variants Grouping']/POI//*[@@templatename='Variant Definition']|$site/*[@@name='Presentation']/*[@@templatename='Variants Grouping']/POI//*[@@templatename='Variant Definition']|$sharedSites/*[@@name='Presentation']/*[@@templatename='Variants Grouping']/POI//*[@@templatename='Variant Definition']
query:$site/*[@@name='Presentation']/*[@@templatename='PoiTypes']//*[@@templatename='POI Type']|$sharedSites/*[@@name='Presentation']/*[@@templatename='PoiTypes']//*[@@templatename='POI Type']

Droplist
databasename=core&datasource=/sitecore/content/Applications/WebEdit/Edit Frame Buttons        (edit frame select buttons)

Multilist
query:/sitecore/system/Marketing Control Panel/Profiles//*[@@templatename='Profile']
query:/sitecore/system/Marketing Control Panel/Profiles//*[@@templatename='Profile']
query:/sitecore/system/Marketing Control Panel/Profiles//*[@@templatename='Profile']
query:$templates

Treelist
datasource=/sitecore/media library&IncludeTemplatesForDisplay=Media Folder,Base Theme,Theme
query:$site/*[@@name='Data']/*[@@templatename='Tag Folder']
DataSource=/sitecore/media library&IncludeTemplatesForSelection=Theme
DataSource=query:$site/Data/Links
DataSource=/sitecore/system/Settings&IncludeTemplatesForSelection=EditTenantTemplate,AddItem,ExecuteScript
DataSource=query:$tenant&IncludeTemplatesForSelection=Site
Datasource=/sitecore/media library&ExcludeTemplatesForSelection=Main section
datasource=/sitecore/layout/renderings&excludetemplatesforselection=Folder,Rendering Folder,Node
query:$tenant

TreelistEx
DataSource=/sitecore/layout&ExcludeItemsForDisplay={E18F4BC6-46A2-4842-898B-B6613733F06F},{75CC5CE4-8979-4008-9D3C-806477D57619},{1CE3B36C-9B0C-4EB5-A996-BFCB4EAA5287},{B4A0FB13-9758-427C-A7EB-1A406C045192}&ExcludeTemplatesForSelection={239F9CF4-E5A0-44E0-B342-0F32CD4C6D8B},{A87A00B1-E6DB-45AB-8B54-636FEC3B5523}
DataSource=/sitecore/layout&ExcludeItemsForDisplay={E18F4BC6-46A2-4842-898B-B6613733F06F},{75CC5CE4-8979-4008-9D3C-806477D57619},{1CE3B36C-9B0C-4EB5-A996-BFCB4EAA5287},{B4A0FB13-9758-427C-A7EB-1A406C045192},{75D27C2B-5F88-4CC8-B1DE-8412A1628408},{B87CD5F0-4E72-429D-90A3-B285F1D038CA},{39522E9A-9B6E-4CB4-850C-23D0D3ADFD0C}&ExcludeTemplatesForSelection={239F9CF4-E5A0-44E0-B342-0F32CD4C6D8B},{A87A00B1-E6DB-45AB-8B54-636FEC3B5523}
IncludeTemplatesForSelection=Site

Multiroot Treelist
DataSource=query:$partialDesigns&IncludeTemplatesForSelection=Partial Design,Metadata Partial Design&IncludeTemplatesForDisplay=Partial Design,Metadata Partial Design,Partial Designs,Partial Design Folder

Image
query:$siteMedia

General Link
query:$home

Rich text
/sitecore/system/Settings/Html Editor Profiles/Rich Text XA

Rules
rulespath=/sitecore/system/Settings/Foundation/Experience Accelerator/Variants/Rules Context&hideactions=true&allowmultiple=true
rulespath=/sitecore/system/Settings/Foundation/Experience Accelerator/Search/Item Query Rules Context&hideactions=true&allowmultiple=true

Lookup name lookup value list
query:/sitecore/layout/Devices//*[@@templatename='Device']||query:$compatibleThemes
query:/sitecore/system/Settings/Foundation/#Experience Accelerator#/Theming/Enums/Placeholders/*||query:/sitecore/templates/Foundation/#Experience Accelerator#/Grid/#Grid Definition#/#Placeholder Styles#/*
query:$templates||query:$pageDesigns//*[@@templatename='Page Design']
query:/sitecore/layout/Devices//*[@@templatename='Device']||query:/sitecore/system/Settings/*//*[@@templatename='Grid Definition']

Tag treelist
query:$site/*[@@name='Data']/*[@@templatename='Tag Folder']

Styling parameters

code:Sitecore.XA.Foundation.Presentation.CodeDataSource.RenderingStyles, Sitecore.XA.Foundation.Presentation


Troubleshooting Solr populate schema for Sitecore Commerce 9.0 update 3 installation

I was installing Sitecore Commerce 9.0 update 3 and after a long successful run, it broke out with an error saying that Solr fails to populate schema.
After digging out, I found out that this issue is coming from Sitecore-commerce-solr.json has capitalized argument Name that is further concatenated with other arguments into a URL: 

https://localhost:8983/solr/admin/cores?action=Create&Name=platformCustomersScope&Configset=basic_configs&wt=json

where it should be with lower case 'n' instead:

https://localhost:8983/solr/admin/cores?action=Create&name=platformCustomersScope&Configset=basic_configs&wt=json

As I later cleared up from Sitecore, the issue comes from using SIF 2.0 for installing XC 9.0 update 3, which is not supported -we should use SIF 1.2.1 instead. However, changing these configuration json file arguments to lowercase make the trick work.