Wednesday, 21 December 2011

Umbraco 5 Surface Controller

In a recent post I blogged my first steps in creating plugins for Umbraco 5 - creating a tree and editor using a custom hive provider for a third party database, in order to present and edit information within the Umbraco back office.

I noted how the information could also be made available on the front-end of the site by writing code within the razor view template. Whilst that worked, it wasn't very satisfactory and certainly wasn't the MVC way with too much code and logic in the view.

Since then the project has moved on and details have been made available for working with surface controllers. They can be created both directly within the Umbraco project in VS.Net or as plugins.

Creating a Surface Controller

To create a surface controller for use in a plug-in you create a class within a project with a reference to System.Web.Mvc and Umbraco.CMS.Web, with the following setup:
  • Inherits from SurfaceController
  • Named with a suffix of "SurfaceController"
  • Has a class attribute of Surface with a unique GUID
  • Contains one or more action methods that return either PartialViewResult or ContentResult and are marked with the [ChildActionOnly] attribute
  • The project AssemblyInfo.cs file must contain [assembly: AssemblyContainsPlugins]
Otherwise you use standard MVC concepts such as view models and tightly or loosely bound views, either standalone or embedded. You deploy to your package folder as detailed in the previous post.

Using the Surface Controller

There are a couple of ways to make use of the surface controller once it has been built and deployed to the Umbraco application.

One is the standard MVC way - after all this is just a controller action returning a partial view or content result. So you can use @Html.Action. As it's a plug-in, which is created as it's own area, you need to specify the area the controller and action is found within, as follows:

@Html.Action("ActionName","ControllerName", new {area = "PackageName"})

Unfortunately as of writing, this doesn't seem to work. An error of "No route in the route table matches the supplied values." results. Hopefully will sort this out or determine if it's a bug to be fixed shortly.

In any case the better way is really to create a Child Action Macro. This is done via the Developer section and once created the deployed package, controller and action should be selectable from the list. You can then render the macro, e.g. in a template with:

@Umbraco.RenderMacro("artistList")

Further reading

In addition to Shannon Deminick's introductory post linked to earlier, Sebastiaan Janssen also covers surface controllers in his post on creating an Umbraco 5 package.


Get the code

If you’d like to look further you can download the code here - this has been updated from the previous post with amends to the hive, tree and editor plug-ins to adhere to changes in the Umbraco code base; with an additional project added for the Surface Controller.

2 comments:

  1. Hi there,

    Quick question: How do you get access to the current node from the ChildActionOnly surface controller init function ?

    Thanks,

    Nicolas.

    ReplyDelete