all things Sitecore related

Coded field datasources in Sitecore

I was really thrilled to see that Sitecore 7 will support coded datsources. This is a feature we already implemented at our company in earlier sitecore versions (kudos for the idea for my colleague and fellow MVP Remco van Toor).

Coded datasources are very powerful and are frequently used in our company. For example in our latest project we use the sitecore enterprise ecommerce module. Customers are located in the ecommerce database but we had the need to render them as a datasource in a sitecore field.

Sitecore 6
Unfortunately this version doesn’t support coded datasources out of the box, so to achieve the same as in future release sitecore 7 we have to develop a custom field type.

Register a custom field in FieldType config:
<fieldType name=”Coded source list” type=”IQuality.Web.Fields.CodedSourceList,IQuality.Web” />

To use the field on a template we configure it as follow:

template

We select the custom field type coded source list. We have to select a source and the source is the reference to our code. We do that by selecting a source item which is based on our custom template tDatasource.

This template looks like this:

tdatasource

In this template we can configure:

  • Assembly
  • Type
  • Method
  • Arguments (optional)

So next we need two classes for the implementation: the field definition and the datasource class for the field implementation. First of all the custom field:



namespace IQuality.Web.Fields
{
public class CodedSourceList : MultilistEx
{
private IDictionary<string, string> mSourceItems = null;

public CodedSourceList()
{
this.Class = "scContentControl";
base.Activation = true;
}

public new string Source { get; set; }

public new string ItemID { get; set; }

private IDictionary<string, string> SourceItems
{
get
{
if (mSourceItems == null)
{
IDictionary<string, string> lRet = new Dictionary<string, string>();
if (!string.IsNullOrEmpty(Source))
{
Item lCurrItem = Sitecore.Context.ContentDatabase.GetItem(this.ItemID);

Item lSourceItem = Sitecore.Context.ContentDatabase.GetItem(Source);

if (lSourceItem != null && lSourceItem.TemplateID == TDataSource.TEMPLATE_ID)
{
TDataSource lDsataSource = TDataSource.CreateTypedWrapper<TDataSource>(lSourceItem);
Type lSourceType = Type.GetType(string.Format("{0}, {1}", lDsataSource.Type, lDsataSource.Assembly));
if (lSourceType != null)
{
object lSource = Activator.CreateInstance(lSourceType, null);
MethodInfo lSourceMethod = lSourceType.GetMethod(lDsataSource.Method);
if (lSource != null && lSourceMethod != null && lSourceMethod.ReturnType.Equals(typeof(Dictionary<string, string>)))
{
return (Dictionary<string, string>)lSourceMethod.Invoke(lSource, null);
}
}
}

foreach (Item lItem in LookupSources.GetItems(lCurrItem, Source))
{
lRet.Add(lItem.ID.ToString(), lItem.ToString());
}
}
mSourceItems = lRet;
}
return mSourceItems;
}
}

protected override void DoRender(HtmlTextWriter output)
{
//here you can put your own custom rendering based on the MultilistEx rendering for example
}

protected override void OnLoad(EventArgs e)
{
Assert.ArgumentNotNull(e, "e");
base.OnLoad(e);
if (Sitecore.Context.ClientPage.IsEvent)
{
string str = Sitecore.Context.ClientPage.ClientRequest.Form[this.ID + "_value"];
if (str != null)
{
if (base.GetViewStateString("Value", string.Empty) != str)
{
this.SetModified();
}
base.SetViewStateString("Value", str);
}
}
}
}
}

So the main logic is in the sourceitems property (we user compiled domain model to create a type wrapper from tDatasource). In the property we use reflection to execute the method defined in tDatasource. We enforce the method to return an Dictionary<string, string> which we can use to render the field as a multilistex.

So the second class is the custom datasource for the field. I may look like this:



namespace IQuality.Common.Web.Fields
{
class CustomersSource
{

public Dictionary<string, string> GetData()
{
var lResult = new Dictionary<string, string>();
lResult.Add("{some sitecore ID}", "Customer 1");
lResult.Add("{some sitecore ID}", "Customer 2");
return lResult;
}
}
}

As a result in sitecore we see our customers in a custom field:
field with result from coded datasource

Sitecore 7
As said earlier sitecore 7 will support coded datasources out of the box. You can use your own coded datsources as the source for some (bucket) field types. To do this you have to implement an IDatasource interface. The interface looks like:


public interface IDataSource
{
// Methods
Item[] ListQuery(Item item);
}

About the Author

About the Author: I am working as a Team leader at IQuality Business Solutions B.V., specialized in solution development, with a strong focus on Sitecore. Although most of my time busy with developing, I am also making designs, give sitecore training and advise customers. I am Sitecore MVP since 2011. You can follow me on twitter: @rhlnieuwenhuis please also visit our company sitecore subsite on: getsmarterwithsitecore .

Subscribe

If you enjoyed this article, subscribe now to receive more just like it.

There Are 9 Brilliant Comments

Trackback URL | Comments RSS Feed

Sites That Link to this Post

  1. @BrruuD | March 26, 2013
  2. Mike Reynolds (@mike_i_reynolds) | March 26, 2013
  3. @jammykam | March 26, 2013
  4. regarding sitecore (@regardsitecore) | March 26, 2013
  5. Sitecore New Zealand (@sitecorenz) | March 27, 2013
  6. Marc Duiker (@marcduiker) | March 27, 2013
  7. @IQmarlon | March 27, 2013
  8. PowerShell Scripted datasources in Sitecore (Part 1) | Codality | April 19, 2013
  1. Alex Izotov says:

    Where can I get the example of creating TDataSource?

Post a Comment

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

Top