Friday, January 25, 2013

Render Unto c#


When it comes to CMS development (among other things in life) I’m a big fan of granularity and reusability. I believe that in a good solution architecture, both content and code are managed in discreet, granular pieces, which promotes both consistency and reusability.

That’s why it bothers me that so many Sitecore professionals react to the word “rendering” the same way a horse would. To my mind, a good solution has a geometric ratio of layouts to sublayouts, and sublayouts to renderings. Yet I see projects that are extremely sublayout-centric, with content IA and logic governing page layout.

Sitecore’s arsenal of presentation management tools, such as layout details, placeholder settings and rendering parameters, allows us as developers to truly empower our content owners. When implemented well, these features give the content authors what I like to call “controlled control” over their pages.

Unfortunately, we often see solutions where sublayouts are the dominant presentation component. Sublayouts are far less efficient than renderings, both in terms of performance and management. With sublayouts, there are all the ascx files to manage and deploy. And using sublayouts to present content seems to promote having a single component (sublayout) present multiple fields. This can dramatically reduce the solution’s flexibility – or worse, lead to having multiple components that are slight variations on each other, or have cumbersome logic (often wired to “control” fields in the content) to suppress content or change the presentation behavior.

Worse, some solutions rely almost entirely on the content tree to govern layout, such as by having fields in page templates that change the behavior of the layout, and/or by having sets of child items that code “bubbles up” into the page when they are present.

So why are renderings so often left out of solution architecture? I suspect that the problem lies in Sitecore training. Although Sitecore trainers do point out the different ways that renderings can be created, they tend to use XSL as the example technology in class (probably because it’s quicker to demonstrate --the trainer can show changes to an XSL rendering immediately, without compiling). Regrettably, this leaves many with a linkage in their minds between renderings as a Sitecore artifact and XSL as a technology. The oft-maligned rendering can be implemented using multiple technologies, yet many, many developers believe that renderings can only be developed using XSL.

I’m not going to wade into the great XSL debate here. I personally like XSL, but I rarely use it in Sitecore projects, for a number of reasons that I’ll get into that in a separate post. Suffice it to say that many developers, even if they know XSL, want to avoid it if for no other reason than to make their projects sustainable. XSL is a far more rare skill than c#, so it makes sense to ensure that future developers will be able to extend and maintain the project. And since there’s this misconception that “renderings = XSL”, the “baby” of a rendering-based architecture gets thrown out with the “bathwater” of XSL. And that’s a shame.

So let’s set the record straight. Renderings can and should be developed in c#. Actually, John West points out in his book “Professional Sitecore Development,” there are four types of renderings:
  1. XSL renderings
  2. Method renderings
  3. URL renderings
  4. Web Controls
Of these, Web Control renderings – controls that are implemented entirely in code and deployed in assemblies – are the least used yet most useful presentation component available. (In my next post, I’ll delve into the anatomy of a web control rendering.)

As a simple example, consider a page with a “core content” (“body”) area consisting of a title, a main image, and some body text. These three fields are defined in the page’s template. One way of handling this is to create a sublayout that renders these fields to the output (hopefully, at least, using field renderers). But what happens when the author does not want a title on a particular page (this is a simple example, so let’s not quibble over usability or SEO). Sure, the sublayout’s code-behind could suppress the <h1> when the field is empty or null. Or we could have a checkbox in the template to suppress the title.

What if the content author wants something other than a main image, like a flash or a video? What if they need to insert something between the image and the body? And after the body, they might need set of “spots” to point to other content?

So we might resort to having different sublayouts with variations on the content. This can lead to an unmanageable mess, creating confusion as to which sublayout does what. It also leads to redundant code, which makes ongoing maintenance and modification to the site much more challenging.

Another solution would be to put fields in the template to suppress content, or add content, or modify the presentation of content. Or we might create templates for child items that, when present, are bubbled up into the page. This puts management of presentation into the data. Sitecore is so well architected to give us excellent separation of content and presentation, so why fight that and force content to manage presentation?

I much prefer solutions that have very “light” layouts and sublayouts, with lots of renderings bound to placeholders. For the simple example, I would have a separate rendering each for title, main image, and body text, which I would bind to a placeholder in the sublayout for the core content area. Standard values in the item’s template would bind them by default, but the content owner would have the freedom to change the presentation as required. We can use features like thumbnails, rendering parameters, placeholder settings and compatible renderings both to assist them in the layout process, and to enforce brand or visual design requirements.

Most of my layouts and sublayouts are little more than div’s and placeholders. They exist to manage the geometry of the page or of regions of the page, not to present the actual content. Renderings bound to placeholders actually emit the content. Rendering parameter templates allow the editor to influence the source and behavior of the content in the page. Now, control over presentation and layout are managed in the presentation layer, and content is managed in the content layer. The design of the IA can break the content down into more manageable chunks, promoting reusability and avoiding redundancy.

To be fair, there are times when sublayouts are a better choice than renderings. For example, for forms or other situations where postback is required, I refer to use sublayouts (ascx) controls.. Also, in cases where the parts of the page structure are immutable, it is more efficient to statically bind renderings into sublayouts (by including them in the sublayout markup). This is fine for cases like fixed headers and footers, or when the site design requires an element (like a title) to always be present. There are also rare occasions when I allow a folder of child items to bubble up into a page, but even then, I usually use a placeholder-bound rendering to do the bubbling.

A highly granular architecture, which maintains separation of content from presentation, is hugely empowering to both developers and content editors. It promotes reusability of both code and content, shifts much of the responsibility for page assembly from code to configuration, and empowers editors with more control over the layout of their pages.

Thursday, January 17, 2013

Sitecore Solution Custom Configuration

No matter how many times I look at a Sitecore web.config  I inevitably find something I’ve never seen before, or had forgotten about, or never really understood. There’s such an abundance of settings, pipelines, hooks, events --- all kinds of ways to modify and extend the application.

Good solution architecture should follow that same approach. As much as is practical, functional components should expose custom configuration settings, which allow the solution to be tweaked and extended without the need to deploy code. This includes such thing as connection strings, service URLs and communication parameters, pick list options, content locations, task behaviors, UI factors … anything that code or users need to make decisions about how the application should work.
There are four key places where configuration options can be created and managed:
  1. Web.config
  2. Config files in the /App_Config/Include folder
  3. Sitecore content items (typically in a global “MetaData” or “Settings” node)
  4. Static code classes, exposed as enums, constants, properties or methods
There are other, more obscure methods as well. For example, an application initialization event could create application-scoped objects, or even modify the running config. Cool as all that may be, these techniques are only useful in unusual circumstances, and can complicate analysis and troubleshooting.

There is no single right way for configuration management in a solution; rather, any given configuration setting should be managed in the location that makes the most sense for that function.

Using web.config


It is best to avoid using web.config to store custom application settings. Generally speaking, only Sitecore platform specific configuration should be handled here. Settings embedded within web.config can be a nightmare when deploying and reconciling across environments.
All configuration within the Sitecore section of the web config can be extended and modified within .config files (below). Rather than placing settings in web.config, it is better to group related configuration items within .config files, making management, deployment and troubleshooting much easier.

Content owners cannot make changes to web.config, and developers might not be able to easily make changes here is some landscapes.

Web.config should be used only for very stable, solution-wide settings, and that, rarely (.config files can accomplish the same thing and are more manageable). Ideally, only Sitecore platform specific configuration – things that are part of the Sitecore release --- should be managed in web.config.

Using .config files


Sitecore allows any number of .config files to be created in the  /App_Config/Include folder. These config files require a specific XML structure, and are reconciled with web.config when Sitecore initializes, to create a “running config”. This running config represents what the web.config file would look like if all configuration were managed in one file.

Remember that Sitecore reconciles all of the .config files against web.config at application initialization. It is possible for two config files to modify the same configuration item, and it is difficult to predict what order the .config files will be applied.  Sitecore provides a utility at /sitecore/admin/showconfig.aspx to view the running config, which can be very helpful when troubleshooting.

Well organized .config files are a very powerful way to handle configuration, as related configuration item can be aggregated into a single file. Configuration for settings, pipeline processors, events, etc  can be added to the “running config” here, which has the same effect as modifying web.config, but in a more manageable way. Modifying existing web config entries in external .config files allows the solution to have ‘default” behavior defined in web.config while making server, landscape or application specific changes to be made in separate file in separate environments.

This is the ideal place to manage config in the following circumstances:
  1. The configuration modifies or extends an existing setting, event or pipeline in web.config.
  2. This configuration might need to have different values in different environments.
  3. The configuration related to a module or package that needs to be distributable.
  4. Only developers or administrators should be allowed to change the configuration.

Settings in these files should follow the Sitecore setting syntax.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <settings>
            <!—Items to fetch per connection -->
            <setting name="MyDataConsumer.ItemsToFetchPerConnection" value="10" />


Note the naming convention for the name of the setting node. Using the dotted notation (MySettingGroup.MySettingItem) creates a pseudo-namespace that prevents name collisions. Remember that all settings in config files are merged together into a single running config when Sitecore initializes. Every setting needs to have a unique name when the configs are merged.

 It is a good practice to create an associated class that exposes these settings through properties or static methods.

public static int ItemsToFetchPerConnection
{
       get
       {
              return Sitecore.Configuration.Settings.GetIntSetting(
                     MyDataConsumer.ItemsToFetchPerConnection", 0);
       }
}


Not only can .config files extend Sitecore configuration, but they can even change Sitecore configuration by using a patch attribute.  John West’s blog post, “All About web.config Include Files with the Sitecore ASP.NET CMS” discusses config patching, and includes links to more in-depth reading.

In most cases, developers can create and deploy config files, at least within the developer and QA environments. Of course, content authors generally can’t touch config files.

Using content items


It is common practice to have a global settings section of the content tree, usually (not below) the home node. This node is usually called something like “MetaData” or “Settings”.

This is a great place to manage configuration in these circumstances:
  1. The setting is always the same across all landscapes and environments.
  2. Content authors, editors or power users should be able to manage the setting.
  3. The setting relates to interface elements, like the items to be included in a pick list in a data template or rendering parameter template.

Settings stored here are very easy to manage, but there is also some risk. Whenever a setting can affect the stability of the application, there should be tighter control over who can change it. Using security can help protect these settings while allowing them to be managed in the Sitecore UI, but moving them to .config or static classes protects them from UI users altogether.

Rather than creating a template that contains all of the fields needed for a particular “set” of settings, I generally create a several generic “settings” templates, and use them to create items in grouped folders under a “settings” item at the root of the content tree. Some useful templates include: General (text), Link (for references to content items), WebService (with fields for the URL and credential info), and File (for media library file items).

Settings managed in content cannot have different values for CM and CD (unless you use two different items).

The nature of the setting also comes into play. When the setting represents a list of allowable values in a pick list in the content UI, this is really the only place to manage it (because the items in these lists are defined as data sources for the field). The danger is that these values often govern the behavior of code, and unexpected values can cause the code to throw errors. Again, security can help prevent unintended changes to these settings.

Using static classes


Settings in static classes (constants, properties or enums) is the best scenario from a performance perspective, but is also the least manageable method. Changes to these settings can only be accomplished with a code deployment.

This is a good approach for things that should only be changed when code is changing anyway, or only affect code. Static code configuration should also be considered when performance is a concern. For example, there are cases where a known predictable content item must be referenced frequently in code. Storing the GUID of this item in a static class makes the code much more efficient when accessing the item. If the GUID is unlikely to ever change, this is an excellent approach. Note that Sitecore exposes the Sitecore.FieldIDs and Sitecore.ItemIDs classes where the GUIDS of well-known items are stored.

In fact, this is a good way to “bootstrap” settings that are managed in the Sitecore content tree. Create a property in code with the GUID of the folder that contains the settings. This avoids hard-coding the location of the settings, and allows the settings to be accessed even if the location of the settings folder changes.

Settings location guidelines


 

web.config
Config file
Content item
Static class
Types (what does this setting affect?)
Part of the Sitecore platform
Related to code
Related to infrastructure
Related to content
Roles (who manages this setting?)
Developer
System administrator
Site architect
Business owner
Environments (CM vs CD)
Same on all environments
Different in each environment
Volatility (how often does it change?)
Frequently
Infrequently
Risk (impact of a mistake)
Changes affect entire application
Changes affect part of the application
Changes affect availability of data
Changes are cosmetic or content only




More reading...