Reputation: 7340
I know that there is a SortOrder field. However it seems to me like that field is empty lots of times until you start actually moving content items around in the list. And then if you have a list of items and you move a few of them around, they will get assigned a SortOrder value, but other items will still have no value in the SortOrder field.
I can't figure it out. I am trying to write an algorithm so that I can sort items on the web page in the same way that they are ordered in the Content Editor.
EDIT: Here is the code from Sitecore.Kernel that compares two items. From what I can tell here it first tries to order using the Sortorder field. If those are equal, then it uses the Name field. But it is unclear to me what happens in this code if one of the sort order values is a number and one of the sort order values is blank. Does it treat a blank sort order field like the number zero?
/// <summary>
/// Compares the specified items.
///
/// </summary>
/// <param name="item1">Item1.</param><param name="item2">Item2.</param>
/// <returns/>
/// <contract><requires name="item1" condition="none"/><requires name="item2" condition="none"/></contract>
public int Compare(Item item1, Item item2)
{
if (item1 == null || item2 == null)
{
if (item1 == null && item2 == null)
return 0;
return item1 != null ? 1 : -1;
}
else
{
int sortorder1 = item1.Appearance.Sortorder;
int sortorder2 = item2.Appearance.Sortorder;
string name1 = item1.Name;
string name2 = item2.Name;
return ItemComparer.CompareItems(item1, item2, sortorder1, sortorder2, name1, name2);
}
}
/// <summary>
/// Compares the items.
///
/// </summary>
/// <param name="item1">The item1.</param><param name="item2">The item2.</param><param name="sort1">The sort1.</param><param name="sort2">The sort2.</param><param name="name1">The name1.</param><param name="name2">The name2.</param>
/// <returns/>
private static int CompareItems(Item item1, Item item2, int sort1, int sort2, string name1, string name2)
{
if (object.ReferenceEquals((object) item1, (object) item2))
return 0;
if (sort1 != sort2)
return sort1 - sort2;
if (name1.Length == 0 || name2.Length == 0)
return name1.CompareTo(name2);
if ((int) name1[0] == 95 && (int) name2[0] != 95)
return 1;
if ((int) name1[0] != 95 && (int) name2[0] == 95)
return -1;
else
return name1.CompareTo(name2);
}
Upvotes: 2
Views: 3173
Reputation: 7340
I think I figured it out. Thanks to Mark Ursino for pointing me in the right direction. I started looking through the actual Sitecore.Kernel code to see what it was doing. If you get to a situation where some of your items in a folder have a SortOrder value and some don't, then Sitecore uses a setting from Web.Config called "DefaultSortOrderValue" and assigns that to every item without a SortOrder value when it compares them and sorts them. Now it makes sense! That is why I was seeing a situation where Sitecore would put the item with a 0 at the top of the list and the item with 700 at the bottom of the list and all of the items with no Sortorder value in between.
So all I need to do in my code is sort the same way and I can get my items to always be in the same order as they appear in the Content Editor. Thanks!
Upvotes: 1
Reputation: 31435
The default sub-item sort order is alphabetical. If you set the sub-item sorting on the parent item, it will actually fill out the "Subitems Sorting" field on the parent with the algorithm to use. If you don't change the sub-item sorting and you move a single item within a sub-tree and therefore "break" the default alpha sort, it will set a SortOrder value on all of the items within that axis of the tree.
To test this:
As you move items up and down the increments get smaller as it tried to only change some of the sort orders and not all of them.
The default algorithm to compare items is in the Sitecore.Data.Comparers.ItemComparer
class.
Upvotes: 5
Reputation: 7994
Sorting is not exactly straight-forward, as you have discovered. Depending on the parent's rule for sorting, items will be displayed differently. Some of the sorting options also have secondary sorts.
For example, the default uses the sort order field, but does a secondary alphabetical sort if the values are blank or the same as another element in the list.
Regardless of the setting, you should not need to try to mimic the algorithm used in Content Editor. If you call the Item API, it will apply the appropriate sorting when you retrieve the children of the parent by default. Simply do not apply any ordering to the results, and the order the children are returned should match to what you see in Content Editor. In this way, you can ensure that children are returned based on the configuration in Content Editor, since different areas of the tree may have different sorting applied.
That being said, if you are using the IQueryable search interface, you'll most likely want to implement something that you can predict. In this case, you should be sorting based on what makes sense to the end user and not what the author is doing in the editing interface.
Upvotes: 2