PowerShell Scripted data sources in Sitecore (Part 2)

CMS Code Samples Open Source PowerShell Scripting Sitecore Software Development Solution

There are 2 more ways I’ve managed to find and implement that you can control data sources with PowerShell:

  • rendering data source roots
  • rendering data source itself

The motivation would be similar to what I’ve described in the ?Part 1? blog post. So without further ado let’s cut to the meat?

Rendering Data Source Roots

You might want your roots to be dynamic and you can deliver those using a PowerShell script!

Sitecore allows you to specify a place in the content tree where content for your rendering or sublayout can be selected from. More over it allows you to specify more than one of those roots. What’s even greater – this is done through a pipeline defined in web.config, which means we can hook into it with? PowerShell!

A cool part of the experience is that you can have multiple roots, which means that your scripts can be more liberal in what roots they expose.

image

This is done using the getRenderingDatasource pipeline and the implementation looks as follows:

 1public class ScriptedRenderingDataSourceRoots
 2{
 3    public void Process(GetRenderingDatasourceArgs args)
 4    {
 5        Assert.IsNotNull(args, "args");
 6        string sources = args.RenderingItem["Datasource Location"];
 7        if (IsScripted(sources))
 8        {
 9            var items = new List();
10            var contextItem = args.ContentDatabase.GetItem(
11                                  args.ContextItemPath);
12            GetScriptedQueries(sources, contextItem, items);
13            args.DatasourceRoots.AddRange(items);
14        }
15    }
16}

The implementation of IsScripted and GetScriptedQueries are the same as in my previous blog post so I’ll just skip those. Now in the console implementation the IsScripted has been improved to not only take over when ?script:? is detected but also when the data source definition points directly at the script library in “/sitecore/system/Modules/PowerShell/Script Library/” ? so you no longer have to add the ?script:? for the console to detect that it needs to take action.

The hook into the pipeline is simply:

 1<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
 2  <sitecore>
 3    <pipelines>
 4      <getRenderingDatasource>
 5        <processor
 6            patch:before="*[@type='Sitecore.Pipelines.GetRenderingDatasource.GetDatasourceLocation, Sitecore.Kernel']"
 7            type="Cognifide.PowerShell.Processors.ScriptedRenderingDataSourceRoots, Cognifide.PowerShell" />
 8      </getRenderingDatasource>
 9    </pipelines>
10  </sitecore>
11</configuration>

That’s really all it took to implement PowerShell integration there! Isn’t Sitecore awesome?!

Scripted rendering/sublayout data source items

Now this is probably the coolest data source integration of the three implemented so far – instead of pointing at an item – you can point at a script and make the script provide an item! This is based on a new functionality in Using this you can have your rendering e.g.:

  • randomize promo content between requests
1Get-ChildItem master:\content\home\ | Get-Random
  • provide different content for different time of day, day of week etc.
1Get-Item "master:\content\home\$([DateTime]::Now.DayOfWeek)"
  • provide different content for different users?
1Get-Item "master:\content\home\$($me)"

? to provide just a few samples. Now - there is nothing in it you couldn’t otherwise do with code, but with PowerShell you can change the module?s behaviour on the fly without ever needing to restart your server or recompile your code!

Starting with CMS 6.5.0 rev. 120706 (Update-5) – Sitecore added a new pipeline (which by the way is not really well documented and it took some digging to find out how it works) which means that it will not work on older versions than 6.5 Update-5.

The console hooks into the pipeline using the following include:

 1<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
 2  <sitecore>
 3    <pipelines>
 4      <resolveRenderingDatasource>
 5        <processor 
 6            type="Cognifide.PowerShell.Processors.ScriptedRenderingDataSourceResolve, Cognifide.PowerShell" />
 7      </resolveRenderingDatasource>
 8    </pipelines>
 9  </sitecore>
10</configuration>

And the code for it is even simpler than the roots resolver:

 1public class ScriptedRenderingDataSourceResolve
 2{
 3    public void Process(ResolveRenderingDatasourceArgs args)
 4    {
 5        Assert.IsNotNull(args, "args");
 6        string source = args.Datasource;
 7        if (IsScripted(source))
 8        {
 9            var items = RunEnumeration(source, Sitecore.Context.Item);
10            args.Datasource = items.First().Paths.Path;
11        }
12    }
13}

Again with the RunEnumeration identical to the previous post implementation. Now, I think I’m happy and ready to put the data sources to rest? did I miss anything that could get scripted (?) Let me know!

The full implementation is available in the Cognifide’s Sitecore PowerShell Console (starting with 2.0 RC3) already available on Sitecore Marketplace.

Comments