This project is read-only.

Custom Module/Type vs UI Created Part

Topics: Customizing Orchard, General
Apr 14, 2011 at 6:22 PM

While I attempt to wrap my head around all the different things that Orchard does to do what it does, I'm stuck wondering exactly when I should create a content part via the UI and when I need to make my own - but I think I'm almost there.

Let's say I have a website that is served just well from the CMS, but I also need to add locations (like stores). i could just create a new part, with the locations details, create a list that contains the locations and then create special views for these parts. It works just fine. I can see a list of locations, the details, etc. The permalink is little manual (if I want to use the address), but with no code-writing, who cares! So in this case, would there be a need for any custom work? What would be the benefits?

I do see a problem, however, if I needed specific querying capability. Let's say I needed to display the locations within 5 miles of a zip code. There does not seem to be a way to handle this, I then would need to create a module where i can add this capability via the drivers, handlers, routes, etc.

Does that sound right? Am I missing something from the big picture?

Apr 14, 2011 at 6:59 PM

The way I approach it is, if I need any custom functionality that's not available in the UI, I'll typically build a Part that wraps up that functionality. Then I can build a type in the Dashboard and add the part to it. Or I could write a module specifically for my website to build the content type from that part. Or I can build it in a Recipe.

One time when it really makes sense to create content types from code (i.e. in Migrations) is when you're building a bigger feature where several types need to interact with each other. For instance if I was building a Forums module then yes I'd create ForumThread, ForumPost, and Forum content types in Migrations (but each of those would be composed of parts as generalised as possible). The same would hold for Blog / BlogPost.

So if you're building redistributable add-on components I think it's best to avoid creating types as far as possible; it could easily create naming conflicts with other types the user already has, and it's nice to leave it up to the user to choose what their content types are called. With the forums example, you could easily just create parts called ForumPart, ForumThreadPart, ForumPostPart; and then let the user add them to whatever content types they like, even multiple ones - so you could have an "Images Forum" with templates geared towards displaying thumbnails, and a "Chat Forum" for normal text posts.

I don't think there can really be any strong guidelines for this, though; the options are all there and it's a case of what makes most sense for a given task.

Apr 14, 2011 at 8:44 PM

Although my exposure and experience of Orchard is somewhat limited (a couple of weeks) I'm taking the approach that the missus (who is sat just opposite me) whilst is not PC Illiterate isn't too technically minded and wouldn't know her arse from her elbow if she had to try and put parts together from the UI. As is such I plan to do everything as much as I can as modules so she can just download and go.

Downloading/Installing from the gallery is a breeze and I plan to abuse that fact as much as is humanly possible ;)

Apr 14, 2011 at 9:56 PM

Is there any way to manage which queries get run when using the built-in types? Like using the long/let from fields? Or this that additional functionality you mentioned?

Apr 14, 2011 at 10:02 PM

Is there somewhere that an external part (like a custom part/field) can talk to your own record for persistance.

Let's say I have a location with a lat/long. And I want to create a custom type/field that will allow me to click on a map to save the coordinates. Is there a way to get those values from the external field and save them to my custom part and not in Orchards structure?

Apr 14, 2011 at 10:05 PM

You can have properties on a part. Take a look at this: (it has exactly what you are asking for).

Apr 14, 2011 at 10:05 PM
Edited Apr 14, 2011 at 10:06 PM

When you create a ContentPart you also create a ContentPartRecord which defines the table that the properties of the part are persisted to.

There is already a map module on the Gallery that you can have a look at as an example (I'm not sure if it goes as far as storing lat/long)

Edit: There you go ;)

Apr 15, 2011 at 12:57 AM

@bertrandleroy - that's exactly what I had in mind. Funny enough, I had it open in a tab that from a search in the gallery. Thanks for the pointer.

I haven't looked at the Bing Map List's code, but I was asking whther one could extract the properties from a different part/field and use it my own module's properties (to save it in the db as a flat record instead as part of the content's parts record)

Apr 15, 2011 at 1:00 AM

I didn't answer that other question because until I see a scenario that justifies it, it doesn't seem to make a lot of sense to me. But yes, you can .As<> a content item to cast it into another part and peek inside, and that includes looking at fields.

Apr 15, 2011 at 1:05 PM


The current justification, and I don't know Orchard at all well, but unless I'm mistaken, when you build parts composed of other parts and fields the data is not flat as you would expect it an in RDMS. So while having it display in Orchard is very simple, through the use of the templates and zones (an impressive system) it doesn't help other business uses. Some justifications would be querying by any field, web services, access for other apps, etc.

However, thinking about it now, maybe a view would solve the issue here. One could easily create a view with all the joined tables that could be used by other data access means.

Apr 15, 2011 at 8:08 PM

But you *can* query by any property of any part so I'm not sure what you're saying here. Your original question seemed to be different though: "I was asking whther one could extract the properties from a different part/field and use it my own module's properties (to save it in the db as a flat record instead as part of the content's parts record)" It's that part about duplicating the info from another part into your own that I can't see any justification for (although it's technically possible).

Apr 15, 2011 at 9:54 PM

So that I could extract it, save it in my own objects properties, save it and then query for it later.

Any docs on querying by part and where in the pipeline you would do this or this a custom module/part scenario?

Apr 15, 2011 at 10:17 PM

Why would you need to make a copy of it in order to query it?

Look for examples in the source of using ContentManager.Query.