Orchard CMS: How To Create Content In Your Module Migrations.cs

18 March 2013

While I'm on an Orchard streak, here's something else that I felt sounded easy on paper, but wasn't well documented.

In the form of a question - "How can I create content (pages, widgets, whatever) when my module is activated?"

To create all content (which again makes judicious use of dynamic objects, since Orchard has no idea what sort of content is being created at compile time / the extension possibilities are endless), Orchard provides the ContentManager class. This magical class is referenced by name in the documentation around content in Orchard, but I didn't find it very well explained.

So looking at it from a few steps back; the ContentManager class is an implementation of the IContentManager interface - however, you don't create an instance of the ContentManager class as you may have been expecting. Instead, Orchard loves Inversion of Control and Dependency Injection with the use of the AutoFac library which sounds really complicated, and I guess in a certain light it is, but you don't have to fully understand the intricacies to be able to get what you want (which in this instance, is a ContentManager class to use).

The steps to get a ContentManager class are:

  1. Have a parameter in your constructor that accepts the type of dependable interface you're after - in this case, we want IContentManager.
  2. In your constructor, assign the parameter to a variable for later use.

So within our migrations code for our module:

    //variable to store the content manager
    private readonly IContentManager _contentManager;

    //constructor parameter accepting IDependency classes
    public Migrations(IContentManager contentManager)
    {
        _contentManager = contentManager;
    }

    public int Create()
    {            
        //we can now use _contentManager!

        return 1;
    }

So great - we have a ContentManager. How can we use it to, for example, create a List? Simple; call the .Create() method (which has a few overloads, the simplest of which is a string for the Content Type name) and then modify any parts or fields you want (by calling the .As<T>() extension method), then .Publish() it.

For example, you can throw the following into your Create() method in migrations.cs:

        var eventList = _contentManager.Create("List");
        eventList.As<TitlePart>().Title = "Sample List";
        _contentManager.Publish(eventList);

And there you have it, content creation on module activation! I guess in some instances you could probably be using Recipes as well; but that's a discussion for another time...

Orchard is great - a lot of really smart thought went into it, and it shows - it's just a shame that to work out how to do this I had to trawl through a trillion pages, and pieced it together with this blog post, and a half example in the Widgets module. Who knows - maybe you aren't supposed to do it this way any more, but if not, there's no documentation about that either ;)

Tags: ContentManager, migrations, module, Orchard

Add a Comment

No Comments