Dispatching Orchard shapes to arbitrary zones
In
my LIDNUG demo
last week, I showed an interesting technique that I know
some people will want to apply to their own stuff.
The scenario is that you want the main content being displayed on the page to render parts of itself outside of the Content zone, typically in a sidebar zone.
My own example was a
Buy From Amazon
part that displays a badge in the sidebar to enable readers
to buy the book being reviewed:
Usually, zones contain widgets, but zones are just shapes, and they can contain any nested shape, not just widgets. Here is the shape we are building from our driver:
var shape = shapeHelper.Parts_BuyFromAmazon(
ProductSku: part.ProductSku,
AssociateAccount: accountSettings.AssociateAccount,
BackgroundColor: accountSettings.BackgroundColor,
TextColor: accountSettings.TextColor,
LinkColor: accountSettings.Linkcolor,
Width: accountSettings.Width,
Height: accountSettings.Height,
ContentItem: part.ContentItem);
Nothing fancy here. In order to send that shape to the sidebar, all we need is a reference to the current work context in our part driver. This is easily obtained by injecting a dependency to IWorkContextAccessor.
Once this is done, we can just get the layout shape from the work context, and then access its zones. Once we have the right one, we can add our shape to it:
_workContextAccessor.GetContext()
.Layout.Zones[zone]
.Add(shape, position);
Finally, we return an empty driver result rather than the shape, so nothing gets rendered in place:
return new DriverResult();
When the zone where we sent the shape is going to render, our shape will get resolved to a template exactly like a widget would. For all practical purposes, this is like a local widget that your content item gets to create and control.