Skip to content

Why we need DefinedContent

Dave Greasley edited this page Apr 5, 2015 · 4 revisions

The Problem

Quite often we find ourselves needing to reference a particular page in our site structure for one reason or another. This often leads to people having to reference the Id of a particular page.

Many people who use Umbraco will have seen code such as this:

@{
    int searchPageId = 1234;
    var searchPage = Umbraco.TypedContent(searchPageId);
}
<a href="@searchPage.Url">Go to search page</a>

Whilst the code above will work, it has a number of problems:

  • The Id of the search page might change - if the page gets deleted then it would need to be recreated, resulting in a different Id.
  • If we are running our site in multiple environments then the Id of our page may be different per environment.
  • If we have lots of hard coded references to the page in question and the Node Id changes, we have to update each reference manually.

Existing Solutions

I have seen, and indeed used, a number of solutions to the problem. None of them complete satisfactory.

Constants class:

public class NodeIdConstants
{
    public const int SearchPageId = 1234;
}

This class solves the problem of updating lots of references to the same Id, because we only have the Id in one place and then we refer to the NodeIdConstants.SearchPageId constant when we need to get the Id of the search page.

It does, however, prove difficult to manage the Ids if they change between environment because you will end up either having to put the source file for this class in the App_Code folder or update it when you are doing a build for a new environment.

Dictionary Items:

More recently I have been using Dictionary items to store Node Ids in. Dictionary items are handy because they can be created and updated in the back office and do not need recompiling or redeploying of any code in order to update.

Again, I normally have a class which wraps the Dictionary Ids such as:

public static class PageIds
{
    public static int SearchPageId
    {
        return Convert.ToInt32(umbraco.library.GetDictionaryItem("searchPageId"));
    }
}

Now I can reference my search page by PageIds.SearchPageId, which is actually quite nice. Again this solves our problem of updating lots of references if an Id changes and it solves the problem with the Constants class that I need to recompile my code in order to change an Id.

If an Id does change though, either per environment or for some other reason then we still have to remember to go through and update the Dictionary items.

Another issue I have with this is that it feels like a bit of a hack. The Dictionary is meant for text translations in various languages, not for storing the Ids of nodes.

Also, what if we have a multi language site? That means we have to maintain a list of our Dictionary items in each language the site supports or (using the code above) people in other languages will get lots of errors as the call to Convert.ToInt32 doesn't like if you pass in an empty string.

The Answer

DefinedContent fixes all of these problems and more! See Features and Usage for more information.