1. Skip to content
  2. Skip to sidebar

Custom Item Generator

As our first official Velir blog post we wanted to introduce a tool that we’ve recently committed to the Sitecore shared source repository, the Custom Item Generator.  If you want to skip the introduction you can find the module here at http://marketplace.sitecore.net/en/Modules/Custom_Item_Generator.aspx

When we started developing for Sitecore we ran into the common issue of how best to structure our project code, specifically how to organize code used for accessing items and the content stored in their fields. Putting this code in code behinds, which seems to be a somewhat common practice, often leads to sites that are not well structured and are very difficult to maintain.  Around this time we happened upon a blog post by Alexey Rusakov talking about the Sitecore provided custom item classes.  Reading through the blog post we realized this approach solved many of the issues we were trying to solve (I would link to said post here, but I cannot seem to find it any more). Custom items are used by Sitecore in the API to wrap access to various Sitecore provided templates, two examples would be MediaItem and TemplateItem. We took this idea, expanded it a bit for our own uses, and created a tool to generate the custom item class files and thus the Custom Item Generator was born.

Introduction to Custom Item Pattern

Below is a very basic example of accessing an item using a field name.  Say we have a Publication item with a Title field that we want to display, without a custom item it might look something like this

Item pubItem = sitecoreDb.GetItem("{PubGuid}");
litTitle.Text = pubItem[“Title”];

Whereas with a custom item, the code would look like this

PublicationItem pubItem = sitecoreDb.GetItem("{PubGuid}");
litTitle.Text = pubItem.Title.Rendered;

The above example, while simple, highlights some of the advantages of using custom items to wrap templates and the fields contained within them.

Code Structure – One of the main benefits of using custom items to wrap access to templates is that it creates a sensible structure for template based code.  This structure is extremely valuable in team based development and allows new Sitecore developers to come up to speed quickly.

Field Name Safety – In the above non custom item example we need to know the exact name of the title field.  If that field name was changed in the Sitecore template, the project will still compile, but we would receive a runtime error when accessing the field.  By wrapping the reference to the field in a custom item we only need to update the field name in one location.

Convienent Type Casting - Often times it is helpful to cast field values to a specific type.  Easy examples would be casting an Integer field value to an int, or returning a List of items from the many list based Sitecore fields.

Ease of Maintenance – Centralizing template logic helps eliminate duplicate code and reduces the guess work needed to determine where certain code is located in the system.  This dramatically eases maintenance over the long term, especially when bringing in less experienced Sitecore developers.

Velir Custom Item Overview

At a base level our approach to the custom items is similar to Sitecore’s, however we have also made some additions to our custom items to make them even easier to work with.

Field Access

For each kind of field we have created custom field classes to provide alternate ways to get at a field’s value.  For example the Publication item mentioned earlier will have the following options

  • FieldName.Rendered – This will access the field through the Sitecore field renderer, in most cases where you are displaying a field’s content on the front end you would want to use .Rendered.
  • FieldName.Raw – This will return the underlying value that is being stored in the field.
  • FieldName.Field – This will allow you to access the underlying Sitecore provided field object.

In addition to the above we also provide a convenience property based on the type of field.  A good example of this can be seen accessing an Image URL

String imageUrl = pubItem.Image.MediaUrl;

Partial Classes

For a variety of reasons we break our custom items down into partial classes, the breakdown is this

  • .base.cs – This is where the auto generated code goes.  No custom code should be placed in these classes since if they are regenerated the custom code would be overwritten.
  • .instance.cs – Contains code related to a single instance of an item of the template.
  • .interface.cs – Contains all interface implementations related to the template.
  • .static.cs – Contains static methods related to the template.

By breaking the classes up this way we end up with much cleaner/smaller .cs files.  This setup also provides guidance as to where certain kinds of code should go.  Say for example a new developer comes into a project and needs to implement an interface for a specific custom item, with these partial class files there is no question as to where that code should be placed.

The Custom Item Generator (CIG)

When we first started working with custom items we were creating the class files by hand.  This process is both time intensive and very error prone.  As you might guess this sometimes lead to custom items that were out of sync with their related templates.  We realized that to fully integrate custom items into our development process, we were going to need a tool to generate the class files.

Version 0

The first version of the CIG was a basic web form held in a utilities folder in the web root.

Initially we just copied and pasted the generated code into a single manually created class file.  This process was still too slow, so we quickly replaced that with auto generating the class files.

The main issues with this approach being

  • You had to leave Sitecore to generate the class files.
  • You had to be careful not to overwrite code when you regenerated the custom items.
  • It was not straightforward to create/recreate custom items for folders full of templates.

Version 1

To solve some of the issues we made the following changes to the CIG

  • Added the ability to create the custom items from the Sitecore UI.
  • Broke the custom item classes into partial classes.  This allows us to recreate the .base.cs file without worrying about overwriting custom code.

Now to create custom items it is simply a matter of going to the templates folder, right clicking on the template/folder of templates we wish to create, and click generate

Where we go from here

We have been developing sites using custom items with the Custom Item Generator for the last few years, and we have found this setup to work very well.  Using the tool makes the code creation simple and quick, and the structure provided by this approach has helped us to keep our sites maintainable and flexible.

In the near future we will be doing more posts covering some custom item examples as well as ways that the Custom Item Generator can be extended.  Hopefully this post combined with the shared source wiki page will be enough information to get you started using the tool. We are very interested in feedback from the Sitecore community, so please send any comments/questions/suggestions to customitem@velir.com.

29 Responses to "Custom Item Generator"

  1. I was excited to see this tool presented at Dreamcore 2010 and am glad to see it out in the wild now as well. We’ve been employing the Custom Item pattern for a few years now at Aware but, as you noted, it does get pretty tedious creating all of the wrapper classes by hand.

    Hopefully this tool will help spur others into using the Custom Item pattern and, dare I say it, usher in more consistent Sitecore development practices.

    Thanks for sharing with the community!

    Adam

  2. Gabriel Boys says

    Hey Adam,

    We are excited to see what happens when people get their hands on this tool. The custom item pattern has served us well, so we are definitely glad to try and help make it easier for others to get started using them.

  3. Nice idea Gabriel. I can’t wait to take it for a spin.
    Just on the custom item pattern, I tried to remember as much about it from Alexey’s blog as I could and posted about the pattern earlier this year: http://adeneys.wordpress.com/2010/06/25/custom-item-pattern/

    BTW, how about creating a Sitecore Rocks! plugin for the Custom Item Generator. That would be sweet!

  4. I installed the package last night in a brand new SC 6.2 install. I made some dummy templates and tried to generate the custom items but the generate button didn’t do anything. I suspect something may have been missing from the package? Today I’m going to pull the source from SVN and build it myself.

  5. I just created a brand new SC 6.2 site and added the CustomItemGenerator source to my solution as another project. I installed the package into my site, then built the source to overwrite the package’s CustomItemGenerator.dll. I tried to generate custom item classes for a sample dummy template and the generate button doesn’t seem to do anything still.

    I checked what the button does in the core and saw it calls devtools:generatecustomitem(id=$Target) so I’m thinking maybe something isn’t hooking in. I looked in the CustomItemGeneratorCommand class and saw that if you try to generate custom items on any items other than a template or template folder, there should be a sheer alert in SC, which I don’t get.

  6. Gabriel Boys says

    Hey Mark,

    I just downloaded the package an retested it and it is working for me. If you see all of the menu items but clicking on Generate Custom Items does not do anything my guess is that the command is not set up correctly. Do you see this

    in ~/App_Config/commands.config . If that is not there, try adding it and see if that fixes the issue.

  7. Gabriel Boys says

    Oops the XML got stripped out there, this line should be in the commands.config

    <command name=”devtools:generatecustomitem” type=”CustomItemGenerator.SitecoreApp.CustomItemGeneratorCommand,CustomItemGenerator” />

  8. Gabriel Boys says

    @Alistair We have been looking into Sitecore Rocks integration, that is definitely coming down the road.

  9. Thanks Gabe — that command wasn’t listed in the commands.config (for me at least). Now its working.

  10. Gabriel Boys says

    Hey Mark,

    That commands.config change has to made manually unfortunately, let me know if you run into any more issues.

  11. Awesome,

    Suggestion: If you made the item class web service enabled then you could easily make this a plug-in for Sitecore Rocks. If you need assistance with this, feel free to let me know.

  12. Gabriel Boys says

    Hey Lars, I would definitely appreciate some help with Sitecore Rocks integration. Is there some documentation you could point me to?

  13. This looks very promising! I have had the same ideas and actually built an implementation of this for a client, but without the automatic generation of the classes. I was actually checking out how to do this, but it seems that it is already done. Great work!

    In our code we have a Factory that delivers a hand-written class which is typesafe for the item’s template. Like:
    var item = TemplateFactory.GetTemplate(Sitecore.Context.Item);
    litTitle.Text = item.Title;

    Not too much work, but automatically generating these classes is wonderful.

    BTW. You forgot to mention how useful this is in databinding contexts:

    <asp:Literal Text='’/>

    Cheers, Matthijs

  14. Hmm, seems my code got mangled:

    <asp:Repeater ..>
    <ItemTemplate>
    <asp:Literal Text=’<%# Eval(“Title”) %>’/>
    </ItemTemplate>
    </asp:Repeater>

  15. Hey Matthijs,

    Thanks for the input, let us know what you think after using the tool a bit, feedback is always helpful. You note some good points here. I think what we are going to do down the road is write a more real world example than the simple one we already posted (which was just meant as a very basic introduction) and that example would include some code similar to what you have above.

    Gabe

  16. Hello Gabriel,

    Really nice module! This module (and some others) inspired me to make a very similar module that I’ve finished and contributed (I hope you don’t mind!!!). It was also mentioned on the Sitecore shared source weblog.

    I have made some different design choices, some of which are explained in the documentation.

    I’d love to get your opinion on the Compiled Domain Model module. You can watch the video if you want to get a quick impression of how it works.

    Module website: http://trac.sitecore.net/CompiledDomainModel/wiki
    Demo video: http://www.youtube.com/watch?v=ApngdILYpkA
    Module documentation: http://hermanussen.eu/sitecore/CompiledDomainModel/Documentation/default.htm

    Cheers,

    Robin

  17. Hey Robin,

    I will check it out, sounds interesting.

    Gabe

  18. Bo Breiting says

    I just downloaded the Custom Item Generator and installed it in Sitecore 6.4.1. However when I push the Generate button in the tool window I recieve the error “Unable to find resource ‘CustomItem.base.vm’”. I have tried downloading the source code and stepped through it in debug mode but as far as I can see the path to the nVelocity templates is resolved correctly and set in CustomItemGenerator.CodeGenerator.GenerateCode() in line 41 “props.SetProperty(“file.resource.loader.path”, NvelocityUtil.GetTemplateFolderPath());” where GetTemplateFolderPath() returns the correct physical path for the NVelocity template folder.

    Have you encountered this error?

  19. Gabriel Boys says

    Hey Bo,

    I am pretty sure this has something to do with using a .NET 4 app pool. If you switch it to .NET 2 it should work. We are currently looking into this issue, it has been brought up to us by other users as well.

    Gabe

  20. R Jong says

    I’m really looking forward to some adjustments that make this module work under the .NET 4 app pool. Any updates on this yet?

  21. Gabriel Boys says

    The issue here is with the version of Nvelocity included with Sitecore, it does not work with .NET 4. We are working on a version of the CIG that instead uses a newer version of Nvelocity from the Castle Project which can be found here

    http://www.castleproject.org/others/nvelocity/index.html

    If you need this immediately you should be able to refactor the source

    http://svn.sitecore.net/CustomItemGenerator/trunk

    using the newer NVelocity DLLs.

    That being said I hope to release the updated version of the CIG in the next few weeks.

    Gabe

  22. R Jong says

    Ok, looking forward to it. I’m currently creating a shared source module which makes use of modules that create wrapper classes for sitecore items. My module only runs in 4.0 so at this point I can only include an adapter for the CompiledDomainModel module. However I would really like to add your module also for greater usability.

  23. Wojciech Wieronski says

    Thanks Gabriel! Got the latest source from svn, removed the ref. to Sitecore.NVelocity added a ref. to the latest NVelocity from castle, built it and deployed the CustomItemGenerator and NVelocity assemblies. It worked!

  24. This is a different solution that also works:
    1) download the svn-source from the custom item generator (cig)
    2) make it a .NET 4 project
    3) add the default NVelocity dll (the one you use in your sitecore website) to the cig-project
    4) build the cig-project
    5) copy/paste the CustomItemGenerator.dll from the cig-project to the sitecore website.
    6) build the sitecore website solution.

  25. Gabriel Boys says

    Really sorry on the delay with releasing this, for anyone using .NET 4.0 this should work (please let me know if you use it and it does not)

    http://trac.sitecore.net/CustomItemGenerator/browser/Trunk/Data/Packages/Custom%20Item%20Generator-1.0-net4.zip

    Going to be writing an updated blog post in the next couple days, but the above is publicly available right now.

  26. I’ve created the getFullName method.now I want to call it in my sublayout…how to do that…I’m new to sitecore…?

  27. Hi Gabriel,

    I have incorporated ‘CustomItemGenerator’ into my projects and now I want to work with automated unit testing using NUnit Framework on one of my project.

    When I access the properties (like CustomTextField) generated through ‘CustomItemGenerator’ in NUnit GUI it throws error, below is the stack trace of error -

    at Sitecore.Pipelines.RenderField.RenderFieldArgs..ctor()
    at Sitecore.Web.UI.WebControls.FieldRenderer.RenderField()
    at Sitecore.Web.UI.WebControls.FieldRenderer.Render()
    at CustomItemGenerator.Fields.BaseCustomField`1.get_Rendered()
    at CustomItemGenerator.Fields.SimpleTypes.CustomTextField.get_Text()

    But when I create my own properties (string type) in the same class (generated through ‘CustomItemGenerator’), they are accessible in NUnit GUI.

    It would be great if you can provide some help on this problem.

  28. Hmm that is odd, I am not sure but it looks like it may be that the Sitecore render pipeline is not available. How are you running the NUnit tests against Sitecore?

  29. Richard Dias says

    Hi Gabe,
    I ran into you at Dreamcore UK, have been using CustomItemGen ever since. Was wondering how we could best handle empty fields when it comes to PageEditor. Even though field.Render works fine when there is text there to edit, we would want authors logged into edit mode via page editor to be able to add text to empty fields. Cheers. Richard

Leave a Reply:

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*

back to top