The Shape Tracing feature for Orchard makes it a snap to find and override shapes all over your sites, and I use it regularly to create alternates. A common use case is to find and override a part’s shape based on it’s content type – really useful if you want to alter how a part looks if it is on a page, product, contact, etc. I found myself in a scenario today where I wanted to override a shape based on both the content type or the display type, and both at the same time.
The documentation on Alternates lists only 2 alternates for parts, [ShapeType]__[ContentType], and [ShapeType]__[Id], but thanks to Orchard’s near-infinite level of flexibility, we can quite easily add as many alternates as we want.
A quick read through WidgetAlternatesFactory and UrlAlternatesFactory should be more than enough to get you started, but the key is to latch on to when a shape is displayed, and inject some alternate shape names.
I ended up with the following implementation:
public class PartContentTypeAlternateFactory : ShapeDisplayEvents {
public override void Displaying(ShapeDisplayingContext context) {
context.ShapeMetadata.OnDisplaying(displayedContext => {
var shapeType = displayedContext.ShapeMetadata.Type;
var contentItem = displayedContext.Shape.ContentItem;
var displayType = displayedContext.ShapeMetadata.DisplayType;
var contentType = contentItem.ContentType;
displayedContext.ShapeMetadata.Alternates.Add(
String.Format("{0}__{1}", shapeType, displayType));
displayedContext.ShapeMetadata.Alternates.Add(
String.Format("{0}__{1}__{2}", shapeType, (string)contentType, displayType));
});
}
}And you end up with some alternates like this:
Surprisingly, I couldn’t find any information about people hitting this problem before (maybe I’m just doing it wrong?), but if this helps let me know in the comments!
Alternates are very powerful, for example you can customise the shape of the first item on your blog, override shapes based on the current URL, and much more.
Happy Orcharding!









