Sitecore Development in the Real World - Page Template Development Process
I've noticed that new Sitecore developers often struggle at first to get productive. Between learning Sitecore, supporting tools and project specifics, it can be a bit overwhelming if you haven't done it before. If only there was a step by step guide that laid straight the path of what needed to be done.
This post will serve to make it easier by laying out the steps needed to build out page templates. I recommend incorporating Team development for Sitecore and Glass Mapper as an ORM, though all steps could be completed without them. It does assume your following an organization structure similar to what I laid out in my "Sitecore Organizational Strategies" post.
A process to follow
Once you've organized your project and are ready to begin creating page templates, here are the steps:
Create Data Templates
You can't create anything without a data template. Getting to this point, you should have a good idea of what elements are on the page. Before you move forward creating fields, I do recommend ensuring the design of your template is optimal. This amounts to evaluating your templates along 3 considerations:
Field Types - Are you using the right field types?
I think we too often don't give this enough thought. For example, how do you normally choose between multilist, tree list and treelist ex? I love the simplicity of the multi list, but it can be difficult for content authors to know what they're choosing if the titles of items aren't clear. Treelists help by providing the folder structure to give authors context on what is being chosen, but configuring its data source is more complex. Treelist ex are just like treelists but more performant in the content editor as they'll only fetch records on demand.
Data Template Quick Tips
- Don't create separate fields for link text and link url. The general link field has a text property which should be used and works correctly with the field renderer.
- Set Rich Text fields data source to one of the HTML editor profiles.
- Set the data source for File and Image fields to the path to a folder in the media library
- Use the Xpath Query builder developer tool to test out multi list data source queries
- Give developer friendly names to fields and Content Author friendly names to fields by specifying field titles.
- Reorder groups and fields using the field sorting buttons on the builder options tab
Inheritance - Are you repeating yourself across templates?
The DRY principle applies to Sitecore development as well. If you think of each template as mapping to a class, getting the inheritance model correct is an essential task. Page templates should inherit from a base template which should include fields like meta tags and other common fields that span pages. At a page level, you need to really consider whether you can think of areas of your page really should be reusable components that could be applied to other pages. For example, say your template had a section for related content that showed 3 related articles to your content. This is the type of feature that I could imagine applying to multiple templates. To implement it I would create a separate template called "Related Articles" with a single mutlilist field. Then I would make my page template inherit from it. Remember when you take this approach, to set each group's Sortorder (show standard fields, in the appearance group) to ensure it gets positioned below the templates build tab defined fields.
Reuse - Are you making your templates as flexible as they need to be?
You should also consider your template from a content reuse perspective. Are you including things in your template that would be better off being linked to and stored in the data folder instead of the content tree? For example, say your page template had a section to display details about a coupon. You could include all the coupon details (image, link, text as needed) directly in the page template. But that would mean every page would require content authors to fill in all the details on every page they create. Sure you can set defaults in standard values, but it still becomes difficult to maintain if the coupon details change. A better solution might be to create a coupon template and a library for common coupons as a subfolder of the data folder in the content tree and use a drop link field to reference which coupon should be associated with your page. This makes it easier to ensure all pages use the same set of coupons and makes it trivial to update the coupons when they change.
Map Templates to Classes
Once you've created your data templates, the next step is to create Model classes which can be used to access data template values from your renderings and sublayouts. You may be tempted to bypass this step and just leverage the Sitecore API directly, but this in general leads to more difficult to maintain code. While you can roll your own model classes from scratch, here is where ORM frameworks like Glass Mapper really shine. They make it easy to represent your data templates as .Net classes and provide a framework for automatically mapping Sitecore Items to their corresponding classes.
If you use Team Development for Sitecore (TDS) you can even configure code generation templates to automatically generate glass Model classes for your data templates every time you sync with Sitecore. Leveraging this approach makes this step take next to no effort. After you create your data templates, sync your TDS project with Sitecore and your Model classes automatically get updated to include any changes you made in Sitecore.
One final tip on code generation. You still may find it would be useful to add additional properties or methods to Model classes. As generated classes get overwritten every time they are regenerated, the best approach for this is to leverage partial classes in .Net. Simply create another file with the partial class declaration and add field and methods as needed.
Create Renderings or Sublayouts
If you followed the previous two steps you have two things: a data repository in terms of a Sitecore data template to store CMS field values and a data access mechanism to inject their values into strongly typed model classes. At this point you have everything you need to actually create the presentation components to render those values. Here are some guidelines to follow as you go through the process of actually surfacing CMS values:
Sitecore.Context.Item Considered Harmful
Seriously, don't use Sitecore.Context.Item. If you do, your rendering will only work if it is the item being viewed. It won't support personalization or AB testing. The best practice always is to default to the Data Source parameter and only if it is not set, use the Sitecore.Context.Item. If you're not using glass, you should do this by declaring a property of type Sitecore.Data.Items.Item and setting it as early as possible. If you are using glass, this is automatically handled for you if your sublayout or view rendering inherits from the provided base classes.
Avoid Monolithic Views
Just because you could render everything in the data template in a single rendering or sublayout, doesn’t mean you should. Try to apply the single responsibility principle in that a sublayout or rendering should only be responsible for rendering a single thing. It also goes back to your data template design: If you broke out some fields into a separate template and then inherited it, then it would make sense that to render the inherited fields you should just load a separate rendering or sublayout. The rendering or sublayout could deal with just the inherited class and not the page template class and could be reused easily on other pages that inherited that template.
Static vs Dynamic Binding Considerations
Even though you segmented your sublayouts to make it easier to compose, doesn't mean you should connect everything together using Sitecore placeholders. They are a great tool and necessary if you're looking to support personalization or AB Testing. But ask yourself if it's overkill. One of my pet peeves is seeing placeholders used to specify header and footer controls. Doing that means every single template and page will have a presentation detail configuration to connect those controls to the pages. Will they ever really change? Probably not, which means it's a complete waste of effort that would have been better suited for having the header and footer statically bound in the parent layout.
Avoid Code Behind In your Sublayouts
This is probably more of a personal preference than an actual recommendation, but having spent the last several years implementing MVC solutions, I feel quite at home mixing C# with ascx markup. So much so that I avoid writing code in the code behind where possible. Glass maps the current Item to the Model property and makes it available directly in the ascx. I'll even use a foreach loop inline instead of a repeater. The code just feels cleaner. Or don't use sublayouts at all and use view and controller renderings instead,
Be consistent with Naming and Location
Don't let things get messy. There is a place for everything and for everything there is a place. Organize your folders accordingly in the web project and ensure similar organization is applied in the Layouts items you create within Sitecore.
Configure Standard Values
You're never done with your page template until you connect everything together and completely configure it for use. This amounts to creating and configuring the standard values for your data templates. Here are the main areas you want to hit:
- Presentation Details
- The first thing you should do is configure your page templates presentation details on its standard values. Configure all the layouts, sublayouts, data source and other parameters as needed. Once that's setup, create an instance of your page in the content tree and test things out. Unless by some miracle you go things working without needing to debug, but that never happens.
- The basic of the basics. Set the default values and use $name, $date and $time as needed.
- Insert Options
- How do you intend for you template to be created anyway? And think about not only your template but any referenced template. You may need to make sure the subfolder you created for those content items are configured properly as well.
- This is a topic that deserves its own blog pose, but if there is a checklist of things to do before you're done done, configuring validation belongs there. Understand the difference between error types and make sure you understand how much it's going to inconvenience your content authors.
- Don't forget to configure workflow for your templates otherwise you'll need to explain how certain content was published without approval. Trust me, not a mistake you want to make.
- For some strange reason I take great pleasure in looking through all the icons available to find an appropriate image for my template. I haven't probably seen them all hundreds of times but damned if I remember whether that icon was in the business or people category. That probably tells you something about me. Anyway, they are recommended and content authors probably do appreciate them, so you're not done till they're configured.
If you're new to Sitecore development, following the 4 steps outlined in the post will help point you in the right direction toward becoming productive developing page templates.
Did I miss any steps? Let me know what you think in the comments?