Uncategorized

Code reviews on Sitecore

Thomas Eldblom and I are reviewing most of the projects, we do in Pentia. The most of the things we comment on concerns C#, architecture, HTML, XSL or other general technologies, but some issues are related to the use of Sitecore. In this post I want to share the most common, most severe or most irritating issues/pitfalls I often stumble upon or look for, when doing a code review. I am glad to say, that I almost never stumble upon the most basic things, such as layouts specified directly on items, masters set on masters (SC5) etc.

·         Use of Sitecore.Context in logic

When having actual classes or general logic, I sometimes find a reference to the Sitecore.Context. Often it is a reference to Sitecore.Context.Item or Sitecore.Context.Database. This is rarely a good idea. The logic should be independent of the context it runs in. Instead you should pass in the objects you need as parameters. If you don’t do this, you’ll bind your logic to a certain context, making it unusable, if you want to use it without a context. Further logic that uses the context isn’t very testable.

 

·         Iterating over to many items

I don’t find this sort of issue very often, but it is pretty severe. The scenario is often that you have a list of all latest documents or a similar relational operation. You implement a simple XSL using “//item”. This works fine in development, but when the client starts importing or creating several thousand documents, the list doesn’t perform and brings the whole site down.

 

·         Too much logic in an XSL

Often you start out with a page type, which looks like a simple rendering. Therefore you start out creating an XSL. As you dig into the specs, you find out, that you need a lot of logic. You end up with a large amount of XSL extensions and a complex rendering. The result is a way to complex XSL, which is practically unreadable and impossible to maintain. When you have a lot of logic use a sublayout.

 

·         Reference to specific databases

Sometimes I find a reference to a specific database. For instance something like Sitecore.Configuration.Factory.GetDatabase(‘web’). Allthough it may be needed in some situations, it often gives some unintended sideeffects. Most of the time you want to operate on the context database, so you use the correct database specified in the site section in the web.config. A direct reference to the web database might cause preview functionality not to work as intended, and a direct reference to the master database might not work if you are using a staged environment.

 

·         Null reference

As Sitecore is so type weak and everything is an item, you don’t know what fields/properties the item has. No matter how experienced the developer is, I often find the use of a field of some sort, where it hasn’t been validated whether the field is null or not, resulting in a null reference exception if the input is incorrect.

 

·         Overriding standard Sitecore functionality

Sometimes a developer isn’t satisfied with the way Sitecore implements something – for instance the indexing, the site resolver, the domain etc. As Sitecore allows you to override almost everything, the developer thinks… Hey, I’ll just override the domain doing my own implementation. Although this might be necessary, it should be considered carefully. I have too many times stumbled into a problem with a custom implementation of standard functionality, either because it may be more complex than first assumed, the next developer on the project isn’t aware of it or last but not least an upgrade of Sitecore changes the requirements to the functionality.

 

I am hoping you want to share some of your experiences as well – telling what Sitecore pitfalls you often stumble upon or find very irritating.

Standard
Uncategorized

Introducing the Lucene Index Viewer

I have earlier complained about Sitecore 6 Lucene implementation hard-coding compression, making it impossible to view the index in Luke. Further I have often wanted to view an index in production, where a Luke installation wasn’t allowed.

Therefore I decided to implement an index viewer and I am proud to announce, that it is now released. It has been added to the Sitecore Shared Source modules. Go to http://trac.sitecore.net/IndexViewer to download the package or the source. To see some screenshots go to http://trac.sitecore.net/IndexViewer/wiki/Documentation.

In the IndexViewer it is possible to: See information about an index (Last modified, number of ducuments etc.), browse the documents in an index and search through the index using different Lucene Query types.

Let me know if you have any comments, feature request or similar. Enjoy!

Standard
Uncategorized

Microsoft TechEd EMEA 2008

Jens and I from the Pentia Core team are going to attend the Microsoft TechEd 2008 conference in Barcelona, 10-14 November. Over 200 sessions of tech talk over 5 days – who could wish for more:-)
(Plus we’ve also managed to get tickets for FC Barcelona vs. Valladolid at Camp Nou – I’m soo excited!)

Are others of you in the Sitecore community also attending the conference? Maybe we should get together for a talk about how the topics could be applied in our daily work with Sitecore. Write me a comment if you are interested.

Standard
Sitecore, Uncategorized, XSL

XslExtensions be gone – part 2

As described in part one of my post, we at Pentia have for some time had a bad feeling about the XSLT extensions concept introduced by Microsoft in the XsltTransform class and implemented further in Sitecore. We feel that XSLT’s belong in the UI tier (in a traditional n-tier architecture) and XSLT extensions has a tendency to introduce a mix of UI and business layer functionality and limited by the type restrictions in XSLT.

All developers (in their right minds) knows that asp.net codebehind files should contain UI layer functionality, not business logic, and that one c# codebehind file is bound to one asp.net file. What we want to achieve, is to have the same link between codebehind files in ASP.NET and XSLTs, therefore in our internal projects at Pentia, we have introduced the concept of XSLT codehind files.

So how does that work, you might ask?

Basically, we’ve developed a module which is included in all our projects (through our build environment), which automatically links XSLT extension classes to XSLT files through a common namespace. The module consists of an overridden Sitecore.Web.UI.WebControls.XslFile class, which overrides the AddExtensionObjects function:

  public class XslCodebehindFile : Sitecore.Web.UI.WebControls.XslFile
  {
    protected override void AddExtensionObjects(XsltArgumentList list, Item item)
    {
      //...
    }
  }

The AddExtensionObjects function dynamically determines which .NET class is the codebehind file for the current XSLT and adds it to the XsltArgumentList with a specific namespace (in our case http://www.pentia.net/codebehind). The class to add is determined via a custom .NET Attribute class which decorates the codebehind class (see the example below).

Furthermore the module implements an overridden Sitecore.Web.UI.XslControlRenderingType class:

  public class XslCodebehindControlRenderingType : XslControlRenderingType
  {
    public override Control GetControl(NameValueCollection parameters, bool assert)
    {
      // Returns the XslCodebehindFile class instead of the XslFile class
      // ...
    }
  }

This class is used by the Sitecore renderings engine to return the .NET class which implements a Sitecore rendering type. The class is hooked into Sitecore through the web.config (done automatically though our build environment):

<configuration>
  <!-- ... -->
  <sitecore>
    <!-- ... -->
    <renderingControls>
      <!-- ... -->
      <control template="xsl rendering"
        type="PT.XslCodebehind.XslCodebehindControlRenderingType, PT.XslCodebehind"
        propertyMap="Path=path" />
        <!-- ... -->

So how does the developer actually use it?

The developer starts by writing his XSLT file, e.g. /xsl/newslist.xslt. Most often it turns out that XSLT files does not even require codebehind or that the required functionality is implemented in the Sitecore XSLT extensions, but in the rare cases where advanced functionality is required (e.g. paging in the list of news) the developer creates a c# class file named newslist.xslt.cs (to keep the naming conventions defined by Microsoft). The class in the file is decorated with the XslCodebehind attribute which points to the fully qualified XSLT file:

  [XslCodebehind("/xsl/NewsArchive.xslt")]
  public class NewsArchive
  {
    //All functions in this class can be called in NewsArchive.xslt
    public Int32 GetCurrentPageIndex(XPathNodeIterator archive)
    {
      //...
    }
    public Int32 GetPreviousPageIndex(XPathNodeIterator archive)
    {
      //...
    }
    public Int32 GetNextPageIndex(XPathNodeIterator archive)
    {
      //...
    }
    }

This class is then automatically linked into the XSLT file at runtime and can be called though the http://www.pentia.net/codebehind namespace:

  <?xml version="1.0" encoding="UTF-8"?>
  <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:sc="http://www.sitecore.net/sc"
    xmlns:codebehind="http://www.pentia.net/codebehind"
    exclude-result-prefixes="sc codebehind">
    <!-- ... -->
    <xsl:template match="*" mode="main">
      <!-- ... -->
      <a href="?p={codebehind:GetNextPageIndex(.)}">
        <!-- ... -->
      </a>
      <!-- ... -->
    </xsl:template>
  </xsl:stylesheet>

Easy-peasy – no meddling about in web.config and a much tighter coupling between XSLT files and their .NET functions.

The XSLT codebehind functionality took me about half a day to code and include into all our projects. It has made it practically easier for developers to link functionality to XSLT files and conceptually easier to understand the placement of the XSLT functionality in the UI layer.

Standard
Uncategorized

No More Masters

Sitecore 6 has retired the masters term – a fine decision which hopefully will remove a lot of the obvious mistakes made when designing Sitecore 4 and 5 solutions, e.g. like assigning masters and layout directly to a content item.

The concept has been substituted by the possibility to assign templates directly templates (i.e. “Which templates can be created under this page type” instead of “Which prefilled items can be created under this page type”). The prefilled data on the master (which was copied to the items) can still be applied using Standard Values (which was there in Sitecore 5 as well). Standard Values are made even more powerful than in Sitecore 5 since it now derived through all inheritance levels, i.e. if DerivedItem is created from DerivedTemplate which derives from BaseTemplate, standard values set on BaseTemplate also applies to DerivedItem. This means that you can e.g. set a layout on BaseTemplate and thus all the derived templates will now have a standard layout which you apply changes to.

With this and other features, Sitecore 6 has made some nice changes to force developers to design better Sitecore solutions by applying content reuse and thus makes the solution easier maintainability. But there are some issues: Sitecore 6 no longer indicates whether a value is a standard value or actually applied to the item (see below). In my opinion this is a major flaw. It is vital for developers and administrators to be able to instantly determine whether a value should be changed directly on the item or on the template, thereby allowing them to think about whether the change should be universal or local change. An ugly dent in the before mentioned “changes to force developers to design better Sitecore solutions”. Thankfully the designer of the DBBrowser (hail!) has not been so rash – but this is still not a tool I would like my users (even the super-ones) to see. Hopefully this will return in an upcoming hotfix.

Standard
Uncategorized

Type before function?

I’ve recently been made aware of how type-centric Sitecore is in its architecture and best practices.

Consider the main sections in Sitecore: Content, Templates, Layouts, and even the folder structure /xsl, /layouts. Sitecore seems inherently to point the architect towards categorizing his solution after which types of elements it consists of, i.e. which templates do my website consist of, how many layouts do I have, which XSL’s do I have to write etc. instead of looking at the conceptual structure of the website, i.e. which functionality do I have, e.g. newsletter, document, navigation etc. Trying to piece together all the parts which make one function on the website involves browsing through a lot of folders in Sitecore and looking into a lot of code, whereof many of the references are very loose e.g. template names in XSLT files, or assembly references in the web.config (or even worse: assembly references in Sitecore). All in all it is not an architecture which is very helpful for reuse and overview.

I vision Sitecore in a future version working in a more functionality-centric way, for example imagine the Sitecore content tree:

  • /sitecore
    • Content (This is where the editors edit the site – not much different here)
    • Components (This is where we – the developers – roam)
      • Component (each functionality has its own section)
        • Templates (this defines the templates for this component)
        • Presentation (This defines all the presentation elements for this component, layouts, renderings etc.)
        • Settings (General settings, dictionary texts etc. needed by the component)

…and that’s it. No more browsing the entire tree looking for the settings for the Mailing list module. No more: “I wonder if this layout is used by any of my 367 templates”. No more: “Was that document.xsl or document.ascx”. Just imagine the ease in making of package for porting functionality to a new website.

Just my two cents…

Standard
Uncategorized

Assigning layouts

My first idea was to write a post about the top 5 mistakes when developing in Sitecore, but then I decided to go for the one potential danger I consider grave enough for its own post: Assigning layouts to items.

A layout is basically a simple field (__layout) on an item which describes how the item is rendered by the rendering engine, and as such can be assigned on the item and on the Standard values (http://sdn5.sitecore.net/End%20User/Template%20Manager/Standard%20Values.aspx).

On pre-5.3 version of Sitecore standard values was not available, so in order to have layout reuse, layouts was assigned to templates. This functionality has been preserved in Sitecore 5.3 for backward compatibility. I’ve actually just recently been made aware of Sitecore’s recommendation on putting layout settings on standard values instead of on the template. Architecturally this is absolutely the right way to go – the template way was a hardcoded layout engine functionality to enable reuse.

Well to get back to the point: Do not – ever – assign layouts directly to items.

Assigning layouts to template standard values gives you the reuse you want and need, in order to maintain an architecturally sound Sitecore installation. Consider a situation where you have a layout (header, footer, menu, spots, content) defined on your document template, and you want to introduce a breadcrumb on your site. If the architecture is correct, this can be accomplished merely by changing the document template and all documents on your website will be updated.

Then again consider a situation where 10 specific documents need a slightly different layout. Well, the simplest way would be to just set the layout directly on these documents. WRONG! Settings layouts on directly on items primarily set aside all reuse, but more importantly makes you completely loose the overview of your solution. If you in this case wish to introduce a breadcrumb you will have to manually find (on your 10.000 page website) the items which has a specific layout and correct these – which often leads you to the painstaking realization that you have to write a script.

Therefore what you should consider is introducing data templates and layout templates and use template inheritance. In projects in Pentia, we define fields and functionality in one template then derive to another template and set the layout on this. Consider a template DocumentData which holds the fields Title and Text, and another, Document, which derives from DocumentData and define the layout (and other standard values). If I need specific layouts on certain items, I derive another layout template from DocumentData, e.g. WideDocument, which then defines the specific layout. This means that all layout settings are always in the Templates section of Sitecore – easy to find and reusable.

Standard