NCIM Sitecore Team

Just another WordPress.com site

First Sitecore User Group NL Meeting

leave a comment »

After many weeks of planning and preparation it finally happened… On the 31st of October the first Dutch Sitecore User Group meeting was held at the NCIM Groep in Leidschendam!

19 Sitecore enthusiasts from several companies across the Netherlands attended this event including two Sitecore representatives; Rudy van Herpt and Alex de Groot.

I started the evening by  introducing the user group, its goals and the members of the steering committee.

The slides (in Dutch) are available for download in pdf format here (highly recommended for all who are interested in the user group).

We discussed possible topics for upcoming SUGNL events and the format to present them, taking into account our broad target audience (dev/marketer/content manager). The format will be a mix of client cases, technical presentations and discussions on best practices and tips & tricks.

Although most of the attendees have a background in software development or marketing many stressed the importance of end-users attending the user group meetings as well. Annemarie, Jeroen and Arend briefly explained how they typically tackle Sitecore related challenges at Suneco and that it usually requires a joint effort between all competences.

Next Robbert showed some screenshots of the SUGNL prototype website. Robbert made an initial design which was further refined  by Estate (many thanks for that!). In the next several weeks Robbert will devote his spare time building this website.

Then it was up to me to give short demo on Sitecore Item Buckets. This is an excellent Shared Source Module available for free on Sitecore Marketplace. I made a small example how Item Buckets could be used for managing a large set of movie and actor items in Sitecore (and yes I am a Bond fan!).

The demo initiated some great discussions between several people who are already using this in production environments. Thanks to Jeroen (Suneco) and Ruud (Partech) for sharing their experiences and insights.

After seeing a screen full of C# code it was time for some people to get a drink. So we ended the evening with drinks, snacks and great conversations.

To conclude

The first Sitecore User Group NL  meeting was a big success! Many thanks to all the attendees. I hope to see all of you again at next SUGNL events.

To register for upcoming events please visit http://sugnl.eventbrite.nl.

The next event, on December 12, will be an informal drinks session at café Zussen in Utrecht. The next meeting with presentations will be held on January 23 at eFocus (exact program will be disclosed next month).

Keep in touch

If you want to stay informed please join the SUGNL group on LinkedIn or follow our Twitter account: @SUG_NL.

See you at the next SUGNL event!

Marc

Advertisements

Written by marcduiker

November 21, 2012 at 9:34 pm

Posted in Sitecore

Tagged with , ,

Sitecore Symposium Europe (a photo report)

with 3 comments

Marc DuikerOn the 5th and 6th of September I attended the Sitecore Symposium in Amsterdam. Here are some snapshots I took during this great event.

(Apologies for low quality photos due the my old smartphone, usually I produce prettier pictures. )

Registration & Welcome Reception

Since I needed to be in Amsterdam on the evening of the September 4th anyway I briefly went to the Okura Hotel to register.

My badge!

I collected my badge, had a coffee and  talked with Mark van Aalst (Sitecore NL) about the Dutch Sitecore User Group (more on that later).

Welcome Reception

Symposium Day 1

Keynote

On the first day of the Symposium I arrived a bit late. The keynote by Michael Seifert had already started.

Day 1 – Keynote

When the evening program was disclosed it was announced that a trip to Las Vegas could be won, woohoo!

Day 1 –  Win a trip to Las Vegas!

After the keynote a small guerilla action took place to promote the Dutch Sitecore User Group  (many thanks to the distributor of the flyers 😉 ). If you want to join the first meeting of the Dutch Sitecore User Group on the 31st of October please register here.

Day 1 – Sitecore User Group NL flyer

Developer Track

Being a developer I was of course most interested in attending the Developer Track. This started with a keynote by Kerry Bellerose and Lars Nielsen about all the new features Sitecore had been working on lately. One of the main features is Foundry 4. This module enables advanced multisite management and will be made availble for free!

Day 1 – Dev Keynote – Foundry 4

Another great new feature which will be released is SPEAK. SPEAK is the new UI component which is based on HTML5, CSS3 and Javascript and will replace the existing and cumbersome xaml-based SHEER UI.

Day 1 – Dev Keynote – SPEAK UI

Next Tim Ward gave an excellent presentation about various solutions to handle multisite environments. He presented  a completely new module called ‘Sitecore Multisite Manager’ which can be downloaded from github. Really impressive work!

Day 1 – Multisite solutions

The last presentation of day 1 was certainly one of the most memorable ones. It was a ‘drama play’ featuring Kerry Bellerose (as the project manager) and John West (as the Sitecore consultant) on how to avoid 5 common pitfalls when doing Sitecore projects. Although the idea of this drama play was nice, the result wasn’t what I had hoped for (although it was quite entertaining in certain ways ;). I prefer seeing John West talk about in depth technical stuff. That is where he really shines.

Day 1 – Drama play: 5 ways to kill your website

Symposium Day 2

The second day of the symposium started with a mind-blowing presentation by Tim Ward about Item Buckets. These Buckets are meant to hold very large numbers of items without degrading performance when manipulating or querying these items. The ‘Sitecore Item Buckets’ module can be downloaded from github.

Day 2 – Item Buckets

When using the Sitecore Item Buckets, a new search field (based on SPEAK) is available in the Content Editor. Tim showed various ways how this field could be used to query items in the Buckets. I think the entire audience was in awe after this presentation. It was certainly my personal favorite.

Day 2 – Item Buckets

Product Track

Since I wanted to learn more about the available personalization options in Sitecore I made a small sidestep to the Product Track and attended ‘The Many Types of Sitecore Personalization and When to Use It and How’ presentation by Lars Petersen. Lars is an entertaining speaker and this was a very informative presentation (although as a developer I missed seeing some code 🙂 ).

Developer Track

Back on the right track for another presentation by John West. This time about Sitecore MVC and other ‘Killer Features’ of Sitecore 6.6.

Day 2 – Sitecore MVC & 6.6 Killer Features

Again a ‘drama play’ performed by Kerry (the PM) and John (Sitecore dev) where John educates Kerry about the benefits of using Sitecore MVC. In my opinion the drama could have been skipped and that time could have been better spent on a more in depth view on Sitecore’s MVC implementation.

Day 2 – MVC drama

In the Q&A session afterwards Robbert Hock asked some questions to John West.

Day 2 – Robbert Hock  in the MVC Q&A session

Next another great developer oriented presentation by Lars Nielsen about how to become the marketer’s best friend. Since I don’t have many friends in marketing this was a perfect fit for me :).

Day 2 – Marketers best friend

Lars gave a very funny demonstration which involved ‘John East’, the overeager developer.

Day 2 – John East 😉

Lars showed several ways how to use the DMS API to extract valuable customer statistics by involving multidimensional space mathematics. It was very inspiring to see what can be achieved with DMS.

Day 2 – Breaking behaviour

The final developer presentation was given by Morten Ljungberg on how to use the excellent Visual Studio extension Sitecore Rocks. Although many of shown features were known several small gems were revealed that makes life of a Sitecore developer even easier (such as Commandy).

Day 2 – Sitecore Rocks!

To conclude

This was my first Sitecore Symposium and I enjoyed it immensely. It was great meeting other Sitecore enthousiasts in real life and seeing the faces behind the Twitter avatars :). The only downside was not winning the Social Media contest ;), congrats to Robbert though!

The way the Sitecore products move forward, being improved and extended continuously (and some even being provided free of charge), is very exciting and I look forward using many of the new features. Until the next Sitecore Symposium or the first Dutch Sitecore User Group meeting!

Marc

Written by marcduiker

September 18, 2012 at 8:39 pm

Sitecore Custom Time Field

with 7 comments

Problem

Chantal WeijersHi Martijn, I frequently post marketing events on my website. This is not so hard to do, actually due to Sitecore this is quite easy! However, when I want to specify the start and end times I always have to provide the date as well, even when the begin and end dates are the same. Next to the fact that this is slightly annoying, it also looks misplaced and confusing. Do you have a solution for this?

Martijn van der MeerHi Chantal, I certainly do. In order to provide a solution for your problem, I will walk you through the following:

  • What is a Time Field?
  • Why a Time Field?
  • Custom Time Field Code
  • Sitecore Implementation
  • Time Field Rendering (updated)

Solution: Time Field

What is a Time Field?

A Time field is an element for displaying and selecting just the time (figure 1).

Figure 1: Custom Time field

This field type is currently not available as a standard Sitecore field. The two standard date/time elements in Sitecore which do exist are the Date field and the DateTime fields (figure 2).

Figure 2: Standard Sitecore Date and DateTime fields

Why a Time Field?

There are several occasions where a specific Time field could come in handy. For instance, the field can be used in templates for one day events or workshops when start and end times are required but not two different dates. The solution described in this post enables users to specify only what is necessary.

Custom Time Field Code

The code below implements the custom Time field. Most of the code is taken from the standard Sitecore Date field. There are a number of small adjustments made to convert it to a Time field. For instance, the Sitecore TimePicker class is used to replace the DatePicker from the original code. Complete the following steps to define the custom Time field:

  1. Create a new C# class file (e.g. TimeField.cs) in your Sitecore project.
  2. Copy the following code in it (update the namespace appropriately).
  3. Save the file and compile the project.

Now proceed with the ‘Sitecore Implementation’ section.

using System;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Web.UI.Sheer;
using Sitecore.Shell.Applications.ContentEditor;

namespace NCIM.SitecoreTeam.Demos.CustomTypes
{
    public class TimeField : Input, IContentField
    {
        private TimePicker _picker;

        public string ItemID
        {
            get
            {
                return base.GetViewStateString("ItemID");
            }
            set
            {
                Assert.ArgumentNotNull(value, "value");
                base.SetViewStateString("ItemID", value);
            }
        }

        public string RealValue
        {
            get
            {
                return base.GetViewStateString("RealValue");
            }
            set
            {
                Assert.ArgumentNotNull(value, "value");
                base.SetViewStateString("RealValue", value);
            }
        }

        public TimeField()
        {
            this.Class = "scContentControl";
            base.Change = "#";
            base.Activation = true;
        }

        public override void HandleMessage(Message message)
        {
            Assert.ArgumentNotNull(message, "message");
            base.HandleMessage(message);
            if (message["id"] != this.ID)
            {
                return;
            }
            string name;
            if ((name = message.Name) != null)
            {
                if (name == "contentdate:today")
                {
                    this.Now();
                    return;
                }
                if (name != "contentdate:clear")
                {
                    return;
                }
                this.ClearField();
            }
        }

        public string GetValue()
        {
            if (this._picker == null)
            {
                return this.RealValue;
            }
            return this._picker.Value;
        }

        public void SetValue(string value)
        {
            Assert.ArgumentNotNull(value, "value");
            this.RealValue = value;
            if (this._picker != null)
            {
                this._picker.Value = value;
            }
        }

        protected override Item GetItem()
        {
            return Client.ContentDatabase.GetItem(this.ItemID);
        }

        protected override bool LoadPostData(string value)
        {
            if (base.LoadPostData(value))
            {
                this._picker.Value = (value ?? string.Empty);
                return true;
            }
            return false;
        }

        protected override void OnInit(EventArgs e)
        {
            base.SetViewStateBool("Showtime", true);
            this._picker = new TimePicker();
            this._picker.ID = this.ID + "_picker";
            this.Controls.Add(this._picker);
            if (!string.IsNullOrEmpty(this.RealValue))
            {
                this._picker.Value = this.RealValue;
            }
            this._picker.OnChanged += delegate
            {
                this.SetModified();
            };
            this._picker.Disabled = this.Disabled;
            base.OnInit(e);
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            base.ServerProperties["Value"] = base.ServerProperties["Value"];
            base.ServerProperties["RealValue"] = base.ServerProperties["RealValue"];
        }

        protected override void SetModified()
        {
            base.SetModified();
            if (base.TrackModified)
            {
                Sitecore.Context.ClientPage.Modified = true;
            }
        }

        private void ClearField()
        {
            this.SetRealValue(string.Empty);
        }

        private void SetRealValue(string realvalue)
        {
            if (realvalue != this.RealValue)
            {
                this.SetModified();
            }
            this.RealValue = realvalue;
            this._picker.Value = realvalue;
        }

        private void Now()
        {
            this.SetRealValue(DateUtil.IsoNowTime);
        }
    }
}

Sitecore Implementation

Figure 3: Sitecore system content tree (core database)

Make sure the project containing the TimeField type is compiled and available in the \bin folder of your Sitecore solution. Then follow these steps within Sitecore.

  1. Open Sitecore in Desktop mode.
  2. Open the Core database. (in the lower right corner of the screen to change database.)
  3. Open the Content Editor.
  4. Navigate to Sitecore/System/Field Types/Simple Types. In this folder all the simple types for the Sitecore templates are listed.
  5. Duplicate the Date item and rename it to Time (figure 3).
  6. Open the Time item.
  7. Optional: Change the icon for the item to something more specific for time (e.g. People/32×32/clock.png).
  8. Enter the name of the dll that contains the TimeField type (without the .dll extension) in the Assembly field (example: NCIM.SitecoreTeam.Demos, figure 4).
  9. Enter the the namespace + name of the TimeField class in the Class field (example: NCIM.SitecoreTeam.Demos.CustomTypes.TimeField).
  10. Empty the Control field.
  11. Save the item.
  12. Expand the Time item and open the Menu folder.
  13. Select the Today item and rename it to Now.
  14. Open the Now item and change the value of the Display name field to Now.
  15. Save the item.
  16. Delete the WebEdit Buttons folder underneath the Menu folder. This enables the display of a calendar control in Preview/Edit mode and is useless for the Time field.
  17. Save the item.

Figure 4: Time type details

The Time type should now be available as a simple type in Sitecore templates as shown in figure 5.

Figure 5: Time available as simple type in a template

An example of an event item with Start and End time fields is shown in figure 6.

Figure 6: Sample event showing Start and End times.

Update: Time Field Rendering

I received a question about extending this solution to enable a Time field rendering in weblayouts and controls using markup such as:

<sc:Time runat="server" ... />

First I looked into the implementation of the Sitecore Date field  (Sitecore.Web.UI.WebControls.Date in Sitecore.Kernel) and created a Time class based on that. Follow these steps to add a Time class to your solution:

  1. Create a new C# class file (e.g. Time.cs) in your Sitecore project.
  2. Copy the following code in it (update the namespace appropriately).
  3. Save the file and compile the project.
using Sitecore.Collections;
using Sitecore.Diagnostics;
using Sitecore.Web.UI.WebControls;

namespace NCIM.SitecoreTeam.Demos.CustomTypes
{
   public class Time : FieldControl
   {
      public string Format { get; set; }

      protected override void PopulateParameters(SafeDictionary<string> parameters)
      {
         Assert.ArgumentNotNull(parameters, "parameters");
         base.PopulateParameters(parameters);
         if (string.IsNullOrEmpty(Format))
            return;
         parameters.Add("format", Format);
      }
   }
}

In order to use the sc tag prefix either register the namespace in the control where you want to use the Time field or register the namespace in the web.config:

<%@ Register TagPrefix="sc" Namespace="NCIM.SitecoreTeam.Demos.CustomTypes" Assembly="NCIM.SitecoreTeam.Demos" %>

Now the sc:Time rendering can be used, for instance when using the SampleEvent item which has a Start time field (have a look again at figure 6):

<sc:Time runat="server" ID="StartTimeField" Field="Start time" />

Written by marcduiker

August 6, 2012 at 12:05 pm

Posted in Sitecore

Tagged with , , ,

Continuous Integration in Sitecore

leave a comment »

Basically this post is a recap of the “Sitecore and Continuous Integration” webinar, perhaps with some extra details about some subjects.

The goal of continuous integration is to push every little piece of new software to next environments, the last step being production. Along this way, you want your software to be merged, compiled and tested.

This way of developing has been around for a while with standard ASP .NET software. The problem with Sitecore is that it also heavily relies on the database to function. Source control of the database is possible, but can be a deviant complex task. Some guys at Hedgehog developed TDS, a licensed solution for all your Sitecore collaboration problems. This isn’t an option for everyone however, and you maybe want a more simple cost-free solution.

Typical Sitecore development environment with multiple developer machines, development and version control servers and the published site.

Make sure you install Sitecore Rocks before you continue. Watch Pieter Brinkmans webinar if you never heard of Sitecore Rocks before.

VS Project structure

You want your project to be easily shared and deployed between developers. Here are some tips:

  1. Every developer has his own “dirty dev” web, master and core database, best not to use a shared database for development, as you will get in each others way.
  2. Create a different folder for your Sitecore libraries and let VS copy them to the bin folder on each build.
  3. Use a App_Data folder in your VS solution for your Sitecore data folder. Make sure you give this folder the required rights! More on ASP.NET folder structure can be read here
  4. In your web.config file, set a relative reference to App_Data in your datafolder variable.
  5. Make separate config files for each environment you are going to use.
  6. Also make separate ConnectionString.config files, unless you use the same settings on each environment.
  7. (Optional) You may want to consider removing the Sitecore shell from the project, depending on how badly you want use it in your development environment. Also, source control systems aren’t comfortable with large volumes of files. If you do decide to remove it, make shure you leave the Sitecore Rocks webservice intact.
Serialization of items in Sitecore Rocks

Serialization of items in Sitecore Rocks

Sitecore Item Version Control

First, make sure you have a folder called “serialization” in your App_Data folder. This is the folder where our Sitecore items are put into text files.

Committing items

Use Sitecore Rocks to serialize the items you want to share. To do this, right-click the node of the tree and go to Tools/Serialization/Serialize Tree. Do not put the entire Sitecore tree in there, just the necessary like templates, content and media. Now that you have the files on disk, you can commit them to the rest of the team.

Updating items

Synchronize your serialization folder and perhaps the rest of the project. Now just click one of the Update options in the serialization menu and voila, your items are updated!

Automated Building and Testing

This is something that depends on your own preference, methods and project conditions. The idea is to have a different environment with a Sitecore Instance(with shell perhaps) that checks out the latest version of the application of the source control server. The application is then build and tested if you have unit testing. Some options for these are:

There is also this interesting article about Sitecore Unit testing without an HTTP Context.

Deployment

I personally use Microsoft Web Deploy to do this. You can deploy directly from Visual Studio as well as a build server. I used this article to set everything up.

Setting up continuous integration for Sitecore can take some time to perfect, but you will find it very productive once all the little daily frustrations are gone, making time to concentrate on building better websites.

Written by lucasbol

June 29, 2012 at 11:06 am

Sitecore Item Mapping (part 1)

leave a comment »

Problem: Missing items

Avatar Chantal WeijersThere’s an issue with our website since one of our content authors made some changes to the Sitecore content tree. Some items are not showing up on the site. Could you have a look what could be wrong?

Avatar Marc DuikerIt appears that some content items have been moved. Since the current code uses hard-coded item paths to locate the items there’s now a mismatch between the code and the items in Sitecore. There are various options how this can be solved and prevented in the future, let me explain…

Solution: Item mapping using GUIDs

The first thing that comes to mind is that the developers could use item GUIDs in their code instead of (or better: in combination with) item paths or names when retrieving items from the database. The reason is that the item GUID remains the same even when the item is renamed or moved. This would prevent mapping mismatches in such cases.

Warning: Do not use  GUIDs to retrieve content items which are supposed to be dynamic or volatile. Access those items via their static parent item. For a truly dynamic & flexible approach a Setting item could be used which contains GUIDs and paths to the dynamic content items (this last approach is not covered in this post).

Basic Example

Consider the following example of an online bookstore where individual books are stored as content items as children of the Books folder. The book items are based on the Book template (Figure 1). The individual books are considered dynamic content while the Books folder is considered to be static and therefore suitable to be accessed by the GUID.

Sitecore master tree highlighted

Figure 1

The next three code samples each show a GetBooks method which returns the exact same items: a list of books (from the Books folder) that match the Book template.

Approach using only paths and names

public static IEnumerable<Item> GetBooks()
{
    const string booksItemPath = "/sitecore/content/Home/Books";
    const string bookTemplateName = "Book";

    return Sitecore.Context.Database.GetItem(booksItemPath).GetChildren().Where(
        item => item.TemplateName == bookTemplateName);
}

Pro: If  items are deleted and replaced by new items with the same name and location the solution will still work.
Con: If items are moved or renamed the solution will break.

Approach using only GUIDs

public static IEnumerable<Item> GetBooks()
{
    const string booksItemGuid = "{0842454E-361B-4AD3-B03F-43E89779A40F}";
    const string bookTemplateGuid = "{54C24C4E-AAA9-41D3-9977-73C81D5E7747}";

    return Sitecore.Context.Database.GetItem(booksItemGuid).GetChildren().Where(
        item => item.TemplateID.ToString() == bookTemplateGuid);
}

Pro: If items are renamed or moved the solution will still work.
Con: If items are deleted and replaced by new items with the same name the solution will break.

Combined approach using both identifiers

public static IEnumerable<Item> GetBooks()
{
    const string booksItemPath = "/sitecore/content/Home/Books";
    const string booksItemGuid = "{0842454E-361B-4AD3-B03F-43E89779A40F}";
    const string bookTemplateName = "Book";
    const string bookTemplateGuid = "{54C24C4E-AAA9-41D3-9977-73C81D5E7747}";

    return GetContentItem(booksItemGuid, booksItemPath).GetChildren().Where(
        item => IsTemplateMatch(item, bookTemplateGuid, bookTemplateName));
}

private static Item GetContentItem(string id, string path)
{
    // First try to get item via ID.
    // If no item is found try to use the item path.
    return Sitecore.Context.Database.GetItem(new ID(id)) ?? Sitecore.Context.Database.GetItem(path);
}

private static bool IsTemplateMatch(Item item, string expectedId, string expectedName)
{
    return (item.TemplateID.ToString() == expectedId || item.TemplateName == expectedName);
}

Pro: Works in both situations where items are renamed/moved or deleted and replaced with other items having equal names.
Con: Matching templates by name (as a fallback) might not always be a good choice. You really need to make sure the solution uses uniquely named templates.

How to get the GUID

The easiest way to copy an item GUID is to use Sitecore Rocks, double-click the item to open it and then click the small clipboard icon next to the Item ID (Figure 2).

Sitecore Books folder item highlighted

Figure 2

Structuring the identifiers

Although the usage of GUIDs in addition to paths and names result in more reliable solutions (which perform better than only relying on paths) the GUIDs are not very developer friendly with respect to readability and ease of use.

The following code samples show how item mapping can be further abstracted by placing the identifiers (GUIDs, paths, names) in a static class. The structure of this static class can be modeled to mimic the content tree in Sitecore. This allows a more fluent use of identifiers for the developer and by keeping all the GUIDs, paths and names in one place it also improves the maintainability of the code.

/// <summary> Static class which mimics the structure of the Sitecore content and templates tree
/// in order to provide fluent access to content item and template identifiers.
/// </summary>
public static class Model
{
    public static class Templates
    {
        public static class Book
        {
            public static TemplateID TemplateId
            {
                get { return new TemplateID(new ID("{54C24C4E-AAA9-41D3-9977-73C81D5E7747}")); }
            }

            public static string Name
            {
                get { return "Book"; }
            }
        }
    }

    public static class Content
    {
        public static class Books
        {
            public static ID Id
            {
                get { return new ID("{0842454E-361B-4AD3-B03F-43E89779A40F}"); }
            }

            public static string Path
            {
                get { return "/sitecore/content/Home/Books"; }
            }
        }
    }
}

Once the Model class is in place the GetBooks method can be refactored as follows:

public static IEnumerable<Item> GetBooks()
{
    return GetContentItem(
        Model.Content.Books.Id, Model.Content.Books.Path).GetChildren().Where(
            item => IsTemplateMatch(
                item, Model.Templates.Book.TemplateId, Model.Templates.Book.Name)
    );
}

(The GetContentItem and IsTemplateMatch methods are slightly adapted as well to use TemplateID and ID objects directly instead of the GUID strings.)

Sitecore does it too!

You don’t need to create static model classes for standard Sitecore templates and items since they already exist! Have a look at the Sitecore.TemplateIDs and Sitecore.ItemIDs classes in the Sitecore.Kernel.dll. Here’s an example how to retrieve the content root item using the Sitecore.ItemIDs class.

Item contentRoot = Sitecore.Context.Database.GetItem(Sitecore.ItemIDs.ContentRoot);

Static vs Instance

As you can see in the last GetBooks method which uses the model, using static nested classes result in quite some code bloat when calling the GetContentItem and IsTemplateMatch helper methods since the full nested hierarchy of the model needs to be specified as parameters.

An alternative would be to use instance classes to define content and template items and implement interfaces for them. The helper methods could then accept these interfaces which further decouples the code and improves testability as well.

The following code sample shows one possibility how instance classes and interfaces could be used to create a model.

public static class Model
{
    public static IContentItem GetBooksItem()
    {
        return new Books();
    }

    public static ITemplate GetBookTemplate()
    {
        return new Book();
    }
}

public class Books : IContentItem
{
    public ID Id
    {
        get { return new ID("{0842454E-361B-4AD3-B03F-43E89779A40F}"); }
    }

    public string Path
    {
        get { return "/sitecore/content/Home/Books"; }
    }
}

public class Book : ITemplate
{
    public TemplateID TemplateId
    {
        get { return new TemplateID(new ID("{54C24C4E-AAA9-41D3-9977-73C81D5E7747}")); }
    }

    public string Name
    {
        get { return "Book"; }
    }
}

public interface IContentItem
{
    ID Id { get; }
    string Path { get; }
}

public interface ITemplate
{
    TemplateID TemplateId { get; }
    string Name { get; }
}

Using this new Model class the GetBooks method and the helper methods can be refactored as follows:

public static IEnumerable GetBooksUsingNewModel()
{
    return GetContentItem(Model.GetBooksItem()).GetChildren().Where(
        item =>; IsTemplateMatch(item, Model.GetBookTemplate()));
}

private static Item GetContentItem(IContentItem contentItem)
{
    return Sitecore.Context.Database.GetItem(contentItem.Id) ??
        Sitecore.Context.Database.GetItem(contentItem.Path);
}

private static bool IsTemplateMatch(Item item, ITemplate template)
{
     return (item.TemplateID == template.TemplateId || item.TemplateName == template.Name);
}

What’s next?

Manually creating model classes in order to map items is ok for a small project with just a couple of items and templates. But in a real world project, where dozens of models with all their properties would be required, manual creation would not be the way to go. Thankfully there are some alternatives…

Automated Model Generation

There are various solutions available which generate code in order to do item mapping. The solutions I currently have listed are:

  1. CodeGen
  2. Custom Item Generator
  3. Compiled Domain Model
  4. Glass.Sitecore.Mapper
  5. Sitecore Rocks

To avoid one very, very long blog post I will cover each solution in a separate post over the next few weeks. For each solution I’ll discuss the following aspects in order to make a good comparison:

  • Installation & Configuration
  • Ease of use
  • Features & Extensibility

If you know any other code or item generation products or want to include other aspects, leave a comment here on the blog or send me an email!

(This post was updated on June 15 to include samples of retrieving items using both GUIDs and paths and mentioning the pros and cons of each method. The Static vs Instance section was also added.)

Written by marcduiker

June 11, 2012 at 8:27 am

Sitecore Guest Webinar: Continuous Integration

with one comment

Our colleague Lucas Bol gave the first Dutch Sitecore guest webinar last week. The subject was continuous integration with Sitecore using open source products as an alternative to commercial products such as TDS by Hedgehog Development.

The solution that is presented enables developers to work purely from Visual Studio and Sitecore Rocks without the need to create and  deploy Sitecore packages.

Lucas will soon post additional details here to further explain this solution.

Until next post!

Written by marcduiker

May 14, 2012 at 7:58 am

Introduction

leave a comment »

Welcome to the NCIM Sitecore Team blog!

First, let’s introduce ourselves…

Avatar Marc Duiker

Hi! I’m Marc Duiker and I work as a .Net & Sitecore developer at NCIM. My first contact with Sitecore was at WoningNet, a Dutch company that provides products and services for housing corporations. It was love at first site 😉 when I started to use Sitecore. I was really impressed how easy it is to work with and how customisable the platform is. Since then I followed the Sitecore .Net Developer and the Advanced Developer trainings and currently I’m working on a Sitecore project for the Belgian railway company in Brussels.

Avatar Chantal Weijers

Hi! I’m Chantal Weijers. I’m an account manager at NCIM where I’m in charge of our partnership with Sitecore. Since my Advanced User training in London, I have assisted with the development of our website in Sitecore. During this process, I have come across several questions and problems where Marc helped me out. I think it would be useful for all of you, who don’t have a Sitecore developer sitting next to them, to understand how Sitecore works and how it can be used effectively. With this blog we try to bridge the gap between the developer and the marketer in order to take full advantage of the Sitecore experience.

What to expect?

Together, and with the help of a few other colleagues, we will post both technical and marketing related articles on this blog, all concerning Sitecore of course.

While we’re working on our first technical post, you can still sign up for the next Dutch Sitecore developer webinar (May 10) where Lucas Bol, one of our Sitecore developers, will explain how to set up a Sitecore development environment using open source tools.

Until next post!

Written by marcduiker

May 9, 2012 at 11:40 am

Posted in Sitecore

Tagged with ,