Having trouble setting up Area within my module

Topics: Customizing Orchard, General, Troubleshooting, Writing modules
Mar 1, 2012 at 7:36 PM

I've been working on my site so far using a single module and I decided to start putting some features into separate MVC areas because it's becoming unwieldy to have it all in one module without subdividing into some areas. 

I created a new folder for the area in my module root, let's say it's called "Cooking". Folder structure looks something like this: 













When I try to build and run the project I get an error when I navigate to Dashboard -> Content. The recipe I run imports some content items defined in the Cooking" area. Here's the error I get: 

Shape type Parts_RankingsEntity_SummaryAdmin not found

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: Orchard.OrchardException: Shape type Parts_RankingsEntity_SummaryAdmin not found

Source Error: 

Line 89:                 }
Line 90:                 else {
Line 91:                     throw new OrchardException(T("Shape type {0} not found", shapeMetadata.Type));
Line 92:                 }
Line 93:             }

Source File: C:\projects\OrchardEnlistments\autroute\src\Orchard\DisplayManagement\Implementation\DefaultDisplayManager.cs    Line: 91 

Stack Trace: 

[OrchardException: Shape type Parts_RankingsEntity_SummaryAdmin not found]
   Orchard.DisplayManagement.Implementation.DefaultDisplayManager.Execute(DisplayContext context) in C:\projects\OrchardEnlistments\autroute\src\Orchard\DisplayManagement\Implementation\DefaultDisplayManager.cs:91
   Orchard.DisplayManagement.Implementation.DisplayHelper.ShapeExecute(Object shape) in C:\projects\OrchardEnlistments\autroute\src\Orchard\DisplayManagement\Implementation\DisplayHelper.cs:71
   Orchard.DisplayManagement.Implementation.DisplayHelper.Invoke(String name, INamedEnumerable`1 parameters) in C:\projects\OrchardEnlistments\autroute\src\Orchard\DisplayManagement\Implementation\DisplayHelper.cs:38
   Orchard.DisplayManagement.Implementation.DisplayHelperBehavior.InvokeMember(Func`1 proceed, Object target, String name, INamedEnumerable`1 args) in C:\projects\OrchardEnlistments\autroute\src\Orchard\DisplayManagement\Implementation\DisplayHelperFactory.cs:27
   ClaySharp.<>c__DisplayClass16.b__13() in C:\Users\sebros\My Projects\Clay\src\ClaySharp\ClayBehaviorCollection.cs:29
   ClaySharp.ClayBehaviorCollection.Execute(Func`1 proceed, Func`3 linker) in C:\Users\sebros\My Projects\Clay\src\ClaySharp\ClayBehaviorCollection.cs:13
   ClaySharp.ClayBehaviorCollection.InvokeMember(Func`1 proceed, Object self, String name, INamedEnumerable`1 args) in C:\Users\sebros\My Projects\Clay\src\ClaySharp\ClayBehaviorCollection.cs:29
   Orchard.Core.Shapes.CoreShapes.ContentZone(Object Display, Object Shape, TextWriter Output) in C:\projects\OrchardEnlistments\autroute\src\Orchard.Web\Core\Shapes\CoreShapes.cs:236

Is this caused because I have a module.txt in both my module root and in a sub-directory? The View template it's erring on here exists in Cooking/Views/Parts/RankingsEntity.SummaryAdmin.cshtml. It was working fine until I tried to move all this stuff into the sub area.  

Mar 1, 2012 at 7:49 PM

My first thought was: what I think is happening here is that Orchard is looking for a shape template "Parts_RankingsEntity_SummaryAdmin.cshtml" in the Views folder directly in the root of the module, not bothering to iterate though each subfolder (even though you have a Module.txt file in the subarea).

But then again, the Orchard.Core project does the exact same thing: it hosts all sorts of modules in subareas.
I'm curious what could be causing this error you're seeing.

Mar 1, 2012 at 7:51 PM

Perhaps you should try and also add a Placement.info into your subarea? (although omitting placement should just prevent shapes from rendering)

Mar 1, 2012 at 8:04 PM

Copied placement.info from root to /Cooking and that didn't fix it. 

Also tried updating all the stuff in Cooking folder to use namespace MyModule.Cooking -- also didn't solve the problem. 

The stuff I've seen so far in Orchard is using parallel Areas, none of them are using nested ones as I am attempting. I wonder if this is something I'm not supposed to do? 

Mar 1, 2012 at 8:07 PM

Perhaps you could try moving the stuff from the root of your project into a subarea as well?

Mar 1, 2012 at 8:32 PM
Edited Mar 1, 2012 at 8:34 PM

Tried that, now my setup recipe fails because it can't find my "Main" module or the recipe. Man, starting to regret ever trying this.. 

I created a new folder "Main" alongside "Cooking". Moved everything from root to "Main". Appended .Main to all namespaces inside the Main folder. 


System.InvalidOperationException: Could not enable feature MyModule because it was not found.

Mar 1, 2012 at 8:47 PM

I just created a new module and put everything in a subfolder, but Orchard doesn't seem to notice there's a new module in town. I'll have a look using the debugger and see why that's so.

Mar 1, 2012 at 9:14 PM
Edited Mar 1, 2012 at 9:16 PM

Ah I think see what's going on. Orchard will actually not look any level deeper than the root of each module's folder. This is true both for Core modules as well as custom modules as well as themes. You can see this when stepping though the ExtensionHarvester class.

Basically, what Orchard is doing is iterating though each subdirectory of some root directory: "Core", "Themes" and "Modules". For each subdirectory, it will see if there is a Module.txt available. If not, then it simply moves on, ignoring the subdirectory its currently in.

Now, this behavior is implemented inside the ExtensionHarvester, which is registered with the IoC container in the OrchardStarter class. That unfortunately means you cannot provide your own implementation of it (unless you modify the source). I do think it would be a rather nice feature to be able to divide a single module into logical areas.

What would be nice is if the discovery of modules were extensible, so that we could implement our own mini harvester.

Mar 1, 2012 at 9:18 PM
Edited Mar 1, 2012 at 9:23 PM

What I currently do is simply create multiple class library projects. For example, I have one Skywalker.Common module that provides commonly used features. Then I have 2 or 3 other modules, possibly one having a dependency on the other.

This will in effect achieve what you're trying to do. The only difference is that I am using multiple class libraries instead of one.

Mar 1, 2012 at 9:19 PM

Interesting. I was getting pretty frustrated with this and tore up my source code folder structure and files trying to get it working. Thank Jeebus for source control. 

I think your suggestions sound good. Thanks for the help!

Mar 1, 2012 at 9:21 PM

I'll either do that or simply use multiple modules. I wasted enough time on this today that I will just go back to a monolithic module so I can make some progress on my site for the day.