Insights

SXA CLI Scriban For Multi-Theme And Multi-Sites

For Sitecore 10

Configuring SXA CLI And Scriban Support Multi-Theme, Multi-Site In Sitecore 10 SXA

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!

Hey, Developers!

We're on the look out for talented developers to join our team.

Think you have what it takes?

Meet David Austin

Development Team Lead

📷🕹️👪

David is a decorated Development Team Lead with Sitecore Technology MVP and Coveo MVP awards, as well as Sitecore CDP & Personalize Certified. He's worked in IT for 25 years; everything ranging from Developer to Business Analyst to Group Lead helping manage everything from Intranet and Internet sites to facility management and application support. David is a dedicated family man who loves to spend time with his girls. He's also an avid photographer and loves to explore new places.

Connect with David