2015-02-24 61 views
1

我知道有一个SortOrder字段。但是,在我看来,这个字段很多时候都是空的,直到您开始实际移动列表中的内容项目为止。然后,如果您有一个物品清单,并将其中的一些物品移动,它们将被分配一个SortOrder值,但其他物品在SortOrder字段中仍然没有值。Sitecore如何对内容编辑器树中的项目进行排序?

我找不出来。我正在尝试编写一种算法,以便可以按照在内容编辑器中排序的方式对网页上的项目进行排序。

编辑: 以下是来自Sitecore.Kernel的代码,用于比较两个项目。从我在这里可以告诉它它首先尝试使用排序顺序字段。如果这些相同,则使用名称字段。但是,如果其中一个排序顺序值是一个数字,而其中一个排序顺序值是空白,那么我在这段代码中会发生什么呢?它是否将空白排序顺序字段视为数字零?

/// <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); 
} 

回答

4

默认的子项目排序顺序是按字母顺序排列的。如果在父项目上设置子项目排序,则实际上将使用要使用的算法填写父项目的“子项目排序”字段。如果您不更改子项目排序,并且移动子树中的单个项目并因此“中断”默认的alpha排序,它将为该树的该轴内的所有项目设置SortOrder值。

为了测试这个:

  1. 为您的根目录下创建一个新的项目,打开标准字段
  2. 创建子项用字母,例如a,b,c,d,e,f
  3. 看看每个字母项目上的“SortOrder”,它们都是空白的。
  4. 现在将d移到c之上,顺序将变为:a,b,d,c,e,f,其中SortOrder值分别为100,200,300,400,500和600。

当您上下移动项目时,增量会变小,因为它只尝试更改某些排序顺序,而不是全部。

用于比较项目的默认算法在Sitecore.Data.Comparers.ItemComparer类中。

+0

呵呵。是的,这就是我认为它应该起作用的原因。我已经看到奇怪的地方,我会移动列表中的单个项目,只有少数项目会有SortOrder值,其他项目仍然是空白的。也许我看到的东西。 – 2015-02-24 16:22:59

+0

这是一种混乱的方法。清除所有SortOrder值。 Sitecore将恢复为按字母顺序显示。现在进入并手动设置单个项目的SortOrder值(如您的示例中的d),使其类似于700.它将d移动到列表的末尾。现在点击b选择它,然后点击向上箭头将它向上移动到列表顶部。它会将b的排序顺序设置为0,并保持其余的不变。所以现在你有这种奇怪的情况是两个项目(b和d)在他们的SortOrder字段中有值,其他没有任何值。 – 2015-02-24 16:43:51

+1

我不能为我的生活找出Sitecore在这种情况下使用的排序算法来排序项目,当他们中的一些具有排序顺序值而另一些没有。 – 2015-02-24 16:44:42

1

排序并不像您发现的那样直截了当。根据父母的排序规则,项目将以不同的方式显示。一些排序选项也有二次排序。

例如,缺省值使用排序顺序字段,但如果值为空白或与列表中的另一个元素相同,则执行辅助字母排序。

无论如何设置,您都不需要尝试模仿内容编辑器中使用的算法。如果您调用Item API,默认情况下,当您检索父项的子项时,它将应用适当的排序。只是不要对结果应用任何顺序,并且孩子返回的顺序应与您在“内容编辑器”中看到的顺序相匹配。通过这种方式,可以确保基于内容编辑器中的配置返回子项,因为树的不同区域可能会应用不同的排序。这就是说,如果你使用的是IQueryable搜索界面,你很可能会想要实现一些你可以预测的东西。在这种情况下,您应该根据对最终用户有意义的内容进行排序,而不是编辑界面中作者的操作。

+0

好吧,我的内容树中有一个文件夹,其中有一些项目代表在页面上显示的列表中的选项。我的希望是我可以简单地让作者在内容编辑器中订购这些项目,然后按照相同的顺序显示在页面上。我发现大约90%的时间都可以工作。我使用Glass Mapper来检索项目而不是项目API。正如我在上面的评论中所述,有一种方法可以让某些项目具有SortOrder值,而有些项目没有任何价值。 – 2015-02-25 13:45:51

+0

当你有上述情况时,我不知道Sitecore如何计算如何订购物品。如果我删除了自己在代码中的任何排序,并且只使用Glass Mapper检索的项目,则它们的排列顺序与内容编辑器中的顺序不同。对我来说,这在某种程度上感觉就像一个Sitecore错误。感觉Sitecore不应该允许文件夹中的某些项目具有SortOrder值,有些项目不是。或者如果它确实允许,那么它应该有一些可以理解的方式来确定项目的顺序。 – 2015-02-25 13:48:09

1

我想我想通了。感谢Mark Ursino指引我朝着正确的方向发展。我开始浏览实际的Sitecore.Kernel代码,看看它在做什么。如果您遇到某个文件夹中的某些项目具有SortOrder值而其中一些项目没有的情况,则Sitecore会使用Web.Config中的一个名为“DefaultSortOrderValue”的设置,并将它分配给每个没有SortOrder值的项目并对它们进行分类。现在它是有道理的!这就是为什么我看到一种情况,Sitecore会将该项目放在列表顶部的0处,并将列表底部为700的项目和所有没有Sortorder值的项目放在列表中。

所以我需要在我的代码中进行排序的方式是相同的,我可以让我的项目始终与它们在内容编辑器中显示的顺序相同。谢谢!

相关问题