Did you know that you can access special properties of a Sitecore item the same way you get a typical field's value? 

Supported 'special fields' are:

  • @id = Item.ID.ToString()
  • @key = Item.Key
  • @lang = Item.Language.ToString()
  • @mid = Item.BranchID.ToString()
  • @name = Item.Name
  • @tid = Item.TemplateID.ToString()
  • @ver = Item.Version.ToString()
Example:
Sitecore.Data.Items.Item item = Sitecore.Context.Database.GetItem("/sitecore/content");

string id = item["@id"];
string key = item["@key"];
string lang = item["@lang"];
string mid = item["@mid"];
string name = item["@name"];
string tid = item["@tid"];
string ver = item["@ver"];

Sitecore.Diagnostics.Assert.IsTrue(id == item.ID.ToString(), "No match");
Sitecore.Diagnostics.Assert.IsTrue(key == item.Key.ToString(), "No match");
Sitecore.Diagnostics.Assert.IsTrue(lang == item.Language.ToString(), "No match");
Sitecore.Diagnostics.Assert.IsTrue(mid == item.BranchId.ToString(), "No match");
Sitecore.Diagnostics.Assert.IsTrue(name == item.Name.ToString(), "No match");
Sitecore.Diagnostics.Assert.IsTrue(tid == item.TemplateID.ToString(), "No match");
Sitecore.Diagnostics.Assert.IsTrue(ver == item.Version.ToString(), "No match");

When trying to determine if a Sitecore field has a value there are two basic ways.

Sitecore.Context.Item.Fields["fieldName"].HasValue

or

Sitecore.Context.Item.Fields["fieldName"].Value != ""

There are a few major differences.

  1. HasValue will not include checking a clone's original value, Standard Values or Default Values
  2. HasValue will return true if the field value is an empty string
  3. Field.Value will return the clone's original value, Standard Value or Default Values if the field doesn't have a value
  4. If there is no value on the field, clone's original value, standard values, or default value Field.Value will return an empty string
Therefore, 
Sitecore.Context.Item.Fields["fieldName"].Value == null

will never evaluate to true!

Beware. Sitecore Bug 

By calling Field.HasValue you will cause the Field.ContainsStandardValues property to have an invalid value! This has been logged as bug #368493 with Sitecore. For more information see this post.

There are many ways to get the value of a Sitecore field and each is slightly different.

string fieldName = "__Icon";
Sitecore.Data.Items.Item someItem = Sitecore.Context.Database.GetItem("/sitecore/content");
Sitecore.Data.Fields.Field someField = someItem.Fields[fieldName]; // you could use field name, ID or index here

// assumptions:
// 1. The Item exists
// 2. The field exists and has a value on the item
// 3. This was written against Sitecore 6.4.1.101221
                
// Method 1: Indexer on Item supports using a field's name, index, or ID
string value1 = someItem[fieldName];

// Method 2: Get the value from the field
string value2 = someField.Value; // This is commonly seen as someItem.Fields[fieldName].Value

// Method 3: 
string value3 = someField.GetValue(true);

// Method 4: 
string value4 = someField.GetValue(false);

// Method 5: 
string value5 = someField.GetValue(true, true);

// Method 6: 
string value6 = someField.GetValue(false, true);

// Method 7: 
string value7 = someField.GetValue(false, false);

// Method 8: 
string value8 = someField.GetValue(true, false);

// Method 9: 
string value9 = someItem.InnerData.Fields[theField.ID]; 

 

Method 1

This method uses an indexer on the item. If the field doesn't exist on the item you will get an empty string. If the field does exist you will get the same result as method 2.

Method 2

You need to have a field to use this method! If you called method 2 by the more commonly used notation of someItem.Fields[fieldName].Value you can get a null reference exception when trying to access the Value. The first  value to be found will be returned. 

  1. The Value
  2. If the item is a clone, the clone source's value
  3. Standard Value
  4. The field's default value
  5. Empty String

Method 3 & Method 5

These two are functionally equivalent. This method gets the value of the field similar to method 2.

Methods 4 & Method 6

These two are functionally equivalent. This method gets the value of the field without checking a clone's source or the standard values. The first value to be found will be returned. 

  1. The Value
  2. The field's default value
  3. Empty String

Method 7 

This method gets the value of the field without checking a clone's source, standard values or default value! The first value to be found will be returned. 

  1. The Value
  2. Null

Method 8 

This method gets the value of the field without checking the default value! The first value to be found will be returned. 

  1. The Value
  2. If the item is a clone, the clone source's value
  3. Standard Value
  4. Null

Method 9

The FieldList object at ItemData.Fields on an item is the real container of field information for that item. The FieldCollection on Item.Fields is really a way into the FieldList on the ItemData. ItemData is also a much more raw form. Internally the FieldList is a HashList<ID, string> where the key is the field id and the value is the raw value of the field. Cloned Values, Standard Values and Default Values do not exist in the FieldList and using this method would return null where the field has no value.

Sitecore Bug 

By calling Field.GetValue(false), Field.GetValue(false, true), or Field.GetValue(false, false) you can cause the Field.ContainsStandardValues property to have an invalid value! This has been logged as bug #368493 with Sitecore. For more information see this post.

I had discovered a little bug revolving around the Sitecore.Data.Fields.Field.ContainsStandardValue property in Sitecore (at least 6.4.1.101221 through current). You cannot trust the value returned by Field.ContainsStandardValue if you have made any of the following calls:

  • Field.HasValue
  • Field.GetValue(false)
  • Field.GetValue(false, false)
  • Field.GetValue(false, true)

A way to get around the bug would be to immediately call field.GetValue(true, false) if you have made any of the previously listed calls. For example:

// does the field have a value?
bool hasValue = field.HasValue;

// fix bug 368493. 
field.GetValue(true, false);

This bug has been acknowledged by Sitecore and logged as #368493.

 

A common practice in all of my Sitecore sites is to have some sort of content fallback. What this means is that a field's value can come from somewhere other than the field itself, the source item (if it is a clone), or its standard values.

Content fallback is an excellent way to increase editor productivity and reduce content redundancy! Here are the three most common scenarios I run into with every project.

Ancestor Inheritance

One of the more common scenarios for ancestor inheritance is for things like the text that is to show up in the <title> tag of the HTML document. It is SEO best practice to have a unique title for every page. However, in some sites where there are thousands of pages, having an editor give each page a title may be unrealistic. The general practice we take with the sites we do is that if the "Title" field in null then we should use the value of the nearest set ancestor. This allows an editor to set the title at the 'home' node and guarantee that every page in the site will at least have something set for the <title> tag. This concept can be used for many different scenarios in almost any site!

Lateral Fallback

This is a fairly common technique where you may want a "MenuTitle" field to specify the text used in an <a> tag when a link to the item is being generated in a menu. However, in the event there is no "MenuTitle" then we should expect to see the value of the "Title" field.

Default Fallback

This type of fallback I typically use with Lateral Fallback. Furthering our Lateral Fallback example, lets suppose that we don't have a value for "MenuTitle" or the "Title" fields. In this case we simply want to have a value with the name of the item. In the event the item is renamed we should show the current name, not the name used at create time.

There are typically two places where this content fallback logic would live. If the site is using some sort of 'content model' framework such as Custom Item GeneratorCorePoint.DomainObjects or Glass Mapper then it would make sense to put the logic there. However, without such a framework the logic would be forced to live in the presentation layer. There are a few problems with these approaches.

  1. The fallback value isn't obvious to the editors. It doesn't show up in the content editor and they must know there is magic at hand at render time.
  2. Using the Page Editor can become (more) cumbersome.
  3. The fallback value is not readily available via standard API calls. The biggest issue is typically that the value isn't indexed for searching.
  4. Low level caching of the values doesn't happen. Caching is only available at the HTML level.

When Alex Shyba released his language fallback module I immediately envisioned a similar paradigm used for my content fallback scenarios! In my (not so) free time I was able to come up with the newly released Field Fallback Shared Source Module! This approach had one huge benefit and that is the editorial team would be able to see the 'fallback value' right there in the content editor! Furthering this it also had the fallback value in a cache thereby eliminating the need to calculate the fallback value multiple times.

The Field Fallback module will handle the three scenarios above and also provides for a fully pluggable architecture (pipeline based) to handle any other fallback scenarios you may need. This include language fallback! Part of the release includes a port of Alex Shyba's language fallback logic!

You can grab it from the Shared Source repository here - http://trac.sitecore.net/FieldFallback

I am scheduled to present this topic and demonstrate the module in an upcoming Sitecore Users Virtual Group. (After that date I will have the video here)