.NET, Architecture, publishing, Sitecore

Drawing the customization line

Sitecore is an extremely flexible system; in fact most of Sitecore is built with the extensibility and customization functionalities which is provided. This includes pipelines, events, commands, SheerUI, providers and more. All in all: there is not much which cannot be achieved in Sitecore and only the imagination of you and your client sets the limits of customizations – and believe me, in my work of helping out clients and Sitecore partners all over the world, I’ve seen Sitecore completely twisted in many ways. I’ve seen Sitecore’s entire layout engine replaced with an item based layout definition, with subitems representing placeholders and subitems representing presentation elements. I’ve seen publishing and item saved pipelines so crammed full of custom functionality that performance was non-existent and I’ve seen XSLT’s with one line of code: a call to an extension function which would return an entire HTML structure as a string.

So where do we draw the line in the holy name of bending functionality and giving the customer “what they want”? Remember:

  • Convincing the client to choose standard functionality is also an option.
  • Each change of standard Sitecore functionality is potentially expensive – for you and for the client.
  • If possible, do not replace Sitecore functionality, extend it.
  • Think about what you put into Sitecore: Content and functionality can be accessed through .NET code and does not necessarily need to be added to the Sitecore DB’s or in a pipeline.
  • Keep track of your customizations – source control it and document it.
  • Remember that your customizations will have to upgrade with Sitecore.
  • Stay true to yourself: If it feels wrong, don’t do it.

In short, just because you can does not mean that you should:-)

Standard
.NET, Architecture, Sitecore, Uncategorized

5 worst code smells in Sitecore

Last year I wrote a blog post on doing code reviews on Sitecore. While dealing with conceptual issues it doesn’t really say what to look for in code, when evaluating the quality or to evaluate if any wrong decisions have been made when developing the solution.  Therefore I wanted to wright a post about the top 5 code smells I look for, when I am trying to evaluate or trouble shoot a Sitecore solution. These code smells often indicate that the developers have gone down the wrong road and there is something fundamentally wrong in the architecture.

So here goes:

1) Using the descendant axes in xpath expressions:

This one I especially look for, when I am looking at a site which doesn’t perform. It may be used in some cases, but very often I find that a developer has used this to generate relations between content and thereby iterating over the complete content tree. This works fine in development where there are a few hundred content items. However in production where thousands of items are created this simply breaks the performance of the site – especially after publishing which clears the HTML cache.

The descendants can be accessed in multiple ways. In XSLT it normally looks like this:
<xsl:for-each select=”$sc_currentitem/descendant-or-self::item”>
</xsl:for-each>Or like this:
<xsl:for-each select=”$sc_currentitem//item”>
</xsl:for-each>

In C# using the Sitecore API it is most often accessed like this:

item.Axes.GetDescendants()

2) XSLT Import:

This is related to a point in the post about code reviews on Sitecore, where I argue that overcomplicated functionality and logic in XSLTs, is a problem. If you need to do an import of another XSLT in your rendering, you probably do it to call a method or in another way try and reuse functionality. If you want to do this, don’t use XSLTs! XSLTs should only – if you really want to use them at all – hold simple presentations.
XSLTs can be imported like this:

<xsl:import href=”YourOtherXslt.xslt” />

3) Explicitly accessing the master database

Although this can be needed in some cases and especially in scheduled tasks or other backend functionality, most often it is because the developer haven’t thought the issue through or if they have made a wrong decision of how data entered by the user should be stored.
The master database is most often used like this in c#

Database masterDatabase = Database.GetDatabase(“master”);

If you see a call like this, your solution is most likely not ready for staging, where there is no access to the master database from the content delivery server. You should generally use something like this:

Database database = Sitecore.Context.Database ?? Sitecore.Context.ContentDatabase;

This means you operate on the context database and on the content delivery databases this will be the web database and in preview you will use the master database, which is probably what you want.
If you need to write something to the master database, you first need to decide if this is a good idea at all. If you write to the master database from your frontend, you make yourself vulnerable for malicious attack, as people from the outside can enter data into the master database. Normally we handle user entered data in a custom database or parse all user created content to ensure that the master database won’t be flooded with data.
If you really need to access the master database, you should create a service that handles access to the master database, so that your solution is ready for staged environments.

4) XSLT extension over 100 lines of code:

This point is closely related to point number 2, but I really see a lot of issues with XSLTs which have been used wrong and this creates a lot of issues later on in the project lifecycle. If you have an XSLT extension with over a hundred lines of code, chances are, that the developer made a wrong decision when creating the XSLT; instead he/she should have created a sublayout.
XSLT extensions are functional programming and you should use an object oriented approach, so my advice is not to use XSLTs at all, unless you are doing something really simple. Otherwise your solution will become harder and harder to maintain, as utility methods like the XSLT extensions are very hard to understand and couplings in the renderings themself are difficult to map.
You can find all registered XSLT extensions in the web.config under xslExtension and it looks something like this:

<xslExtensions>
  <extension mode=”on” type=”MyNamespace.XslHelper, MyAssembly” namespace=”http://www.example.net/helper” singleInstance=”true”/>

5) Clearing of cache

This may seem obvious to some, but I have seen surprisingly many methods, which cleared the entire Sitecore cache including the data and item cache. If you see this in your code and it is needed, chances are, that you have an architectural issue in your solution. It should most rarely be needed to clear the cache, unless it is after a publish and Sitecore handles this automatically. I have heard many reasons for clearing the cache including an issue, where the developer argued that it was necessary, as he wrote directly to the Sitecore database with a SQL statement, and then Sitecores cache wasn’t updated.
If you experience something like this, the issue is of cause not the cache, but that you don’t use the Sitecore API to read and write data from the database.
The caching is most often cleared like this:

CacheManager.ClearAllCaches();

This is just some of the things I have seen many times, but I know there are many other bad code smells when developing Sitecore solution. Do you have any other code smells to share?

Standard
Architecture, Sitecore

Dedicated image server and Sitecore

A lot of sites which have a large amount of visitors use a dedicated image server.  There are several reasons for this, but mostly it is because that most browsers only allow a few simultaneous connections to the same domain, which stalls the download of a page that has more than two resources. For instance imagine you have a page consisting of multiple images, stylesheets and javascript files. As the clients only allows a few simultaneous downloads, the browser won’t download all the resources at the same time, but wait for each download to complete and first then start the next download.

The reason of this behavior is that the HTTP standard says that only two simultaneous connections between a client and a server should be allowed. This was specified to save servers from heavy IO load, when files where requested. Browsers like IE7 and Firefox 2 lives up to this standard and only allow 2 connections, while new browsers like IE8 and Firefox 3 allows 6 connections.
To ensure that the HTML can be fully loaded independently and without waiting for other downloads and to remove the load from the primary web server; a dedicated image server can be used. This server holds all files and uses a different domain (for instance images.mydomain.com). All files used on the page can then be fully referenced and thereby be downloaded from a different domain. Eg <img src=”http://images.mydomain.com/image1.jpg alt=”image1”/>. As the images are now on a different domain, these can be requested independently of the server providing the HTML and more simultaneous connections can be opened.

But how is this possible in Sitecore where the media library controls all the images?

One of the easiest ways is to have another publishing target for the media. In that way you will have two frontend servers: One serving the normal requests and one serving all media items. You can easily set up another publishing target and for instance use the staging module to clear the cache. Read more on SDN if you want to know how to set it up.

The remaining problem is: How do we ensure that all media items gets prefixed with another domain? Unfortunately there isn’t a simple setting for this (it will probably come in a future a release of Sitecore – I hope :)). However there is a simple solution to the problem as links are expanded by the LinkProvider, which can be overridden. More precisely the links are expanded in the LinkProvider.ExpandDynamicLink method, so we need to override this replacing the media path:

namespace TestApplication
{
  public class CustomLinkProvider : LinkProvider
  {
    public const string MEDIA_PATH = “~/media/”;

    public override string ExpandDynamicLinks(string text, bool resolveSites)
    {
      string baseExpands = base.ExpandDynamicLinks(text, resolveSites);
      return baseExpands.Replace(MEDIA_PATH, “http://images.pentia.dk/” + MEDIA_PATH);
    }
  }
}

Here I override the ExpandDynamicLinks in the inherited class CustomLinkProvider. I replace all media paths (identified by the prefix ~/media/) and replace it with the full path to the image server. The remaining thing to do is to replace the LinkProvider type in the web.config:

<linkManager defaultProvider=”sitecore”>
  <providers>
    <clear />
    <add name=”sitecore” type=”TestApplication.CustomLinkProvider, TestApplication” addAspxExtension=”true” alwaysIncludeServerUrl=”false” encodeNames=”true” languageEmbedding=”asNeeded” languageLocation=”filePath” shortenUrls=”true” useDisplayName=”false” />
  </providers>
</linkManager>

Here I just point the LinkProvider type to my own implementation.

Now that this is set up, all requests for media items will be handled by the image server. This does not just allow faster load times for the client, but will put less pressure on the main server. Further you can tune the media server to handling media items by increasing the media cache, setting the prefetch cache etc.

Enjoy your new Sitecore media server 🙂

Standard
Architecture, Sitecore

Agile Sitecore design

It been a while since my last blog post – my second child Annika was born March 16th and since then I’ve been forced to realize that two children takes up a lot of blog-writing time.

A year ago I wrote a post titled Type before function, which pointed out the very type-centric design of Sitecore. Since then, we have in Pentia tried to develop a design practice which focuses more on isolating logically grouped functionality in our design and thinking outside the type-centric nature of Sitecore. For this purpose, we have “invented” the term component in our design. The purpose of components is to separate the functionality from the type, allowing the developer to focus on one purpose and its interfaces.

The practise has been quite successful – our large-scale solutions have become increasingly easy to maintain and extend. As a side effect of the process, we now have a high degree of reuse – not just knowledge, but actual code – between even seemingly un-similar projects. Not very surprisingly, it turns out that developers are more inclined to reuse code, which is easily overviewed. The design practice is so successful, that we have passed it on to external projects, through our Professional Services.

Here are a few tips on getting you started:

Consistent placement and naming

Not all items belonging to a component can be placed together. Naming and placement makes it easier to identify component items – in a type-centric system.

Keep your files together – we never use the standard Sitecore folders, e.g. /xsl and /layouts. All files in a component are placed below a folder named /Components/[ComponentName]. This makes it easy to identify which files belong together without e.g. garbling the filename with unnecessary prefixes. And if you think about it, it’s not hard to identify a file as an XSLT – so why put it in the/xsl folder? Keeping component items together also goes for templates, renderings and layouts in Sitecore. For the purpose of Sitecore best practice, we still place templates under /sitecore/templates (although I suppose it’s not strictly necessary), and layout items under /sitecore/layouts. But we always use subfolders which are named consistently, e.g. /sitecore/templates/Components/[ComponentName].

Component projects

Each component has a separate Visual Studio project, and therefore a separate assembly. Aside from grouping files even further, this also helps to identify dependencies between components. Use build events on the project to move files from component folders to website folders if needed.

Interface templates

Think of templates in Sitecore as interfaces – never basetypes – which provide your pagetypes or data items with certain functionality. Always refer to these interfaces in the code within the components.

Example: The component Navigation (menu, breadcrumb and sitemap) defines the template Navigable with the fields Menu Title and Show In Menu. This template is assigned to the pagetypes which can be shown in the menu. The renderings Menu.xslt and Breadcrumb.xslt only references the Navigable template by using the XslHelper.IsItemOfType() method (or your own more optimized version).

Common components

There are a number of components which is always in a project, and which brings the functionality of the other components together.

The Design component contains all the graphic design for the project. Do not be tempted to place stylesheets and graphics within each component – the design for a single component is always related to other components, and therefore you will be forced to create unnecessary dependencies.

The PageTypes component brings together the interface templates and renderings and sublayouts in the other components on the actual page type template. Only page type templates are instantiated in the content tree. If you define the page type template News in the News component and not in the PageTypes component, you will be forced to create dependencies to other components e.g. Navigation.

Dependencies and Inversion of control

Keep your dependencies amongst components as few and as obvious as possible. It should not be necessary for a developer to know more than the component he is working on – too many dependencies makes the components too complex and less flexible. The common components is one way to reduce dependencies, another is the use of the inversion of control pattern and possibly an IoC container. Suppose the News component uses the Indexing component for providing data quickly. This could naturally be done by calling the indexing component directly through the News code, thereby creating a dependency. Alternately the News component could provide an appropriate interface which defines its necessary functionality. This interface could be implemented by the Indexing component and instantiated though Reflection or an IoC container like Unity or Spring, thereby inverting the dependency and making the News component more lean.

Standard
Architecture, Sitecore

Command templates – the forgotten feature of Sitecore 6?

I don’t know about you, but I actually haven’t been giving command templates any attention since they were introduced in Sitecore 6. This is really a shame, as it is pretty powerful and can help editors a lot.

For instance take the often used structure for news, where you have a news folder. To avoid too many items in a flat structure you have folders for the current year and the current month. This could back in the old days be used by letting the editors them self create the folders they needed or you could have implemented a lot of event handlers or similar. Now you can just use a command template and let the command create the folders from the current DateTime.

To create command templates follow the guide in the data definition cookbook . Then implement the command to create the folders like this:

public class MyCustomCommand : Command
{
  public override void Execute(CommandContext context)
  {
  if (context.Items.Length == 1)
  {
  Item item = context.Items[0];
  NameValueCollection parameters = new NameValueCollection();
  parameters["id"] = item.ID.ToString();
  parameters["language"] = item.Language.ToString();
  parameters["database"] = item.Database.Name;
  Sitecore.Context.ClientPage.Start(this, "Run", parameters);
  }
}


protected void Run(Sitecore.Web.UI.Sheer.ClientPipelineArgs args)
{
  if (!args.IsPostBack)
  {
    //Means we are in the initial step, we want to ask for the name of the news
    Sitecore.Context.ClientPage.ClientResponse.Input("Enter the name of the news item:", Sitecore.Globalization.Translate.Text("New NewsItem"), Sitecore.Configuration.Settings.ItemNameValidation, "'$Input' is not a valid name.", 100);
    args.WaitForPostBack();
  }
  else
  {
    //Now we got a postback, which means we got a response
    if (!String.IsNullOrEmpty(args.Result) && args.Result != "undefined")
    {
      Database db = Sitecore.Configuration.Factory.GetDatabase(args.Parameters["database"]);
      Item parent = db.GetItem(args.Parameters["id"], Language.Parse(args.Parameters["language"]));
      //Create the folder structure if it doesn't exist
      string year = DateTime.Now.Year.ToString();
      string month = DateTime.Now.Month.ToString();
      TemplateItem folderTemplate = db.Templates[Sitecore.TemplateIDs.Folder];
      Item yearFolder = parent.Children[year];
      if (yearFolder == null)
        yearFolder = parent.Add(year, folderTemplate);
      Item monthFolder = yearFolder.Children[month];
      if (monthFolder == null)
        monthFolder = yearFolder.Add(month, folderTemplate);
      //Create the news Item
      TemplateItem template = Sitecore.Context.ContentDatabase.Templates[new ID("{B2612CF6-16D6-426D-9E74-EE3A4E3989B2}")];
      Item item = monthFolder.Add(args.Result, template);
      //Load the Item in the content editor
      Sitecore.Context.ClientPage.SendMessage(this, "item:load(id=" + item.ID.ToString() + ")");
    }
  }
 }
}

There you go – auto creation of folders. It’s that simple. I can think of really many usages of this – also more complex situations. Too bad the sheer UI documentation is so limited, as it makes it difficult to implement complex wizards etc.

Standard
Architecture, Sitecore

Content and presentation separated – Does it make sense?

Often I hear that Sitecore separates content and presentation completely – In fact it seems that it is a key selling point. Lately I have also seen other CMS vendors promote the same idea. But I must admit that I don’t understand why it seems to be so important. Is it because of reuse of content? Is it because you want to be able to present the same content on different devices such as iPhones, PDAs etc.?

But…  Does it make any sense?

·         Most of the clients we have been working with prefer to use the content editor and not webedit. To ensure that content editing is user friendly and intuitive, most of the time we construct solutions, where the content structure and hierarchy is the same as how it is presented on the frontend. This enables the editor to find and edit content in the same manner they find the information on the frontend.

In this matter it makes more sense to bind content and presentation structure together.

·         You seldom want to use the same content structure on different devices. When constructing sites for mobile devices, you probably want to have a simple flat hierarchy, which is different from your normal site.

Therefore it makes more sense to me, to have two different structures optimized for the presentation on the different devices.

·         Often the editors want to be able to edit the presentation. If they create a list in a rich text, they probably want to be able to decide how this list is presented – hence you bind content to presentation. This is allowed in the rich text field. By nature WYSIWYG editors is bound to presentation. What you create is what is presented. Should you avoid rich text fields completely?

·         If content from rich text fields should be independent from what devices it is presented on, it requires editors to consider this, when they create their content. For instance a table with a lot of data expanding over 320 pixels wouldn’t look good on an iPhone, so the editor has to be more aware of the technical limitations of the devices or limited to use memo fields.

All in all I find that you on some level always want to bind the content to the presentation, allowing more flexible content and giving editors a more intuitive way of creating content.

I agree that you can construct a Sitecore solution that separates content from presentation completely, by developing a solution consisting of a big repository of memo fields, which can be pulled on to a presentation item… But this wouldn’t be very user friendly.

So why is it so important to separate content from presentation and does it make any sense?

Standard