I've come to love SXA since using it in Sitecore 10 and as a fan of Underscore templates, I'm not a fan of using Scriban templates. Yes, you can build appropriate div structures and such in Sitecore. But why? When you can create a single Scriban template, and lay things out exactly how you want, why do anything else? But there is a problem.
If you're just using a single site, it's unlikely you've encountered this issue. What you'll notice however is as soon as you go to a multi-site setup, you'll start to realize an issue if you're using the SXA CLI. There is only one scriban folder under /-/media/
. So whenever it updates it's putting everything under the Site that is configured. This means that every site would share similar components. We don't want that!
Why Sitecore? Why?
Let's Solve It In 4 Steps
Let's say your Sitecore SXA environment has two sites and each has a different theme. Not to mention, each use different components. Naturally you want those scriban templates to sync to their appropriate location and you don't want components that shouldn't be there.
It's a problem that should never have happened, but have no fear, we are going to fix it.
Step 1 - Manage Scriban Themes
First thing first, is to create sub-directories under your /-/media/scriban
folder. One for each theme. It doesn't matter what they're called, but I suggest matching the theme name so you can keep track.
This may result in something that looks similar to the following structure:
/-
|__ /media
|__ /scriban
|__ /MyTheme
| |__ ... rendering variants
| |__ manifest.json
|__ /YourTheme
|__ ... rendering variants
|__ manifest.json
Step 2 - The Manifest
Located in the scriban folder, /-/media/scriban
you'll find a find, manifest.json
. Open it up. Inside you'll see a very simple json object.
{
"siteId":"{5590F9D6-3DA9-4A00-868D-BB25BB2A99DF}",
"database":"master"
}
In the previous step you would have screated a theme folder for each theme underneath Scriban root. Duplicate the manifest.json
file and place a copy of it in each of the new theme folders updating the siteId
accordingly.
In each of these new theme folders, you can recreate the appropriate variant structure for your theme.
Step 3 - Configuration
Locate the gulp
folder within your theme, /-/media/Themes/<theme name>/../gulp
.
Open up the config.js
file.
Scroll down to approximately line 63, where it identifies the path
and metadataFilePath
for the Scriban tempaltes.
In each of the return statements, you'll see the path to the original scriban folder. Update it to the corresponding new path you've created for the theme in question. e.g.
path: (function () {
if (!global.rootPath) return;
let rootCreativeExchangePath = global.rootPath.split('-\\media'),
_path = './';
if (rootCreativeExchangePath.length > 1) {
_path = _path + path.relative('./', global.rootPath.split('-\\media')[0]).split(path.sep).join('/')
}
return _path + '/-/scriban/MyTheme/**/*.scriban';
})(),
metadataFilePath: (function () {
if (!global.rootPath) return;
let rootCreativeExchangePath = global.rootPath.split('-\\media'),
_path = './';
if (rootCreativeExchangePath.length > 1) {
_path = _path + path.relative('./', global.rootPath.split('-\\media')[0]).split(path.sep).join('/')
}
return _path + '/-/scriban/MyTheme/metadata.json';
})()
This allows the SXA CLI to know where to look for both the manifest.json
file as well as all the Scriban templates associated with the site and theme in question.
There's just one issue, which we solve in Step 4. The way that the CLI works, is it expects all the Scriban templates to be in the root of the Scriban folder, not a subfolder. And that "path" is passed into Sitecore. So when it's trying to install them it's looking for the MyTheme
item under the /<Tenant>/<Site>/Presentation/Rendering Variants
directory.
Good news, we can fix that very easily.
Step 4 - PowerShell
Deep within the bowels of Sitecore, you will find the SXA CLI PowerShell scripts. These scripts are how synching is working. You're looking for the following file in question:
/sitecore/system/Modules/PowerShell/Script Library/SXA/SXA - CELT/Web API/ChangeScriban
We're going to modify the following section of code in such a way that it strips out the theme subfolder we created within /-/media/scriban
. This way it finds the right items as part of synching.
if ($form.AllKeys.Contains($streamsKey)) {
$deserializer = $form[$streamsKey] | ConvertFrom-Json
$deserializer | % {
$content = $_.content
$path = $_.path
$index = $path.IndexOf("-/scriban/")
$path = $path.Substring($index).Replace("\", "/")
$decoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($content))
$entry = New-Object Sitecore.XA.Feature.CreativeExchange.Storage.Import.ContentImportEntry
$entry.Path = $path
$entry.Content = $decoded
$entries.Add($entry)
}
}
Below we've updated the above script, making the necessary modifications. I've commented above each change
$deserializer = $form[$streamsKey] | ConvertFrom-Json
$deserializer | % {
$content = $_.content
$path = $_.path
$index = $path.IndexOf("-/scriban/")
# Grab the path
$shortPath = $path.Substring($index)
# Strip out the sub folder we created
$newPath = "{0}/{1}/{3}" -f $shortPath.Split('?=/',4)
# Update path with the new path and continue on
$path = $newPath.Replace("\", "/")
$decoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($content))
$entry = New-Object Sitecore.XA.Feature.CreativeExchange.Storage.Import.ContentImportEntry
$entry.Path = $path
$entry.Content = $decoded
$entries.Add($entry)
}
Save the script and restart your SXA Watch process. Note: When you start the sxa watch -d
within the appropriate theme folder, it will now synch everything under the scriban subdirectory associated with that theme.
Happy Building!