Find items which override standard values using Revolver

1

April 24, 2009 by Alistair Deneys

For a while now, the best practice for assigning presentation in Sitecore has been to apply the presentation to an item’s template standard values rather than on the item itself. This has some distinct advantages. Firstly, presentation is usually defined by the type of the item, such as a list page or a news page. It makes sense that we have a central place in which to define the presentation for all items of this type. Secondly it is much easier to update presentations site wide if all the presentations are defined in a central location. For example, we might now want to bind a mini-search component onto each page, but want to use dynamic binding and placeholders rather than statically placing the component on a layout or sublayout used by all pages.

But what about those single items that are unique in their presentation? Wouldn’t it make sense to break the rule for these? Just go ahead and define the presentation on the item itself? These items are usually things like the “contact us” item or some other form which only exists in a single place. To keep in line with the best practices, we would have to create a template for each of these unique presentation items which sounds like a lot of work, not to mention the increased number of templates we now have to manage.

So it sounds tempting to break the rule and allow presentation on the item itself. Until it comes time for maintenance on the site. And not maintenance 2 weeks after going live, try after 6 months when those individual items that “we were sure we’d never forget about” are floating around the content tree somewhere we can’t remember 😦 . Hind sight is 20/20.

So for these reasons, just let me clarify the answer to this dilemma before continuing. Don’t break the rule. Only assign presentation to standard values. It doesn’t matter if you have an additional 15 templates. More templates is far more desirable than trawling the content tree looking for items which might have presentation defined on them.

So what can I do if I had a moment of insanity and ignored this rule and defined presentation on the unique items directly? As usual, it’s Revolver to the rescue!

Unfortunately, if you request a field value in Sitecore, Sitecore will return to you either the field value of the item if it exists, or the standard value if the item doesn’t override the field value.

gf -f __renderings

Using the above command we cannot determine if the field value comes from the item or from the standard values. What’s more, if I list all the item’s fields:

gf

Only fields which are set on the item are returned. But the output of this command is not particularly useable. So how could we determine, through examining field values if an item has overridden the standard values of it’s template. Well we know we can retrieve an item’s field value. We know we could also grab the item’s template id:

ga -a templateid

And we can use IDs with the cd command. So we can easily, from the item, change our context to it’s template, find it’s standard values, then get the field value on the standard values. If the field value is different, then we know the item has overridden the standard values. So let’s combine all this together into a Revolver script, so we can navigate to a single item, execute the script, and get some kind of indication as to whether the item’s field value is the same as it’s template, or if it’s different, indicating an overridden standard value. For the following example, we’ll focus on comparing the __renderings field, which is where the presentation is defined.

Let’s start by storing the item’s field value in an environment variable so we can use it later to compare against.

set itemfield < (gf -f __renderings)

Now we need to navigate to the item’s template so we can get the field value from the standard values.

cd < (ga -a templateid)

About the only way we can compare a field in Revolver to some arbitrary string is using the find command with an expression filter or a field filter. For more info on expressions in Revolver, just type “help expressions” in the Revolver shell prompt. For this example we’ll use a field filter. So we’ll see if we can find the standard values item of the template, by applying the field filter. If we find the item we’ll echo the text “match!”.

find -f __renderings ($itemfield$) (echo match!)

The find command operates on the children of the current item. So in the above example, we’re relying on the fact that the standard values item will be the only item with presentation defined (as well it should be). If a child item (standard values) __renderings field matches the field value from the item, then we get the “match!” text displayed, as well as a message saying we found 1 item.

If this were in a script, we’d also want to return to the previous context item as our current context is on the item’s template. Revolver stores the previous context path whenever the cd command is run in an environment variable called “prevpath”, so we can revert our context by executing:

cd ($prevpath$)

We wrap parenthesis around the variable prevpath in case it includes spaces in it.

We could make this script a little more generic and reusable by using arguments which can be passed to the script to check any field of an item against it’s standard values. This could also be handy for fields such as “display in breadcrumb” and such where you normally use the standard value of “true” (1) but might occasionally want to see what doesn’t follow the default. The resulting script might look like this.

set itemfield < (gf -f ($1$))
cd < (ga -a templateid)
find -f ($1$) ($itemfield$) (echo match!)
cd ($prevpath$)

Let’s name this script “issv” (IS Standard Values). Now we can navigate to an item and execute the script, providing it the field we want to compare.

issv __renderings

Executing this against an item that has been overridden:

<?xml version="1.0" encoding="utf-16"?>
<r xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <d id="{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}" l="{14030E9F-CE92-49C6-AD87-7D49B50E42EA}">
    <r ds="" id="{67FE0428-DFDA-488E-B772-B5DFA2F89A16}" par="" ph="main" uid="{3F6D1B32-8D68-432A-976D-46C3DE95BB82}" />
    <r ds="" id="{F53BB574-1CF8-4446-A127-0EBCA1AA6D9E}" par="" ph="main" uid="{586D9E7F-8CB3-4399-A33C-C5BB90749FC7}" />
  </d>
</r>
/sitecore/templates/User Defined/Doc
Found 0 items
/sitecore/content/Home/New Doc

Executing this against an item which has not been overridden (the standard value is used):

<r xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <d id="{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}" l="{14030E9F-CE92-49C6-AD87-7D49B50E42EA}">
    <r ds="" id="{885B8314-7D8C-4CBB-8000-01421EA8F406}" par="" ph="main" uid="{43222D12-08C9-453B-AE96-D406EBB95126}" />
    <r ds="" id="{CE4ADCFB-7990-4980-83FB-A00C1E3673DB}" par="" ph="/main/centercolumn" uid="{CF044AD9-0332-407A-ABDE-587214A2C808}" />
    <r ds="" id="{493B3A83-0FA7-4484-8FC9-4680991CF743}" par="" ph="/main/centercolumn/content" uid="{B343725A-3A93-446E-A9C8-3A2CBD3DB489}" />
  </d>
  <d id="{46D2F427-4CE5-4E1F-BA10-EF3636F43534}" l="{14030E9F-CE92-49C6-AD87-7D49B50E42EA}">
    <r ds="" id="{493B3A83-0FA7-4484-8FC9-4680991CF743}" par="" ph="content" uid="{A08C9132-DBD1-474F-A2CA-6CA26A4AA650}" />
  </d>
</r>
/sitecore/templates/Sample/Sample Item
match!
Found 1 item
/sitecore/content/Home/Sample Item

See in the second output we get the “match!” string output. This is good if we just want to test single items at a time, but what about searching the entire content tree (content section) for items which override their standard values presentation? Combine the issv script with the find command.

cd /sitecore/content/home
find -r (issv __renderings)

...

<?xml version="1.0" encoding="utf-16"?>
<r xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <d id="{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}" l="{14030E9F-CE92-49C6-AD87-7D49B50E42EA}">
    <r ds="" id="{67FE0428-DFDA-488E-B772-B5DFA2F89A16}" par="" ph="main" uid="{3F6D1B32-8D68-432A-976D-46C3DE95BB82}" />
    <r ds="" id="{F53BB574-1CF8-4446-A127-0EBCA1AA6D9E}" par="" ph="main" uid="{586D9E7F-8CB3-4399-A33C-C5BB90749FC7}" />
  </d>
</r>
/sitecore/templates/User Defined/Doc
Found 0 items
/sitecore/content/Home/New Doc

<r xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <d id="{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}" l="{14030E9F-CE92-49C6-AD87-7D49B50E42EA}">
    <r ds="" id="{885B8314-7D8C-4CBB-8000-01421EA8F406}" par="" ph="main" uid="{43222D12-08C9-453B-AE96-D406EBB95126}" />
    <r ds="" id="{CE4ADCFB-7990-4980-83FB-A00C1E3673DB}" par="" ph="/main/centercolumn" uid="{CF044AD9-0332-407A-ABDE-587214A2C808}" />
    <r ds="" id="{493B3A83-0FA7-4484-8FC9-4680991CF743}" par="" ph="/main/centercolumn/content" uid="{B343725A-3A93-446E-A9C8-3A2CBD3DB489}" />
  </d>
  <d id="{46D2F427-4CE5-4E1F-BA10-EF3636F43534}" l="{14030E9F-CE92-49C6-AD87-7D49B50E42EA}">
    <r ds="" id="{493B3A83-0FA7-4484-8FC9-4680991CF743}" par="" ph="content" uid="{A08C9132-DBD1-474F-A2CA-6CA26A4AA650}" />
  </d>
</r>
/sitecore/templates/Sample/Sample Item
match!
Found 1 item
/sitecore/content/Home/real

...

So we can now see (once we paw through the output) which item’s override their standard values. And if we pull this into a text editor, all we have to do is search for the “Found 0 items” text to find the culprits.

Another way to check the item’s field value against it’s standard value, and have a bit nicer display of the differences, would be to export the field values and save them into files on the server’s file system, then use an external file compare utility to highlight differences for us. For this approach, we want to export the field value into a file which is stored on disk using the item’s ID as the filename for easy identification of the item during the file comparison. We would also export the standard value for each item into another folder.

Let’s start this approach by exporting the value of the field to a file which uses the item’s ID as the filename.

set p < (ga -a id)
echo -f c:\temp\comp\$p$.txt < (gf -f __renderings)

Now, export the standard value to file.

cd < (ga -a templateid)
echo -f c:\temp\compsv\$p$.txt < (gf -f __renderings (__standard values))

Of course you need to make sure the output folders exist before running the commands.

Now that the item’s field value and the standard values are on disk, we can use an external file compare tool such as WinMerge to compare which files are different. But before we do that, let’s put the above examples into a script so we can run this over all the content items again.

set p < (ga -a id)
echo -f c:\temp\comp\$p$.txt < (gf -f $1$)
cd < (ga -a templateid)
echo -f c:\temp\compsv\$p$.txt < (gf -f $1$ (__standard values))
cd ($prevpath$)

And I’ll name this script “outv”. Now let’s combine that with the recursive find command.

cd /sitecore/content/home
find -r (outv __renderings)

And this is what the folder comparison results look like in WinMerge.

field comp

So I can now see the top three items are different, and I have their IDs so I can easily navigate to them in Revolver, or even paste the ID into the search box inside the desktop to open the content editor on the item.

I hope this helps alleviate some pain for you when you have to do maintenance or updates on those old projects. And I’ve already added a feature request on the Revolver backlog to allow finding items which override standard values much easier.

Advertisements

One thought on “Find items which override standard values using Revolver

  1. […] Deneys have blogged about how to do something like this in Revolver, You might want to read his blog before proceeding. I will try to replicate some of that in […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

The views expressed on this blog are solely my own and do not necessarily reflect the views of my employer.
%d bloggers like this: