Virtual Items in Sitecore
One of the many benefits of using a good CMS like Sitecore is the ability to reuse a single piece of content in multiple locations around your site. This ability is provided through virtual items.
So what is a virtual item? A virtual item is an item that doesn’t actually exist. Why wouldn’t you want the item to exist? One reason would be to keep your content tree clean and another would be to reduce the workload on your content authors. Often virtual items are used to provide a single source of content that can be reused throughout multiple points in your site.
In this post I’m going to visit a few options available inside Sitecore for using virtual items and some related options for achieving those goals mentioned above.
Clone items were introduced in Sitecore 6.4. A cloned item uses another item (source item) in the same way template standard values are used. If a cloned item’s field value is null Sitecore will get the value of that field from the clone source. This allows fields of a cloned item to be overridden without affecting the source item.
This option is good when you want a physical item to be shown in the content tree or when you need to allow content authors to create the cloned items themselves. It’s also a good option for when you want to share most of the fields of the source item, but allow overriding of others when the shared item is used, such as whether it would appear in the breadcrumb (if that was controlled through a field value).
Standard values also works with clones, so if a clone source doesn’t have a field value that field value will be read from standard values right through to the clone item itself. If the value is then overridden on the clone source, that overridden values will be read by the cloned item. The clone is an additional layer in the standard values stack.
Cloned items work just like any other item, cause they are actually a real item. So in that respect they’re not actually virtual. But they can help achieve that goal of having a single source for content and reusing that content throughout the website. Because clone items are real items they will have a different ID to the clone source item.
But if I want a single source of content, allowing users to override values on the cloned item itself goes against that. How can I stop content authors from overriding values on cloned items? Simple! The same way you would stop them from editing any piece of content, by using Sitecore security.
If you’re using Sitecore 6.4 or lower then proxy items are what you would use instead of clone items. Proxy items were deprecated in Sitecore 6.5, so if you’re starting a new project you shouldn’t be using them. Although still present in Sitecore 6.5, being that they are deprecated Sitecore may remove this feature entirely in a future release.
Proxy items proxy an item (or subtree) from one part of the content tree to another. Updates to a proxy item will update the source item. This means you can’t override a source item value. Other than that, proxy items work in much the same way as clones do.
Unlike clone items which require a physical item in the content tree, proxy items don’t require a physical target item, so they are actually virtual.
A wildcard item is an item named with an asterisk (*). It will handle any item requests at a single level in the content tree if another item at the same level isn’t found.
So if I have a content tree as follows:
/sitecore/content/home/a /sitecore/content/home/c /sitecore/content/home/*
If I make a request for
/sitecore/content/home/b the wildcard item will handle that request. But if I make a request for
a item will handle that.
Wildcard items only work for a single level. In the above example, if I make a request for
/sitecore/content/home/b/b I’ll get an item not found error. To handle that case I would need a wildcard item under the wildcard item. So I need a wildcard item for every level I want to be able to handle all requests for.
Wildcard items are also real items, but they allow the requesting of virtual items at a single level of the content tree. Being real items they must exist in the content tree. Some people might think this makes the content tree look messy, particularly if you have a lot of wildcard items.
One way to hide the wildcard items from normal content authors is to make the wildcard item hidden. In the content editor navigate to your wildcard item, select it then in the configure tab click the
hide item option in the
attributes section. Now the item will only display in the content tree if the user has ticked the
hidden items option on the view tab in the content editor.
If you need to have a lot of wildcard items in predictable locations or if you really don’t want them shown in the content tree you may need to consider the next option instead.
A fairly straight forward way of handling virtual items at any level without messing up your content tree is to create your own
httpRequestBegin processor and insert it into the pipeline. I like to do this after the existing
ItemResolver, so in my custom processor I can check to see if the context item is null, and only process the request with my processor if it is. Every
httpRequestBegin pipeline processor will run on every request, so you need to ensure processors in this pipeline are as efficient as possible. The simple check for a null context item is very efficient.
With a custom pipeline processor much more complex logic for virtual items can be implemented including checking only for specific item names or allowing any level of virtual item to be requested.
A real world example of this kind of option out in the wild is in the Sitecore eCommerce Fundamental Edition module (SEFE). It uses a custom item resolver after the default Sitecore item resolver to service requests for product which don’t live at the requested location, but exist in another part of the content tree.
I recently used this approach myself in a design. The client wanted an item to appear as a child of another item, but didn’t want that child item to actually be an item in the content tree. All the data required to render the virtual child item was pulled from it’s parent. There were several reasons for this design. Firstly, the client had strict rules around the naming of this item; it must always be called by a specific name. Secondly the virtual child item must always sort in a specific manner; at the bottom of the list of real child pages. Both of those could be achieved through other mechanisms. The biggest factor was the fact that the client didn’t want the virtual item to be edited in a different location to the rest of the data on the parent. They wanted the data for the virtual child item defined on the same item as the parent.
Unlike the above options, this option requires some coding. To implement your own processor, create a class which inherits from
HttpRequestProcessor and override the
Process method. In your method populate the Sitecore context item to whatever it should be based on the incoming request.
This option is good when you have predictable logic or when you don’t want to show the virtual items in the content tree.
If none of the above options satisfy your exact needs you could always implement your own custom data provider to provide the virtual items. The biggest advantage of this approach is that your virtual items will appear in the content tree.
Defining the virtual items will be up to whatever logic you implement in the data provider. You could automatically return the virtual items based on business rules or you could infer the virtual items from data the content authors input on real items.
One such example of this is the Item Mirror Data Provider written by Steve Green. It shows how you can allow selecting items in one part of the content tree to have virtual representations of those items appear in other parts.
This is the most comprehensive approach to virtual items and the most difficult. Implementing a data provider is no mean feat and should not be undertaken lightly.
So there you have a few different options when designing how your virtual items should work. The biggest considerations will be whether you want content authors to define the virtual items (whether directly or indirectly), whether you want them to appear in the content tree and whether you want to use an out-of-the-box solution or write some code to achieve what you want.