Here’s another esoteric CMS implementation tip: create “proxy objects” for non-CMS managed resources.
In any CMS project of more than trivial size, you’re going to have content outside your CMS. There’s going to be some page or set of pages somewhere that are provided by some other system that are going to need to co-exist in the Web site along with your CMS-managed content.
Let’s pretend we have a .Net implementation, and there’s a mortgage calculator. It’s a custom-programmed .Net Web form (an .aspx page). What do you do with this?
Well, you can just sit it on the file system and link to it. That would work…okay. But, in a content-managed environment, we want to share some CMS functionality with this page.
- You might want the calculator to use your layout and design (this might be completely independent of the CMS, depending on the system)
- You might want the calculator to use your permissions model
- You might want to configure the calculator based on its relationship to other content (if it appears in the Commercial Mortgage section, brand it like that, otherwise brand it as a Commercial Mortgage calculator)
- You might want to configure navigation items (crumbtrails, especially) based on the content’s “location” in your system (whatever “location” means to your particular system)
- If an editor is writing another page, and wants to link to the calculator, it would be nice if they could select the calculator as another page in the CMS, rather than having to copy-and-paste the URL. Likewise, the URL of the calculator changes, you don’t want to go tracking all those links down.
- You might want a cleaner URL to it – a URL that your CMS manages to keep it all pretty-like
So, the calculator needs to live inside the CMS to some extent. The CMS needs to know that it exists. How do you do that?
This depends highly on the system, but in some form, you need to create a proxy representation of your calculator in the CMS. You need to have some content object that maps to this calculator. The CMS doesn’t necessarily know what the calculator does, but it just needs to have some identifiable piece of content that represents the calculator.
In both .Net systems we worth with (EPiServer and Ektron), you can map content to rendering templates, which are .Net Web forms (.aspx files). For both of these, we would create a “template” that maps to the Web form for this calculator.
I put “template” in quotes, because it’s not really a template in the classic sense that it’s a single thing that renders many content items. Put another way, it’s probably never going to be set as the rendering template for any other content (unless you want your login page coming out looking like a mortgage calculator…).
So, what does the content object look like? In one sense, it doesn’t matter – you’re never going to use any of the content in it. It exists solely as a representational proxy object to serve as a linking target and placeholder for where the mortgage calculator “lives” in the site. So, on the one hand, you can just use a ubiquitous “Text Page” content object, and just let your users know that this particular instance of that content is for the calculator, so nothing they enter will actually appear on the page. On the other hand, you might want to consider creating a specific content type for “Mortgage Calculator” which has no fields in it, just so your users don’t get confused and start wondering why the text they entered isn’t showing up.
(To take this one step further, you might actually use some entered content. Your calculator may have some introductory text or help text that you could let your users manage. In this situation, you’d be adding field or properties to this content type that will only ever be used in one place, but this seems like a completely reasonable usage pattern to me.)
On other systems, this might be harder. In particular, systems that don’t map content objects to simple templates on the file system might be problematic, but you can usually get the theory to work by providing some one-off templating functionality. You can override node rendering in Drupal based on content ID, and you can do the same with an override template in eZ publish.
Now, you may be sitting around thinking, “Well, yeah, of course this is how you do it.” If so, then congratulations, you came to this perspective much faster than most integrators. I’ve seen some heinous things done to get around these problems, when creating a proxy object would have solved all of the problems quite handily.