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:

public class ScriptedRenderingDataSourceRoots
{
    public void Process(GetRenderingDatasourceArgs args)
    {
        Assert.IsNotNull(args, "args");
        string sources = args.RenderingItem["Datasource Location"];
        if (IsScripted(sources))
        {
            var items = new List();
            var contextItem = args.ContentDatabase.GetItem(
                                  args.ContextItemPath);
            GetScriptedQueries(sources, contextItem, items);
            args.DatasourceRoots.AddRange(items);
        }
    }
}

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:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <getRenderingDatasource>
        <processor
            patch:before="*[@type='Sitecore.Pipelines.GetRenderingDatasource.GetDatasourceLocation, Sitecore.Kernel']"
            type="Cognifide.PowerShell.Processors.ScriptedRenderingDataSourceRoots, Cognifide.PowerShell" />
      </getRenderingDatasource>
    </pipelines>
  </sitecore>
</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
    Get-ChildItem master:\content\home\ | Get-Random
  • provide different content for different time of day, day of week etc.
    Get-Item "master:\content\home\$([DateTime]::Now.DayOfWeek)"
  • provide different content for different users…
    Get-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:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <resolveRenderingDatasource>
        <processor 
            type="Cognifide.PowerShell.Processors.ScriptedRenderingDataSourceResolve, Cognifide.PowerShell" />
      </resolveRenderingDatasource>
    </pipelines>
  </sitecore>
</configuration>

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

public class ScriptedRenderingDataSourceResolve
{
    public void Process(ResolveRenderingDatasourceArgs args)
    {
        Assert.IsNotNull(args, "args");
        string source = args.Datasource;
        if (IsScripted(source))
        {
            var items = RunEnumeration(source, Sitecore.Context.Item);
            args.Datasource = items.First().Paths.Path;
        }
    }
}

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.

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...



This entry (Permalink) was posted on Monday, May 6th, 2013 at 4:34 pm and is filed under .Net Framework, Code Samples, Open Source, PowerShell, Sitecore, Software, Software Development, Solution, Web applications. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response , or trackback from your own site.