January 2012

Volume 27 Number 01

Orchard CMS - Orchard Extensibility

By Bertrand Le | January 2012

Most Web applications have a lot in common but at the same time exhibit a lot of differences. They all have static pages (“Terms of Use,” “About Us” and so on). They present contents within a common layout. They have navigation menus. They might have search, comments, ratings and social network integration. But some are blogs, some sell books, some keep friends in touch and some contain hundreds of thousands of reference articles on your favorite technologies.

A Content Management System (CMS) aims at providing the common pieces while imposing no constraints on the type of site being built. It’s a delicate exercise in extensibility.

The creators  of the Orchard CMS (orchardproject.net)—that includes me—have opted for an approach that relies massively on composition and convention. In this article, I’ll present a few examples of simple extensions to the system that should be a good starting point for your own modules.

A Dynamic Type System

No matter what CMS you use to build your site, there will be a central content entity that goes by different names. In Drupal, it’s called a node, and in Orchard, it’s a content item. Content items are atoms of content such as blog posts, pages, products, widgets or status updates. Some of them correspond to a URL, and some don’t. Their schemas vary greatly, but what they have in common is they’re the smallest content units on the site. Or are they?

Splitting the Atom

As developers, our first reaction is to identify content items as instances of classes (post, page, product or widget), which is correct to an extent. In the same way that classes are composed of members (fields, properties and methods), content types (the “classes” of content items) are themselves composite objects. Instead of being composed of simple properties with types that are themselves classes, they’re composed of content parts, which are the atoms of behavior of your content. This is an important distinction, which I’ll illustrate with an example.

A blog post typically is composed of a URL, title, date, rich text body, a list of tags and a list of user comments. None of those parts is specific to a blog post. What makes a blog post is the specific composition of the parts, not just any one of the parts.

Most blog posts have comments, but comments could also be used in a commerce site to implement reviews. Similarly, tags are potentially useful as a way to classify any content item, not just blog posts. The rich text body of a post is no different from the body of a page. The list goes on. It should be clear at this point that the unit of behavior on a Web site is smaller than the unit of content.

Another fact about CMSes is that content types aren’t fixed in advance. Blog posts used to be simple text, but they quickly became a lot more. They now routinely contain videos, podcasts or image galleries. If you blog about your travels around the world, maybe you’ll want to add geolocation to your posts.

Again, content parts come to the rescue. You need a longitude and latitude? Extend the blog post type by adding a mapping part (we have several available in our module gallery: gallery.orchardproject.net). It quickly becomes obvious when you think about it that this operation of adding a part to an existing type will be performed most often by the owner of the site, not by a developer. Hence, it shouldn’t be possible only by adding a complex property to a Microsoft .NET Framework type. It has to be metadata-driven and happen at run time so that we can build an admin UI to do it (see Figure 1).

The Orchard Content Type Editor
Figure 1 The Orchard Content Type Editor

This is the first way to extend Orchard: You can create and extend content types at will from the admin UI. Of course, anything that you can do from the admin UI, you can do from code, such as this:

item.Weld(part);

This code welds a part onto a content item dynamically. That’s an interesting possibility, as it allows instances of types to be extended dynamically at run time. In dynamic languages, this is called a mix-in, but it’s a concept that’s almost unheard of in statically typed languages such as C#. This opens up new possibilities, but it isn’t exactly the same thing as what we were doing from the admin UI. We also want to be able to add the part to the type once and for all instead of adding it to each instance, as shown here:

ContentDefinitionManager.AlterTypeDefinition(
  "BlogPost", ctb => ctb.WithPart("MapPart")
);

This is actually exactly how the blog post content type is defined in the first place:

ContentDefinitionManager.AlterTypeDefinition("BlogPost",
  cfg => cfg
    .WithPart("BlogPostPart")
    .WithPart("CommonPart", p => p
      .WithSetting("CommonTypePartSettings.ShowCreatedUtcEditor", "true"))
      .WithPart("PublishLaterPart")
      .WithPart("RoutePart")
      .WithPart("BodyPart")
  );

You may notice in this code snippet that tags and comments seem to be missing from blog posts. This is one more example of careful separation of concerns. The blog module actually knows nothing of tags and comments, no more than the tags and comments modules do about blogs. A third party is responsible for putting them together.

Yummy Recipes

At setup, a recipe is executed that’s responsible for this type of task. It’s an XML description of the initial configuration of the site. Orchard comes with three default recipes: blog, default and core. The following code shows the part of the blog recipe that adds the tags and comments to blog posts:

<BlogPost ContentTypeSettings.Draftable="True" TypeIndexing.Included="true">
  <CommentsPart />
  <TagsPart />
  <LocalizationPart />
</BlogPost>

I’ve shown so far the various ways in which content parts can be composed into content items. My next step will be to explain how you can build your own parts.

Building a Part

To illustrate the process of building a new part, I’m going to rely on the example of the Meta feature from my Vandelay Industries module (download it from bit.ly/u92283). The Meta feature adds keywords and description properties for Search Engine Optimization (SEO) purposes (see Figure 2).

The SEO Meta Data Editor
Figure 2 The SEO Meta Data Editor

These properties will be rendered into the head section of the page as standard metatags that search engines understand:

<meta content="Orchard is an open source Web CMS built on ASP.NET MVC."
  name="description" />
<meta content="Orchard, CMS, Open source" name="keywords" />

The Record

The first piece of the puzzle will be a description of the way in which the data is going to be persisted into the database. Strictly speaking, not all parts need a record, because not all parts store their data in the Orchard database, but most do. A record is just a regular object:

public class MetaRecord : ContentPartRecord {
  public virtual string Keywords { get; set; }
  public virtual string Description { get; set; }
}

The MetaRecord class derives from ContentPartRecord. This isn’t absolutely necessary, but it’s definitely convenient as it gets some of the plumbing out of the way. The class has two string properties, for keywords and description. These properties must be marked virtual so the framework can “mix-in” its own logic to build the concrete class that will be used at run time.

The record’s sole responsibility is database persistence, with the help of a declaration for the storage mechanism that can be found in the MetaHandler:

public class MetaHandler : ContentHandler {
  public MetaHandler(
    IRepository<MetaRecord> repository) {
    Filters.Add(
      StorageFilter.For(repository));
  }
}

The storage also has to be initialized. Early versions of Orchard were inferring the database schema from the record classes, but guessing can only take you so far, and this has since been replaced with a more accurate migration system where schema modifications are explicitly defined, as shown in Figure 3.

Figure 3 Explicitly Defined Schema Modifications

public class MetaMigrations : DataMigrationImpl {
  public int Create() {
    SchemaBuilder.CreateTable("MetaRecord",
      table => table
        .ContentPartRecord()
        .Column("Keywords", DbType.String)
        .Column("Description", DbType.String)
    );
    ContentDefinitionManager.AlterPartDefinition(
      "MetaPart", cfg => cfg.Attachable());
    return 1;
  }
}

The MetaRecord table is created with a name that the system will be able to map by convention to the MetaRecord class. It has the system columns for a content part record added by the call to the ContentPartRecord method, plus the Keywords and Description string columns that will automatically map by convention to the corresponding properties of the record class.

The second part of the migration method says that the new part will be attachable from the admin UI to any existing content type.

The Create method always represents the initial migration and usually returns 1, which is the migration number. The convention is that in future versions of the module, the developer can add UpdateFromX methods, where X is replaced by the migration number from which the method operates. The method should return a new migration number that corresponds to the new migration number of the schema. This system allows for smooth, independent and flexible upgrades of all components in the system.

To represent the actual part, a separate class is used, which I’ll look at now.

The Part Class

The representation of the part itself is another class that derives from ContentPart<TRecord>:

public class MetaPart : ContentPart<MetaRecord> {
  public string Keywords {
    get { return Record.Keywords; }
    set { Record.Keywords = value; }
  }
  public string Description {
    get { return Record.Description; }
    set { Record.Description = value; }
  }
}

The part acts as a proxy to the record’s Keywords and Description properties as a convenience, but if it didn’t, the record and its properties would still be available through the public Record property of the base ContentPart class.

Any code that has a reference to a content item that has the MetaPart part will be able to gain strongly typed access to the Keywords and Description properties by calling the As method, which is the analog in the Orchard type system of a CLR cast operation:

var metaKeywords = item.As<MetaPart>().Keywords;

The part class is also where you’d implement any specific behavior of the part’s data. For example, a composite product could expose methods or properties to access its subproducts or compute a total price.

Behavior that pertains to user interaction (the orchestration code that would in a regular ASP.NET MVC application be found in the controller) is another matter. This is where drivers come in.

The Driver

Each part in a content item has to get an opportunity to participate in the request lifecycle and effectively do the work of an ASP.NET MVC controller, but it needs to do it at the scale of the part instead of doing it at the scale of the full request. A content part driver plays the role of a scaled-down controller. It doesn’t have the full richness of a controller in that there’s no mapping to its methods from routes. Instead, it’s made of methods handling well-defined events, such as Display or Editor. A driver is just a class that derives from ContentPartDriver.

The Display method is what gets called when Orchard needs to render the part in read-only form (see Figure 4).

Figure 4 The Driver’s Display Method Prepares the Rendering of the Part

protected override DriverResult Display(
  MetaPart part, string displayType, dynamic shapeHelper) {
  var resourceManager = _wca.GetContext().Resolve<IResourceManager>();
  if (!String.IsNullOrWhiteSpace(part.Description)) {
    resourceManager.SetMeta(new MetaEntry {
      Name = "description",
      Content = part.Description
    });
  }
  if (!String.IsNullOrWhiteSpace(part.Keywords)) {
    resourceManager.SetMeta(new MetaEntry {
      Name = "keywords",
      Content = part.Keywords
    });
  }
  return null;
}

This driver is in fact a little atypical, because most drivers result in simple in-place rendering (more on that in a moment), whereas the Meta part needs to render its metatags in the head. The head section of an HTML document is a shared resource, so special precautions are necessary. Orchard provides APIs to access those shared resources, which is what you’re seeing here: I’m going through the resource manager to set the metatags. The resource manager will take care of the rendering of the actual tags.

The method returns null because there’s nothing to render in-place in this specific scenario. Most driver methods will instead return a dynamic object called a shape, which is analogous to a view model in ASP.NET MVC. I’ll come back to shapes in a moment when the time comes to render them into HTML, but for the moment, suffice it to say they’re very flexible objects where you can stick everything that’s going to be relevant to the template that will render it, without having to create a special class, as shown here:

protected override DriverResult Editor(MetaPart part, dynamic shapeHelper) {
  return ContentShape("Parts_Meta_Edit",
    () => shapeHelper.EditorTemplate(
      TemplateName: "Parts/Meta",
      Model: part,
      Prefix: Prefix));
}

The Editor method is responsible for preparing the rendering of the editor UI for the part. It typically returns a special kind of shape that’s appropriate for building composite edition UIs.

The last thing on the driver is the method that will handle posts from the editor:

protected override DriverResult Editor(MetaPart part,
  IUpdateModel updater, dynamic shapeHelper) {
  updater.TryUpdateModel(part, Prefix, null, null);
  return Editor(part, shapeHelper);
}

The code in this method calls TryUpdateModel to automatically update the part with data that was posted back. Once it’s done with this task, it calls in to the first Editor method in order to return the same editor shape it was producing.

Rendering Shapes

By calling in to all the drivers for all the parts, Orchard is able to build a tree of shapes—a large composite and dynamic view model for the whole request. Its next task is to figure out how to resolve each of the shapes into templates that will be able to render them. It does so by looking at the name of each shape (Parts_Meta_Edit in the case of the Editor method) and attempting to map that to files in well-defined places of the system, such as the current theme’s and the module’s Views folders. This is an important extensibility point because it enables you to override the default rendering of anything in the system by just dropping a file with the right name into your local theme.

In the Views\EditorTemplates\Parts folder of my module, I dropped a file called Meta.cshtml (see Figure 5).

Figure 5 The Editor Template for the MetaPart

@using Vandelay.Industries.Models
@model MetaPart
<fieldset>
  <legend>SEO Meta Data</legend>
  <div class="editor-label">
    @Html.LabelFor(model => model.Keywords)
  </div>
  <div class="editor-field">
    @Html.TextBoxFor(model => model.Keywords, new { @class = "large text" })
    @Html.ValidationMessageFor(model => model.Keywords)
  </div>
  <div class="editor-label">
    @Html.LabelFor(model => model.Description)
  </div>
  <div class="editor-field">
    @Html.TextAreaFor(model => model.Description)
    @Html.ValidationMessageFor(model => model.Description)
  </div>
</fieldset>

Everything’s Content

Before I move on to other extensibility topics, I’d like to mention that once you understand the content item type system, you under­stand the most important concept in Orchard. Many important entities of the system are defined as content items. For example, a user is a content item, which enables profile modules to add arbitrary properties to them. We also have widget content items, which can get rendered into zones that a theme defines. This is how the search forms, blog archives, tag clouds and other sidebar UI get created in Orchard. But the most surprising use of content items might be the site itself. Site settings are effectively content items in Orchard, which makes a lot of sense once you understand how multitenancy is managed in Orchard. If you want to add your own site settings, all you have to do is add a part to the Site content type, and you can build an admin edition UI for it following the exact same steps that I outlined earlier. A unified extensible content type system is an extremely rich concept.

Packaging Extensions

I’ve shown how to build your own parts for Orchard, and I’ve alluded to the concepts of modules and themes without defining these terms. In a nutshell, they’re the units of deployment in the system. Extensions are distributed as modules, and the visual look and feel is distributed as themes.

A theme is typically a bunch of images, stylesheets and template overrides, packaged into a directory under the Themes directory. It also has a theme.txt manifest file at its root to define metadata such as the author of the theme.

Similarly, a module is a directory under the Modules directory. It’s also an ASP.NET MVC area, with a few twists. For example, it needs an additional module.txt manifest file that declares some metadata for the module, such as its author, Web site, feature names, dependencies or version number.

Being only one area of a larger site, a module needs to play nice with a few shared resources. For example, the routes that it uses must be defined by a class implementing IRouteProvider. Orchard will build the full route table from what was contributed by all modules. Similarly, modules can contribute to building the admin menu by implementing the INavigationProvider interface.

Interestingly, the code for the modules isn’t usually delivered as compiled binaries (although this is technically possible). This was a conscious decision that we made to encourage module hacking, where you start from a module that you download from the gallery and tweak it to address your specific needs. Being able to tweak the code for anything is one of the strengths of a PHP CMS such as Drupal or WordPress, and we wanted to provide that same kind of flexibility in Orchard. When you download a module, you download source code, and that code gets dynamically compiled. If you make a change in a source file, the change gets picked up and the module is recompiled.

Dependency Injection

So far, I’ve focused on one type of extensibility, the type system, because that represents the majority of Orchard modules, but there are many other extensibility points—far too many, in fact, for me to list here. I still want to add a few things about the general principles that are at work throughout the framework.

One key thing to get right in a highly modular system is loose coupling. In Orchard, almost everything above low-level plumbing is a module. Even modules are managed by a module! If you want these modules to work as independently from one another as possible—if you want one implementation of a feature to be swappable with another—you can’t have hard dependencies.

A key way to reach this goal is to use dependency injection. When you need to use the services from another class, you don’t just instantiate it, as that would establish a hard dependency on that class. Instead, you inject an interface that this class implements, as a constructor parameter (see Figure 6).

igure 6 Injecting Dependencies through Constructor Parameters

private readonly IRepository<ContentTagRecord> _contentTagRepository;
private readonly IContentManager _contentManager;
private readonly ICacheManager _cacheManager;
private readonly ISignals _signals;
public TagCloudService(
  IRepository<ContentTagRecord> contentTagRepository,
  IContentManager contentManager,
  ICacheManager cacheManager,
  ISignals signals)
  _contentTagRepository = contentTagRepository;
  _contentManager = contentManager;
  _cacheManager = cacheManager;
  _signals = signals;
}

This way your dependency is on the interface, not the class, and the implementation can be swapped without having to change your code. The specific implementation of the interface that gets injected is no longer the decision of the consumer of the interface. Control is inverse here, and it’s the framework that makes that decision.

Of course, this isn’t limited to the interfaces that Orchard defines. Any module can provide its own extensibility points by just declaring an interface that derives from IDependency. It really is that simple.

Some Other Extensibility Points

I’ve only scratched the surface of extensibility here. There are many interfaces that can be used in Orchard to extend the system in creative ways. One could even say that Orchard is essentially nothing but an extensibility engine. All pieces in the system are swappable and extensible.

Before I conclude this article, I’ll mention some of the most useful interfaces in the system that you might want to check out. I don’t have nearly enough room here to go into these in depth, but I can give you pointers, and you can go into the code and follow usage of the interfaces. This is a really great way to learn, by the way.

  • IWorkContextAccessor enables your code to access the work context for the current request. The work context, in turn, provides access to the HttpContext, current Layout, site configuration, user, theme and culture. It also provides facilities to get an implementation of an interface, from those places where you can’t do dependency injection or where you need to delay it until after construction.
  • IContentManager provides everything you need to query and manage content items.
  • IRepository<T> gives access to lower-level data access methods, for those times when IContentManager isn’t enough.
  • IShapeTableProvider enables a boatload of on-the-fly shape manipulation scenarios. Basically, you hook up to events about shapes, and from them you can create alternate shapes to be used in certain situations, transform shapes, add members to them, move them around in the layout and so on.
  • IBackgroundTask, IScheduledTask and IScheduled­TaskHandler are the interfaces to use if you need delayed or repeated tasks to be executed in the background.
  • IPermissionsProvider enables your modules to expose their own permissions.

Learn More

Orchard is an extensibility powerhouse, and presenting all it has to offer in this limited space is a challenge. My hope is that I gave you the will to learn more about it and dive deep into it. We have a friendly and lively community on orchard.codeplex.com/discussions that will be happy to guide you and answer your questions. With so much to implement, and so many ideas to explore, here’s a great chance to provide a significant contribution.


Bertrand Le Roy started his professional developer career in 1982 when he published his first video game. He released in 2002 what was probably the first CMS to run on ASP.NET. A year later, he was hired by the Microsoft ASP.NET team and moved to the United States. He has worked on ASP.NET versions 2.0 to 4 and ASP.NET AJAX; contributed to making jQuery an official part of the .NET developer’s tool chest; and represents Microsoft in the OpenAjax Alliance steering committee.

Thanks to the following technical expert for reviewing this article: Sebastien Ros