Layer Template

Topics: General
Apr 23, 2011 at 5:31 PM

Is it possible to create a layer template? I want CMS users to be able to create a new page, then add a set of widgets defined in the different zones as decided by me. For example, I want an HtmlWidget to be in the Content, AfterContent and AsideFirst zones for "layer template 1". A user creates a page then goes and creates a layer for it with the "layer template 1" template. Now, they have all the HtmlWidgets ready to edit.


Apr 23, 2011 at 5:34 PM

This could be done as a module, handling the creational event, and creating layers and contents specifically for this page.

Implement a Handler, and hook the specific event, then you can find some examples of Layers/Widgets creationg in the Setup code, on in the Blog recipe file in this module. If you want it to be triggered by a user's choice, like a drop down list, you could also create a Part instead of a handler.

Apr 23, 2011 at 6:41 PM

It looks like it's all done in the recipe files now? I can't seem to find any examples of creating layers and adding widgets except for in the recipe files in the setup module.

Apr 23, 2011 at 7:26 PM

 I think I have it now, using IContentManager?

How can I create a layer part without having to reference Orchard.Widgets in my project?

Apr 23, 2011 at 9:58 PM
Edited Apr 23, 2011 at 9:58 PM

You absolutely need the reference. Then you can import IWidgetsService as a dependency and use its CreateLayer and CreateWidget methods.

Apr 23, 2011 at 10:56 PM

Thanks. I've pretty much got what I needed but I'm having one last problem with casting my part into a RoutePart to get the title, so that I have something to name the new layer. Here's a simple version of what I have (the page part is just an empty class that inherits from content part):

ContentDefinitionManager.AlterPartDefinition(typeof(PagePart).Name, cfg => cfg.Attachable());

ContentDefinitionManager.AlterTypeDefinition("LeftNavigationPage", cfg => cfg

Then a handler that I want to handle the event when a user clicks the "save" button:
  OnCreating((ctx, part) =>
	   if(ctx.ContentType == "LeftNavigationPage")
		   var route = part.ContentItem.As<RoutePart>();
		   var layer = widgetService.CreateLayer(route.Title, String.Empty, String.Format(@"url ""~/{0}""", route.Slug));

		   var leftNav = widgetService.CreateWidget(layer.ContentItem.Id, "HtmlWidget", String.Empty, "1", "AsideFirst");

The route variable is not null, but all of it's properties are. I've tried handling OnCreated<PagePart>, OnCreated<RoutePart>, OnCreated<ContentPart> etc. but it's always null. 

Apr 23, 2011 at 11:13 PM

I think you need Publishing / Published. Work of warning here tho; the Publish event gets triggered asynchronously when you fill in the title; what happens is a "fake" ContentItem gets not-really-published to create the slugified title. Not sure if this will cause you a problem or not but it's a confusing side effect if you're not expecting it. I don't actually know how to work around this. I raised a workitem:

Apr 24, 2011 at 3:54 AM

Tried handling Published/Publishing, but it has the same effect.

Apr 24, 2011 at 4:03 AM

Strange ... for the ContentNotifications module I used the Published event and was able to get the title fine.

The only difference is I used As<IRoutableAspect>() instead of As<RoutePart>() ... you could see if that makes any difference (but I don't know why it would).

Apr 24, 2011 at 5:45 AM

Is your module in the gallery? If so, I might take a peak to see if you're doing anything different ;)

Apr 24, 2011 at 5:59 AM


You want to look at PublishNotificationPart and PublishNotificationPartHandler.

To be honest I haven't tested it since Orchard 1.1 came out so let me know how it goes. If there are any problems I need to figure out how to fix it anyway!