Extending Sitecore ribbon with PowerShell scripts

Sitecore is built from the grounds up with extendibility in mind. Be that plugging into any place in its internal pipelines or any aspect of its User eXperience, therefore when I’ve managed to extend it’s context menu, I expected to have no problems whatsoever doing the same to its ribbon. Mind you I was right…

Using the PowerShell Console Module it took me less than 10 minutes total to add a nice piece of functionality that I thought was missing – Publish items I have modified.

ContextScriptsRibbon

Similarly to extending context menu – first I’ve created the script I wanted to execute that will take the current item and it’s sub-items and publish them by adding a new script item using the /sitecore/templates/Cognifide/PowerShell Script template in the core database. I’ve put it in the same place I store all my my scripts – in the /sitecore/content/Applications/PowerShell Console/Scripts branch but feel free to store them anywhere in the tree.

  • Filled in the Script body part with my script.
  • I decided I want to see the publishing results as I want to verify if the items I expected got published.

ContextScriptRibbonBody

Now the UI integration bits…

Since I wanted it nicely integrated with the publish button – I’ve created a Publish My Items item of template /sitecore/templates/System/Menus/Menu item within the /sitecore/content/Applications/Content Editor/Menues/Publish/ branch in the core database, set it’s icon and reference the script item in the Message field using the following pattern:

item:executescript(id=$Target,script={0937769B-998D-4580-B9FE-730C4CDABECD},scriptDb=core)

where the script guid is the ID of your script and the scriptDb is the database the script is located in.

ContextScriptsRibbonBinding

That’s it really. You can download the solution but I would strongly recommend you try the manual approach – it’s really exciting to see the puzzles click in.

The solution requires the Sitecore PowerShell Console from Cognifide, available for free from Sitecore Shared Source site.

Sample scripts for Sitecore PowerShell Console

Find out about your configuration:

List your available site providers. You will use the name provided in the “Name” column in place of where I use “cms” in the later samples.

get-psdrive `
  | where-object { $_.Provider.ToString() -eq "CmsItemProvider"} `
  | format-table Name, Root

Sample scripts for working with pages:

For the same of brevity I’m assuming your location is already somewhere within a Sitecore tree (e.g. you did something akin to cd master:\content prior to executing the following scripts.

List all properties & fields available for a particular page (including Sitecore properties defined in the item template).

get-childitem | get-member -memberType property*

List all items in the CMS of which template name contains “Article”

get-childitem -recurse `
  | where-object { $_.TemplateName -match "Article" } `
  | format-table DisplayName, Name, TemplateName

List all subitems and how many days ago were they modified

get-childitem -recurse `
  | format-table Name, `
  @{Label="Days since modified"; Expression={ `
  [datetime]::Now.Subtract([Sitecore.DateUtil]::IsoDateToDateTime($_.Updated)).Days} }

Delete all pages that have not been modified for the last 365 days.

get-childitem -recurse `
  | where-object {[datetime]::Now.Subtract([Sitecore.DateUtil]::IsoDateToDateTime($_.Updated)).Days -gt 365 } `
  | remove-item

List all items Updated over the last 24 hours and who changed them.

get-childitem -recurse `
  | where-object { [Sitecore.DateUtil]::IsoDateToDateTime($_.Updated) -gt [datetime]::Now.AddDays(-1) } `
  | format-table -property DisplayName, UpdatedBy, {$_.Paths.Path}

List all pages that have their “Text” field filled in.

get-childitem -recurse `
  | where-object { $_.Text -ne $null } `
  | format-table -property DisplayName, {$_.Paths.Path}

Make a nice reviewer’s comment on all pages with their “Text” property filled in.

get-childitem -recurse `
  | where-object { $_.Text -ne $null } `
  | foreach-object { $_.ReviewersComment = "Great job providing content!" }

Add a warning to the beginning of “Text” property for all pages that have not been saved for the last 180 days.

get-childitem -recurse `
  | where-object {`
  [datetime]::Now.Subtract([Sitecore.DateUtil]::IsoDateToDateTime($_.Updated)).Days -ge 180 `
  -and $_.Text -ne $null }
  | foreach-object {$_.Text = "<p style='color:red'>Old content. Review pending!</p>" + $_.Text }

Replace a string in a property on all pages with another string (in this sample – removing the warning the last sample added).

$old_content = "<p style='color:red'>Old content. Review pending!</p>"
$new_content = "";
get-childitem -recurse `
  | where-object {$_.Text -match $old_content} `
  | foreach-object {$_.Text = $_.Text.Replace($old_content, $new_content) }

Display the 10 most recently changed pages ordered in the reverse chronological order or changes. Display the page name, who changed it and when as well as the page status.

get-childitem -recurse `
  | sort-object -property Updated -descending `
  | select-object -First 10 `
  | format-table -property DisplayName, UpdatedBy, Updated

Sample scripts for working with Media Library / files:

Removes all .xml files from the “Old Xml Files” in Media library.

cd "master:\media library\Old Xml Files"
get-childitem -recurse `
  | where-object { $_.Extension -match "xml" } `
  | remove-item

Copy all files from the “staging” folder to the “production” folder in Media Library.

Copying files within media library is done as follows. This can also be done for items in the content branch.

copy-item "master:\media library\staging\*" "master:\media library\production\"

PowerShell Console for Sitecore – what can it do for me?

The aim of the PowerShell console for Sitecore is to create a command line interface to your data so you can automate and aggregate mundane tasks ass well as create statistics and a discoverability layer on top of your content.

Have you ever found yourself:

  • having to make a mundane change to a large number of pages?
  • in need of getting statistics field or template usages?
  • being curious of e.g. what’s the oldest page on your site?
  • in need to find out how many authors really create your content and how active they are?
  • having to copy or move a large number of files from one folder to another?
  • renaming or deleting files in your file store en-masse?
  • publish pages that match some specific feature rather than a whole branch?

sharp_toolIf the answer to any of those (and more) is something akin to “yes I did!”, I believe you might find my little plugin useful.

The idea is to create a scripting environment to work within Sitecore process, being able to make native calls to Sitecore API and modify content on a per-property level. The goal was to make it familiar to your IT and developers so they can reuse their skillset with it or if they rather learn it here, this knowledge will benefit them in the long run as clearly PowerShell is becoming an industry standard. The plugin’s aim is to manipulate not just sites, but files and pages on a large scale or perform statistical analysis of your content using  a familiar and well documented query language. The console allows you to execute and test scripts interactively, but also gives the admin means of exposing scripts to end users within context menus and in the ribbon. I’m sure in the long run I’ll come up with more applications. Scripted pipeline processors? Scripted renderings? Scripting campaigns statistics and engagement workflow steps? You name it…

Read the rest of this article »

Should you put your Sitecore site behind a load balancing proxy you will run into a bit of a problem with analytics where all the Engagement Analytics app would ever report would be your own load balancing proxy’s IP address. Needless to say that is fairly big loss as you are unable to reap a host of benefits of the Sitecore CEP like page personalization, automation and reporting.

While our website was running on Sitecore 6.4 this problem was already solved and we have implemented something akin to the solution from Jeroen’s blog. Meanwhile Sitecore has reimplemented its analytics engine from the grounds up in version 6.5, and I should say they did a great job on that. However in the process the API for the analytics has changed to a degree that made our current solution obsolete, basically what we got logged looked as follows:

BrokenAnalytics

Read the rest of this article »

Posted in .Net Framework, ASP.NET, C#, Code Samples, Sitecore, Software Development, Solution
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading ... Loading ...
| Leave a Comment »