At certain times, you want to populate your site with data in addition to what regularily fits in blocks or pages. Things like comments on articles, product reviews, "likes" or article ratings pops into mind. All these things are content, but they do not seem to fit into any of the default types in EPiServer. A comment for an article isn't really a page, nor a block, and it's certainly not a product variant. But it's still content, and should be treated as such. And for the editor, you'll want some simple, familiar interface to manage them.

With the introduction of the new user interface in CMS 7, along with the strong concept of the IContent interface, we have some pretty nifty options. What about letting the comments pop up in the navigation panes along with blocks, media and (for commerce installations) products? That would be really neat. And here's how.

1. Your custom IContent entity

The very first thing you'll need is the piece of content you want to store. This could be anything, really. It needs to, at least, inherit from IContent. In addition, you may inherit from things like ILocalizable, IVersionable and a whole bunch of other things, depending on your needs. If you look at PageData, for example, it actually implements 16 such interfaces in addition to inheriting from ContentData. Each of them applying a given set of functionality.

In my example, I'm simply going to be implementing a product review type, shown below:

Do notice that I have not given it any reference to the content it belongs to. This is because I'm going to be storing these in product's asset folders, giving it an implicit reference to it's "owner".

2. ContentRepositoryDescriptor

Next, you'll need some sort of way to hook into the user interface of EPiServer. This is done through a descriptor class inheriting from ContentRepositoryDescriptorBase, like shown below

Things to notice

Most of the stuff implemented there should be reasonable intuitive. One exception though: Roots returns an emtpy array of ContentReferences. This property tells EPiServer where to start listing content from. If all your custom entities is stored under a given place in the content tree, locate this and return it here. If you have several root nodes, return all of them. In this example I'm returning none, since I want all my reviews to be located in the reviewed content's asset folder. This will then show up similarily to the "local blocks" folder; "For this page".

3. Navigation component

Next, you'll need a navigation component. Something that describes the front end look and behavior of the descriptor you just made.

Things to notice

Under that given LanguagePath you'll need nodes title and description.

PlugInAreas has two different paths given. The first one is for normal CMS content: this component will be visible on normal CMS pages. The second is to make it visible on Commerce entities. If you need only one of them, remove what you do not need.

4. Add some stuff!

Now, to add some stuff to this place, add it to the Asset folder that belongs to your entity. To have an asset folder, the content type must implement IResourceable. Pages do this out of the box, but if you're creating stuff for a Commerce entity like I am, you need to Implement IResourceable yourself. Adding things to the asset folder of content is done as usual by getting the asset folder content link, and then just using the content repository to save content as usual. Shown below.

After these steps, you should have something that looks more or less like below. You can also edit/delete the reviews via the normal context menus they have, making the need for custom administration interfaces obsolete.

There seems to be a bug here, if using this for Commerce entities, it will display "For this {0}".

Hoorah!

This blog post has taken things from this forum thread, making the info slightly easier accessible.