shoot_out_of_cannon_400_clr_13993In one of my previous posts I described how to create reports in Sitecore PowerShell Extensions (SPE for short) that allow you to leverage the joint power of Sitecore and PowerShell to deliver complete and elegant reports in little to no time. In this post I’ll tell you how to take this a step further and operationalize them into full blown Sitecore Desktop applications.

The secret sauce is in the actions you can place on the report, the additional parameters that I haven’t mentioned in the previous post, and the use of Sitecore rules engine with some rules that come with SPE.

For the purpose of this post I will limit the scripts to samples that are (mostly) in the vanilla SPE deployment.

Let’s begin with describing the actions and how you can configure them to appear in your reports.

What are report actions?

Actions are simply commands powered by scripts and with visibility dependent on certain conditions like the .Net class of the object that is displayed or perhaps other session settings.

Action Scripts

You define an action as a script located in an SPE script library and appears in the Actions panel. In the simplest scenario the action would appear when the script library name matches the .Net class name of the items displayed. In the above scenario the actions are placed under /Platform/Internal/List View/Ribbon/Item/ where Platform is the module and Item is a script library. Let’s take a look at the script here /Platform/Internal/List View/Ribbon/Item/Open

Contents of the Open script:

foreach($item in $selectedData){
# Run Sheer application on Desktop
Show-Application `
    -Application "Content Editor" `
    -Parameter @{id ="$($item.ID)"; fo="$($item.ID)"; 
                 la="$($item.Language.Name)"; vs="$($item.Version.Number)";
                 sc_content="$($item.Database.Name)"}
}

The variable $selectedData is provided to the script automatically by SPE in context of the content of the results on Show-ListView.

What input is passed to an action script?

When your action script is executed the environment is initialized with a number of variables at your disposal as seen below:

  • $selectedData – the selected objects in the list view (the same will be passed to the $resultSet variable for compatibility with older scripts)
  • $allData – all objects passed to the list view using the -Data parameter.
  • $filteredData – all objects displayed after filtering is performed with the search criteria entered by the user in the ribbon.
  • $exportData – same as $filteredData, however in this case the objects will have additional properties to support easy display with properties processed as text.
  • $actionData – any object that was passed to Show-ListView using the -ActionData parameter. Useful when you need additional context that the Show-ListView command does not explicitly know about. It’s your custom data.
  • $formatProperty – the content of the –Property parameter when running the command.
  • $title – window title of the list view.
  • $infoTitle – info title of the list view.
  • $infoDescription – info title of the list view.

Consequently you get the full state of the report the user sees in the UI and you can act upon it.

How the report determines if your action is visible?

You can have multiple actions defined with dynamic visibility. The actions are generally only relevant in the context of your report. This is done on two levels. The first level happens based on the location of the script and .Net object type you are displaying in the report. The second level is based on Sitecore rules. For the action to appear all of the following conditions must be met:

  • All scripts visible in the report should be located in an enabled module.
  • The action script should be within the path /Internal/List View/Ribbon/<Object type> . The <Object type> is the name of the .Net class for which the action is valid. For example, if you want your action to be visible for Sitecore.Data.Items.Item then save the script at the path  /Internal/List View/Ribbon/Item.
  • If the action script has no rules defined in the “Show if rules are met or not defined” field it will appear for all objects passed to Show-ListView that are of the type based on location. Rules will provide more granular control and allow for rule-based conditions that determine action visibility.

Using rules to control action visibility

Rules add the full power of the Sitecore rules engine – similarly to what you can do on context menu items or ribbon actions in Content Editor like I’ve described in my previous post. Some examples where this can be useful include only enabling or disabling the action for items located under a specific branch of the tree or if a persistent session exists.

The following screenshot shows how to create an action that only appears in reports that list objects of type Item that are of template Schedule.

Schedule Action

For specific reports this global state might not always be enough. You can narrow down the rules further by using the report name. Name your report by providing an additional parameter to your Show-List view in addition to what I described in my previous post about reports.

Consider the following script:

Get-ChildItem master:\ | Show-ListView -ViewName ListChildren

The output of the report will be like any other unnamed report but adds support for additional rules. Let’s say I want my action to open a new report that lists all the children of the selected items in the report “ListChildren”. After running the action my script should display the new report with the children and close the “ListChildren” report. Not very useful but illustrates the point.

Action Script

Now I need to save my script in the proper Script Library in my enabled module:

Action Save

 

At this point my action will show on all reports what list Item objects. But now that my script is saved I can modify its rules to narrow it down only to Show for reports named “ListChildren”. For this I can click the “Runtime” button in the ISE ribbon and edit the “Show if rules are met or not defined” field.
Script Runtime Settings

Now you can specify that you want the action to only appear when the report is named “ListChildren”
Script Rule
Confirm the save on all dialogs to persist your changes. Now our action appears when we run this script in ISE.

Get-ChildItem master:\ | Show-ListView -ViewName ListChildren -Property Name, ProviderPath

Now you see me
The actiona does not appear if no view name is provided to the -ViewName parameter. Running the script below will produce a report with the action not shown:

Get-ChildItem master:\ | Show-ListView -Property Name, ProviderPath

Now you dont

But wait, there’s more!

Updating report in place

The above action works just fine but will close the previous report and open a new report window in the Sitecore desktop. That’s not a great user experience. What if you want to update the content of the report in place using the action? That’s possible using the Update-ListView command. Consider the following script:

Update ListView

In this case we’re not closing the existing report but rather updating the list in place, all you need to do is send the new data to the Update-ListView command.

Showing user progress for long running scripts

One last thing that you might wonder is if the Write-Progress command works as it does in case of ISE or the dialog that runs scripts from Content Editor context menu. Let’s copy the following script into your action:

for($i = 0; $i -le 10; $i++){
  Write-Progress -Activity "I need to do something important for 5 seconds" `
    -Status "I'm quite on track..." `
    -PercentComplete ($i*10) -SecondsRemaining (5-$i/2) `
    -CurrentOperation "Trying to look busy.";
  Start-Sleep -m 500
}

Write-Progress -Activity "Now I'm doing something else..." `
    -Status "Should take me about 3 seconds but I'm not quite sure...";
Start-Sleep -s 3;

for($i = 0; $i -le 10; $i++){
  Write-Progress -Activity "Ok let me revisit one more thing..." `
    -Status "Just 5 more seconds" `
    -PercentComplete ($i*10) -SecondsRemaining (5-$i/2) `
    -CurrentOperation "Just making sure.";
  Start-Sleep -m 500;
}

Write-Progress -Completed -Activity "Done."

And you will see the following output:

Write Progress

Showing other PowerShell dialogs

The action runs fully asynchronously so you’re free to show any of the power of the provided commands. This means that you can ask for additional input using the Read-Variable command or Show alert using the Show-Alert command or do just about anything possible otherwise from the context menu, ribbon or other interactive integration points.

Passing additional data to actions

The Show-ListView command has one more useful parameter named -ActionData which I mentioned above but is worth mentioning again. Anything passed using this parameter will be set as the $actionData variable – this means your report and actions can pass custom data in them it can be as simple as an object or as complex as a hashtable so there is really no hard limit on what can progress from a report to report. Any object that was passed to Show-ListView using the -ActionData parameter will be available to your action.

Actions running in persistent sessions

The persistent session ID as described in my previous post will be respected and your script will run in that persistent session if it’s already in memory or create a persistent session if it’s not.

Alternatively you can elect to simply freeze the session the initial script that generated report was running in and run actions in that same frozen session by using the -ActionsInSession parameter.

Godspeed!

I hope this blog post will help you deliver the best functionality your users expect from you. Happy scripting!

1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading...



This entry (Permalink) was posted on Tuesday, May 5th, 2015 at 10:00 am and is filed under .Net Framework, PowerShell, Sitecore, Software, Software Development, Solution, Uncategorized, 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.