2016-04-18 19 views
2

HEJ傢伙顯示項目與Sitecore的數據提供

我有一個相當大的問題,我一直在負責創建從SOLR數據庫提取庫存單位自定義數據提供程序(SKU)的成Sitecore的,而沒有實際用項目填充數據庫。

我創建了一個數據提供者,它成功地從SOLR數據庫中的「創建」,在Sitecore的項目中提取數據,通過使用下面的代碼:

public class SkuDataProvider : DataProvider, ISkuDataProvider 
{ 
     private readonly string _targetDatabaseName = "master"; 
     private readonly string _idTablePrefix = "Skus"; 
     private readonly ID _skuTemplateId = new ID("{F806B403-BDAF-4C60-959D-E706A82FC1DC}"); 
     private readonly ID _skuRootTemplateId = new ID("{9767BC47-0A95-40E9-A2DE-3766FF241411}"); 

     private readonly IEnumerable<SkuItemInfo> _skus; 

     public SkuDataProvider(/*IProductPageService productPageService*/) 
     { 
      _skus = new MockDataForSkuDataProvider().GetSimpleSkuCollection(); 
     } 


     public override ItemDefinition GetItemDefinition(ID itemId, CallContext context) 
     { 
      Assert.ArgumentNotNull(itemId, "itemID"); 

      // Retrieve the sku id from Sitecore's IDTable 
      var skuId = GetSkuIdFromIdTable(itemId); 

      if (!string.IsNullOrEmpty(skuId)) 
      { 
       // Retrieve the sku data from the skus collection 
       var sku = _skus.FirstOrDefault(o => o.SkuId == skuId); 

       if (sku != null) 
       { 
        // Ensure the sku item name is valid for the Sitecore content tree 
        var itemName = ItemUtil.ProposeValidItemName($"{sku.SkuId}_{sku.Name}"); 

        // Return a Sitecore item definition for the sku using the sku template 
        return new ItemDefinition(itemId, itemName, ID.Parse(_skuTemplateId), ID.Null); 
       } 
      } 

      return null; 
     } 

     private string GetSkuIdFromIdTable(ID itemId) 
     { 
      var idTableEntries = IDTable.GetKeys(_idTablePrefix, itemId); 

      if (idTableEntries.Any()) 
       return idTableEntries[0].Key.ToString(); 

      return null; 
     } 

     public override IDList GetChildIDs(ItemDefinition parentItem, CallContext context) 
     { 
      if (CanProcessParent(parentItem.ID)) 
      { 
       var itemIdList = new IDList(); 

       foreach (var sku in _skus) 
       { 
        var skuId = sku.SkuId; 

        // Retrieve the Sitecore item ID mapped to his sku 
        IDTableEntry mappedId = IDTable.GetID(_idTablePrefix, skuId) ?? 
              IDTable.GetNewID(_idTablePrefix, skuId, parentItem.ID); 

        itemIdList.Add(mappedId.ID); 
       } 

       context.DataManager.Database.Caches.DataCache.Clear(); 

       return itemIdList; 
      } 

      return base.GetChildIDs(parentItem, context); 
     } 


     private bool CanProcessParent(ID id) 
     { 
      var item = Factory.GetDatabase(_targetDatabaseName).Items[id]; 

      bool canProcess = item.Paths.IsContentItem && item.TemplateID == _skuRootTemplateId && item.ID == new ID("{F37753A0-BC79-4FF7-B975-A8F142AACD76}"); 

      return canProcess; 
     } 


     public override ID GetParentID(ItemDefinition itemDefinition, CallContext context) 
     { 
      var idTableEntries = IDTable.GetKeys(_idTablePrefix, itemDefinition.ID); 

      if (idTableEntries.Any()) 
      { 
       return idTableEntries.First().ParentID; 
      } 

      return base.GetParentID(itemDefinition, context); 
     } 


     public override FieldList GetItemFields(ItemDefinition itemDefinition, VersionUri version, CallContext context) 
     { 
      var fields = new FieldList(); 

      var idTableEntries = IDTable.GetKeys(_idTablePrefix, itemDefinition.ID); 

      if (idTableEntries.Any()) 
      { 
       if (context.DataManager.DataSource.ItemExists(itemDefinition.ID)) 
       { 
        ReflectionUtil.CallMethod(typeof(ItemCache), CacheManager.GetItemCache(context.DataManager.Database), "RemoveItem", true, true, new object[] { itemDefinition.ID }); 
       } 

       var template = TemplateManager.GetTemplate(_skuTemplateId, Factory.GetDatabase(_targetDatabaseName)); 

       if (template != null) 
       { 
        var skuId = GetSkuIdFromIdTable(itemDefinition.ID); 

        if (!string.IsNullOrEmpty(skuId)) 
        { 
         var sku = _skus.FirstOrDefault(o => o.SkuId == skuId); 

         if (sku != null) 
         { 
          foreach (var field in GetDataFields(template)) 
          { 
           fields.Add(field.ID, GetFieldValue(field, sku)); 
          } 
         } 
        } 
       } 
      } 

      return fields; 
     } 

     protected virtual IEnumerable<TemplateField> GetDataFields(Template template) 
     { 
      return template.GetFields().Where(ItemUtil.IsDataField); 
     } 

     private string GetFieldValue(TemplateField field, SkuItemInfo sku) 
     { 
      string fieldValue = string.Empty; 

      switch (field.Name) 
      { 
       case "Name": 
        fieldValue = sku.Name; 
        break; 
       case "SkuId": 
        fieldValue = sku.SkuId; 
        break; 
       default: 
        break; 
      } 
      return fieldValue; 
     } 
    } 
} 

訪問Sitecore的後端時出現的問題,所有項目都以層級方式出現在存儲桶項目下方。

我已經檢查Root項目是否設置了一個存儲桶並且使用的模板是可存儲的。 此外,當手動插入後端時,該項目正確插入存儲桶中。

有沒有人有我的想法,如何解決這個問題?

問候 尼古拉

回答

1

您需要設置Is Bucketable標誌的模板項目,而不是模板項目本身的標準值。

此外,項目獲取「bucketed」的方式是通過事件創建或保存項目。 Sitecore然後創建桶文件夾來存儲項目。在您的情況下,因爲您有虛擬物品,您將需要通過數據提供者處理它們的路徑。

如果您只是希望它們隱藏在標準存儲桶中,那麼我會建議在您的SKU根文件夾下創建一個存儲桶文件夾,並將該項目用作所有SKU虛擬物件的父項目。這樣,bucket文件夾將被sitecore隱藏,您將獲得與標準存儲桶相同的視圖。

這是使用模板: Bucket Folder Template

+0

我在我的職位沒有明確的錯誤,但它被設置在標準值。 :) 但我會嘗試桶文件夾的想法! – MrNantir

+1

看來我達到了預期的效果。感謝您的快速和簡單的回答:) – MrNantir

+0

您將如何處理數據提供程序中虛擬物品的物品路徑? – user1501050