Sitecore SPEAK Gotcha #2 The StackOverflow exception when ID is part of your Entity

Using Sitecore Services Client is fun, but when the unexpected occurs it can be quite confusing to work out what is going on.

Last night was one of these cases; my code was constantly throwing a StackOverflow exception and I couldn’t understand why. There was no real indication and expected break points in code were not being hit.

After hours of scratching my head I decided to go back to basics with the Entities that I was using in part of my solution. It turns out that one of my Entities had an ID property which was causing the issue.

This is an example of the Entity I was using:

public class Template : Sitecore.Services.Core.Model.EntityIdentity
 {
 public string itemId
 {
 get { return base.Id; }
 set { base.Id = value; }
 }

 public string TemplateName { get; set; }

 private ID _templateId = new ID();
 public ID TemplateID
 {
 get { return _templateId; }
 set
 {
 _templateId = value;
 }
 }
 private List<string> _fields = new List<string>();
 public List<string> Fields
 {
 get { return _fields; }
 set { _fields = value; }
 }
 }

The majority of the Entity above is simple enough, however having an ID property will cause a StackOverflow exception (so it seams). What was confusing though is that when invoking my service manually through a browser I did not experience any issues, only when invoking through a SPEAK application (through the fetchEntity function). Fiddler also confirmed that there was a difference between manual invocation and via the fetchEntity function.

What was going on? A SPEAK application (and related JavaScript) needs to be able to understand the information that is contained in your entities prior to using them (e.g. for client side validation). Currently, only the following simple types are supported:

  • string
  • bool
  • int
  • float
  • double
  • long
  • DateTime
  • Enum

(this is taken from the documentation at: https://sdn.sitecore.net/upload/sitecore7/75/developer%27s_guide_to_sitecore.services.client_sc75-a4.pdf)

What I’m going to take a look at is to see if there is a way of extending this to include other types (such as ID). For now, I’m simply using strings for ID’s until I can find an alternative solution 🙂

Sitecore SPEAK Gotcha #1 Populating itemId from your Entity

Just a quick post regarding a small gotcha I experienced with Sitecore Services Client.

Recently whilst setting up some services with SPEAK and Sitecore Services Client I experienced the following error when calling the “fetchEntities” from my SPEAK app to return information from my Template Service (a service that I’m creating to teach myself Sitecore Services Client and SPEAK – full blog post to appear soon regarding its creation)

Below is the JavaScript I’m using to retrieve my information:


var result = templateService.fetchEntity(selectedItem).execute().then(function (template) {
var title = template.Fields;
});

When inspecting this in the console of Chrome I was noticing the following:

404 (Entity does not exist)

This seemed a little strange, as the entity was present and my code was certainly creating and returning the data (debugging verified this). So why was this appearing?

Well, it appears that in your Entity, you need to populate “itemId” field in the base class (Sitecore.Services.Core.Model.EntityIdentity), otherwise the 404 error will occur.

Huge thanks to Mike Robbins @Sobek1985 for this 🙂

Applying Datasources to Sitecore Controls – The Easy Way

Following on from my post The Importance of Datasources I thought I’d show a neat little trick to ensure Datasources are bound to all Sitecore controls within any component/Sublayout that you create.

The approach I normally take to binding Datasources is to firstly inherit from a base class, and get the base class to expose a DataSourceItem property which returns the Datasource, or if one isn’t provided return the context item:

public Item DataSourceItem
{
    get
    {
        // Ensure at the very least Context Item is returned as a fallback
        Item returnItem = Sitecore.Context.Item;

        if (Sublayout != null)
        {
            string dataSourceString = Sublayout.DataSource;

            if (!string.IsNullOrEmpty(dataSourceString))
            {
                Item dbItem = Sitecore.Context.Database.GetItem(dataSourceString);

                if (dbItem != null)
                {
                    returnItem = dbItem;
                }
            }
        }

        return returnItem;
    }
}

(You can get the full base class I use from GitHub at https://github.com/jamielittle/SitecoreToolbox/blob/master/Sitecore.Toolbox/Sublayout/SublayoutBase.cs)

Then in my Component, bind the DatasourceItem to each Sitecore control that is contained within the component:


scTextField1.Item = DatasourceItem;

scTextField2.Item = DatasourceItem;

scImage1.Item = DatasourceItem;

Doing this in every component is a bit of a chore, especially when there are many Sitecore controls contained within the component. So I’ve created a function that will do this for us:


        public void BindDatasourceToSitecoreControls()
        {
            BindDatasourceToSitecoreControls(DataSourceItem);
        }

        public void BindDatasourceToSitecoreControls(Item dataSource)
        {
            if (Controls.Count > 0)
            {
                BindControls(this.Controls, dataSource);
            }
        }

        private void BindControls(ControlCollection controls, Item dataSource)
        {
            foreach (Control control in controls)
            {
                if (control is FieldControl)
                {
                    var fieldControl = control as FieldControl;
                    fieldControl.Item = dataSource;
                }

                if (control is FieldRenderer)
                {
                    var fieldRenderer = control as FieldRenderer;
                    fieldRenderer.Item = dataSource;
                }

                if (control.Controls.Count > 0)
                {
                    BindControls(control.Controls, dataSource);
                }
            }
        }

The BindControls function can be used to recursively traverse through any control collection and when it encounters a control which is of type FieldRenderer or FieldControl (which covers most of the Sitecore controls) it will assign the Datasource that you pass into the function.

There are also two additional functions

  • BindDatasourceToSitecoreContrls() – This function will simply bind the Datasource that is available to any Sitecore controls it finds. This is part of my SublayoutBase.cs base class (as part of the Sitecore Toolbox) and inherits from System.Web.UI.Control so utilises the control collection that is available. You can simply call BindDatasourceToSitecoreControls() from you Page_Load() when inheriting from SubloayoutBase.
  • BingDatasourceToSitecoreControls(Item dataSource) – This function override can be used if a specific Item is used as a Datasource

The above code is included in the SitecoreToolbox on GitHub:

https://github.com/jamielittle/SitecoreToolbox/tree/master/Sitecore.Toolbox

Hopes this helps when using Datasources.

Feel free to leave a comment if you have any questions 🙂

The Importance of Datasources

Over the years I have been involved in my fair share of “rescue” projects with Sitecore with the most common of issues being projects that do not adhere to the standards and best practices of Sitecore.

One of the biggest complaints I hear is the lack of complete Page Editor functionality and components not being testable. Sitecore themselves make it their business to push personalisation and this is one of the key selling points of the Sitecore platform and goes some way to justify the license costs. That said, the lack of adhering to best practices may work for some (ensuring the quickest turnaround time) however later on down the line this will unravel when clients wish to utilise “out of the box functionality” that Sitecore provides.

Also, I’ve heard worrying phrases such as:

They haven’t been shown that or told to use that feature of the Page Editor

or

They don’t or shouldnt use it like that

or even worse

I can’t see this ever needing to be tested or personalised

Two things I normally advise with in these circumstances:

  1. Never make assumptions on how a client with use the Page Editor. Whilst they may not wish to use its functionality now, they may wish to utilise it in the future – so why make these assumptions in the first place?
  2. There may be a future possibility that the client will employ someone who is well versed in Sitecore who wants to begin to utilise the out of the box features of the Page Editor. Wouldn’t it be embarrassing if they clicked the “Set Associated Content” button in the Page Editor on a component and were unable to create a new Datasource to see what it would look like with different labels? (this is built-in, every component should support this)

Fortunately the above can easily be addressed by ensuring that Sitecore’s best practices of using Datasources for almost everything (unless its Presentation Configuration, in which you may wish to consider Parameter Templates). In fact, I rigidly adhere to Datasources unless there is a good and valid case not to.

Common Problems with components:

  • Not abiding to a Datasource at all – Components who get all of their data from the Context Item (which will be the Page). Bear in mind that the Context Item will be the Page – which normally means that there is a lack of separation of Site Information and Page Content.
  • Hard wired Datasources – the data for a component is pulled in via a link directly to a Content Item. The issue with this is obvious, if the Datasource is recreated it will be assigned a new ID, hence the code that utilises it will need to be updated.
  • Not restricting Datasources – Allowing “any” item to be bound as a Datasource that does not contain the correct fields that are expected by the component. Whilst the component might work, the Content Editor could break a component by assigning an inappropriate Datasource.
  • Inappropriate usage of Datasources – Using Dataosources that contain “too much information” i.e. a Global Item that is bound to the majority of components, or a component that takes data from multiple content items – making if difficult to personalise the component as DMS is only capable of taking control over the Datasource (remember, we should be in the habit of allowing ALL components to be personalised – it’s no extra work!)

To address the above, I normally create a base class that contains a DataSourceItem property. This is then bound to the Item property of all the Sitecore controls on the page. This means that the component doesn’t care where there Datasource is being set as that’s not the concern of the Component. All the component should care about is that it is “given” data by Sitecore.

I have an example of a base class that can be used on GitHub in my Sitecore Toolbox Project:

https://github.com/jamielittle/SitecoreToolbox/blob/master/Sitecore.Toolbox/Sublayout/SublayoutBase.cs

When creating the Sublayout in Sitecore I always ensure that each component is coupled with its related Datasource Template (it’s a good idea to create the Datasource Template first to prevent bouncing from Sublayouts to Templates to create the Datasource Template and back to Sublayouts to assign it to the Component). This ensures that the data that is passed to a component is known by the component (and developer) and prevents the scenario where the component has to make a call to a different Content Item in Sitecore for its information (i.e. the component needing to be knowledgable about your IA).

Coupled with this, it is important to specify Datasource Location fields when creating the Sublayout in Sitecore. This will ensure that all Datasources that are suitable for this Component are located in one location improving the experience for the Content Editor.When these fields are provided, Sitecore will not allow an inappropriate Datasource to be bound to a component and the Datasource Location ensures that all Datasource Items are stored in a logical place in Sitecore.

If there is a situation where data is required from different nodes of the content tree, these can be provided via Droplinks in the Datasource Template o those locations – again, this ensures there is clarity and understanding of the data that the component requires to function. This also improves component testability as if the client wishes to perform any AB/MV testing, this will be possible by creating alternative Datasources.

Even if the Content Editor does not want to utilise MV testing, there are other ways to test a component. I’ve had a client want to create two pages with the same component on both, but each component pointing to two different Datasources. This method was required to show an example of a page that contains different content to the CEO to get approval on which content to use. This did require a small amount of rework (as the component pointed to the Context Item for its data) but after a little rework my client was very pleased with the capability and really started to “get” the power of Sitecore.

If the above is adhered to, this will go a long way to ensure that your components

So, just to recap

  • Always use Dataources, they are very easy to use, and will save you rework in the future when you client wants to begin to utiilise other functionality of Sitecore (Testability/DMS etc.)
  • Adopt “Assumption-less Design” i.e. Never assume anything in the Component. Always get you data from the Datasource (unless there is a very good reason not to – fortunately there are not many of these!)
  • If you are finding that the Datasource is too large, it may be an indication that your component needs to be broken down into sub components.

Remember, as Developers it is our responsibility to design components that can be reused whenever required and to have the power to be testable and “personalisable” (is that a word?).

By taking this approach, you are not only ensuring that your clients gets Value for Money and can justify purchasing a Sitecore license, but also helps ensure the longevity of the components that you create 🙂

Feel free to leave any comments/questions 🙂

Dynamic Menu’s in Sitecore Part 2

Welcome to Part 2 of setting up Dynamic Menu’s in Sitecore. In this post, I will quickly demonstrate how easy it is to utilise the power. Of DMS to alter what is displayed in site navigation and empower users to make choices on which content is displayed.

If you want to have a look at how a dynamic menu can be structured, please read Part 1. This post will follow on from there.

So, just to recap, we now have a navigation Item, which is simply an instance of a Navigation link on your site and a Navigation Collection, which consists of a collection of Navigation Items. The Navigation Collection can then be used as a Datasource Navigation Component.

Let’s choose the simple scenario that you want to have a different navigation displayed for a user that has successfully logged into out site.

First let’s assume that we have the following Navigation Items defined:

Navigation Items

Now lets two navigation collections, one for not logged in and one for logged in:

Navigation Collections

The “Not Logged In” collection will contain links to the “Log in” and “Sign Up” Navigation Items:

Not Logged In Collection

The “Logged In” collection will contain links to the “My profile” and “Log out” Navigation Items”

Logged In Collection

As these two collections are designed to be used as Datasources, we need to establish which Datasource to pass to the Navigation component and what drives this decision. This can be achieved by setting up a Rule Condition

Then, set up a Rule Condition which will detect whether the user has logged in:

{
public class AuthenticatedRuleCondition<T> : TrueCondition<T> where T : RuleContext
{
protected override bool Execute(T ruleContext)
{
Assert.ArgumentNotNull(ruleContext, "ruleContext");

if (Sitecore.Context.IsLoggedIn)
return true;

return false;
}
}

We also need to register this new Rule Condition in Sitecore. This can be done by inserting a new Conditional Rendering into the following location (replacing <rule-condition-class> the fully qualified namespace/class name and <dll> with the DLL in which the rule resides):

rule

We can now use this Rule Condition to help decide which navigation to display. To do this, “Personalise” the component in the Presentation Layer and make use of this Rule Condition. Essentially what I am saying below is if my Rule Condition is true (i.e. the user is logged in), use a different Datasource to what is the default (the default is Not Logged In Datasource)

personalise

… and that’s it! It really is that simple. Sitecore already has a rule for authentication “when the current user is anonymous” (or the reverse of that rule) however the above can be easily modified to check for presence of a Role:

if (Sitecore.Context.User.IsInRole(&quot;extranet\\membership&quot;);)

{

// Perform some additional checks if necessary

return true; }

… or any other condition necessary.

When all is published, you will notice that Sitecore provides a different Datasource to the Navigation component when the user is logged in (or when the condition is met).

Hope this helps 🙂

Resetting Standard Fields for all Items of a given template

A very useful feature in Sitecore is the ability to reset fields on an item to their value as defined in Standard Values. This is great, but what if you want to reset fields on many items of the same template?

There doesn’t (yet) appear to be a feature in Sitecore to do this, so I wrote a simple function that performs this task.

Basically, you will need to perform a search to get all your items first, then pass in your list of items and a list of the field names you wish to reset on each item.


public void ResetFields(List<Item> items, List<string> fields)
{
    if (items.Any() && fields.Any())
    {
        foreach (Item item in items)
        {
           ResetFieldsOnItem(item, fields);
        }
    }
}

public void ResetFieldsOnItem(Item item, List<string> fields)
{
    if (item != null && fields.Any())
    {
        using (new Sitecore.Security.Accounts.UserSwitcher(ELEVATED_USER_ACCOUNT, true))
        {
            item.Editing.BeginEdit();

            foreach (string field in fields)
            {
                item.Fields[field].Reset();
            }

            item.Editing.EndEdit();
        }
    }
}

I might create a SPEAK app so that when you click on a template, a button will appear to provide this functionality in the Ribbon – That would be a nice addition 🙂

Dynamic Menu’s in Sitecore – Part 1

One of the components that I appear to have rebuilt time and time again over the years is a Menu component. Whether it be a Header, Footer, Side-bar Navigation – whichever you choose, the underlying structure is generally the same with the only difference being the way the menu is rendered.

This post will highlight the approach I generally take these days, an approach that appears to suit the majority of clients and also one that allows them to be in control of what links are displayed.

This post is split into two parts:

  • Part 1 – Designing a flexible Dynamic Menu system
  • Part 2 – Utilising DMS to drive which menu content is displayed

Part 1 – Designing a flexible Dynamic Menu system

In the past, I’ve encountered scenarios where the perfect menu system has been created which is dynamically generated based upon either fields in the content (e.g. “show in menu” field or generated based upon hierarchy). Then the client has a requirement to add something different into the menu that you need to create a special case for. This can sometimes (depending on the design) result in hard coding specific menu items in order to adhere to project deadlines. Nobody really wants to be doing this!

We’ve all built menu systems, hundreds of times, many different ways. This post discusses the approach and structure of a navigation component that I begin with (and then extend the system based upon customer requirements).

Getting around the above scenarios is relatively simple insofar as you can empower the user to generated their own menu and structure which obviously can be advised by IA or business requirements. This post will show you how.

Firstly, what is a menu anyway? Well, in its simplest form it’s a collection of Navigation Items whereas each Navigation Item can be represented at its basic level by a Title and the Navigation Link. So there’s our first Data Template. The Navigation Item itself:

Navigation Item Template

A Navigation Item is pretty useless in itself without being involved in a navigation Collection (unless of course you want to use it by itself somewhere on your site, which is perfectly acceptable) Then, we can group these into a Navigation Collection by defining a Navigation Collection template as below:

Navigation Links Template

Now that we have our templates structure in place, we can begin to put together our menu structure.

To do this I normally create two folders; one called Navigation Collections and the other called Navigation Items. Then, I set the Insert Options on each folder so that only the relevant content item can be inserted (e.g. Navigation Collection in the Navigation Collections folder and Navigation Item in the Navigation Items folder).

The Navigation Items will contain each navigation item that can be used anywhere on your site and the Navigation Collections can contain a collection of navigation items e.g. header navigation or footer navigation

The benefits of this are:

  • Navigation items can be reused in different navigation collections therefore changing the link in the item will change all usages of the item
  • For multilingual sites, navigation collections can differ per language if required.
  • Navigation collections can be created and managed for different scenarios e.g. A collection to display when you are not logged in and a collection for when you are.

For your Navigation component, you can use the appropriate navigation collection as the Datasource for the component. Don’t forget, the component is completely unaware where it is being used, all it is designed to do is to render information provided to it via its Datasource.

Hopefully that is straight forward and makes sense. Don’t forget, you could extend this by adding a relevant image to the Navigation Item or any other data you feel necessary. Also, you may wish to create alternative types of Navigation Items (such as Drop Down Navigation Item) to cater for different styles of navigation.

In Part 2, I will discuss how you can use DMS Rules to change the navigation depending on the type of user that is logged in.

If you would like to see some an example component that can utilise the Navigation Collections, let me know and I’ll put some together 🙂

Which Sitecore Index to use?

I was asked an interesting question the other day:

Why are my components not working in the Page Editor?

This puzzled me for a bit, the Page Editor was not preventing editing of the content, however the content was not being saved back into Sitecore. However, if the content was modified directly in the Content Editor, everything was fine.

So, what was going on?

Upon closer inspection of the code, it appeared that a the Sitecore ContentSearch was being used to pull content from the Index – but the index being used was “sitecore_web_index”.


ISearchIndex searchIndex = Sitecore.ContentSearch.ContentSearchManager.GetIndex(&quot;sitecore_web_index&quot;);

When this happens, creating a SearchContext, performing a search and calling GetItem() on a SearchResultItem will pull the item out of the Web database. This is fine, however as the items are coming from the Web database, this will not play nicely with the Page Editor.

A “quick ‘n’ dirty” method of getting around this is to look at the Context database to see whether you should be using the Master index or Web index. Below is a static helper to decide which index you should be looking at:

public static string GetIndex()
{
    // TODO - Find a way of getting the database associated with the Datasource
    switch (Sitecore.Context.Database.Name)
    {
        case (&quot;master&quot;):
            return &quot;sitecore_master_index&quot;;
        default:
            return &quot;sitecore_web_index&quot;;
    }
}

Then, simply use this static function in your code instead of naming the index directly:

ISearchIndex searchIndex = Sitecore.ContentSearch.ContentSearchManager.GetIndex(SitecoreJim.Utilities.Index.GetIndex());

Yes, this is quick and dirty – just wanted to get this out there to help others, however you get the concept 🙂

Upon doing a quick google search, I also found this post by The Grumpy Coder which discusses the same thing.

Hope this helps someone!