2013-01-07 11 views
10

Mamy rozwiązanie wielozakładowe (witryna 1 i witryna 2) i muszę mieć możliwość określenia, czy element, do którego uzyskujemy adres URL (w usłudze LinkProvider, który jest niestandardowy) należy do bieżącego kontekstu witryna (Sitecore.Context.Site) lub jest częścią innej witryny. Czy jest to dobry sposób na zrobienie tego?Jak się dowiedzieć, z którą witryną Sitecore element jest powiązany?

Po prostu musimy być w stanie dowiedzieć się, do której witryny jest powiązany dany produkt. Możemy dokonać porównania między tą wartością a bieżącą witryną kontekstową.

+3

Produkt może "należeć" do wielu witryn. Nie sądzę, aby istniało ogólne rozwiązanie tego problemu, będzie ono zależeć od konfiguracji. – Bryan

+1

Tak, zdefiniuj "należy do". Jeśli masz na myśli "znajduje się pod bieżącą ścieżką do głównego kontekstu witryny", odpowiedź Ruuda jest tym, czego potrzebujesz. –

Odpowiedz

8

Proponuję utworzyć metodę rozszerzenia dla klasy Item, która zwraca obiekt SiteInfo zawierający definicję witryny, do której należy.

Niestety nie mam tu mój laptop z całego kodu, więc po prostu wpisane w Visual Studio i upewnić się, że budowę, ale jestem pewien, że działa:

public static class Extensions 
{ 
    public static Sitecore.Web.SiteInfo GetSite(this Sitecore.Data.Items.Item item) 
    { 
     var siteInfoList = Sitecore.Configuration.Factory.GetSiteInfoList(); 

     foreach (Sitecore.Web.SiteInfo siteInfo in siteInfoList) 
     { 
      if (item.Paths.FullPath.StartsWith(siteInfo.RootPath)) 
      { 
       return siteInfo; 
      } 
     } 

     return null; 
    } 
} 

Więc teraz możesz wywołać metodę GetSite() na wszystkich obiektach Item i pobrać SiteInfo dla tego przedmiotu. można używać, aby sprawdzić, czy pasuje do Twojego Sitecore.Context.Site, na przykład wykonując:

SiteInfo siteInfo = itemYouNeedToCheck.GetSite(); 
bool isContextSiteItem = Sitecore.Context.Site.SiteInfo.Equals(siteInfo); 

EDIT: Po prostu pomyślałem, że można też zrobić to krótsze, tak:

public static Sitecore.Web.SiteInfo GetSite(this Sitecore.Data.Items.Item itemYouNeedToCheck) 
{ 
    return Sitecore.Configuration.Factory.GetSiteInfoList() 
     .FirstOrDefault(x => itemYouNeedToCheck.Paths.FullPath.StartsWith(x.RootPath)); 
} 

Więc odebrać cokolwiek lubisz najbardziej :)

+0

Działa to tylko wtedy, gdy istnieje tylko jedna możliwa witryna kontekstowa na element, co nie ma miejsca, jeśli masz wiele domen wskazujących ten sam element główny (np. W celu obsługi domen specyficznych dla kraju/języka). W pytaniu są rzeczywiście różne problemy: 1) jest częścią obecnego drzewa zawartości witryny, a 2) jeśli nie, do której strony należy. –

+3

Kolejność definicji witryny w web.config jest ważna, gdyż dyktuje jak przedmioty, które „należą” do więcej niż jednej stronie są rozwiązane. –

+1

jeśli masz wiele witryn, z których niektóre mają krótsze ścieżki, które są sprzeczne z innymi, można OrderByDescending na RootPath.Length tak dopasować najbardziej specyficzne miejsce pierwsze. – BraveNewMath

0

To jest to, czego używam w naszym rozwiązaniu wielopunktowym.

FormatWith jest tylko pomocnikiem dla string.Format.

5

Wziąłem pod uwagę odpowiedź Ruuda van Faliera, po kilku rundach testów zdałem sobie sprawę, że działa tylko w pewnych sytuacjach. Nie udało się anulować głosowanie, więc zrobiłem jakąś modyfikację kod tutaj:

public static SiteInfo GetSite(this Item item) 
    { 
     var siteInfoList = Sitecore.Configuration.Factory.GetSiteInfoList(); 

     SiteInfo currentSiteinfo = null; 
     var matchLength = 0; 
     foreach (var siteInfo in siteInfoList) 
     { 
      if (item.Paths.FullPath.StartsWith(siteInfo.RootPath, StringComparison.OrdinalIgnoreCase) && siteInfo.RootPath.Length > matchLength) 
      { 
       matchLength = siteInfo.RootPath.Length; 
       currentSiteinfo = siteInfo; 
      } 
     } 

     return currentSiteinfo; 
    } 

więc problem był ten drugi wbudowany w miejscach normalnie mają krótsze drogi jak „/ Sitecore/content”, który będzie pasował do Twojego ścieżka zawartości, zanim osiągnie rzeczywistą konfigurację witryny. Ten kod próbuje zwrócić najlepszy wynik.

+0

'public static SiteInfo GetSite (ten przedmiot) { return Factory.GetSiteInfoList(). OrderByDescending (i => i.RootPath) .FirstOrDefault (x => item.Paths.FullPath.StartsWith (x.RootPath)); } ' – jrap

4
/// <summary> 
/// Get the site info from the <see cref="SiteContextFactory"/> based on the item's path. 
/// </summary> 
/// <param name="item">The item.</param> 
/// <returns>The <see cref="SiteInfo"/>.</returns> 
public static SiteInfo GetSiteInfo(this Item item) 
{ 
    return SiteContextFactory.Sites 
    .Where(s => !string.IsNullOrWhiteSpace(s.RootPath) && item.Paths.Path.StartsWith(s.RootPath, StringComparison.OrdinalIgnoreCase)) 
    .OrderByDescending(s => s.RootPath.Length) 
    .FirstOrDefault(); 
} 
+1

wbijam to @BraveNewMath –

0

i uniknąć zależności celach testowych jednostki, I utworzeniu metody w celu uzyskania tych informacji z pliku web.config bezpośrednio:

public static SiteInfoVM GetSiteInfoForPath(string itemPath) 
    { 
     var siteInfos = GetSiteInfoFromXml(); 

     return siteInfos 
      .Where(i => i.RootPath != "/sitecore/content" && itemPath.StartsWith(i.RootPath)) 
      //.Dump("All Matches") 
      .OrderByDescending(i => i.RootPath.Length).FirstOrDefault(); 
    } 

    static List<SiteInfoVM> GetSiteInfoFromXml() 
    { 

     XmlNode sitesNode = Sitecore.Configuration.ConfigReader.GetConfigNode("sites");//.Dump(); 
     var result = sitesNode.Cast<XmlNode>() 
     .Where(xn => xn.Attributes != null && xn.Attributes["rootPath"] != null 
     //&& (xn.Attributes["targetHostName"]!=null || xn.Attributes["name"].Value) 
     ) 
     .Select(xn => new { 
      Name = xn.Attributes["name"].Value, 
      RootPath = xn.Attributes["rootPath"].Value, 
      StartItem = xn.Attributes["startItem"].Value, 
      Language = xn.Attributes["language"] != null ? xn.Attributes["language"].Value : null, 
      TargetHostName = (xn.Attributes["targetHostName"] != null) ? xn.Attributes["targetHostName"].Value : null, 
      SiteXml = xn.OuterXml 
     }) 
     .Select(x => new SiteInfoVM(x.Name, x.RootPath, x.StartItem, x.Language, x.TargetHostName, x.SiteXml)) 
     .ToList(); 
     return result; 
    } 


    public class SiteInfoVM 
    { 

     public SiteInfoVM(string name, string rootPath, string startItem, string lang, string tgtHostName, string siteXml) 
     { 
      Name = name; 
      TargetHostName = tgtHostName; 
      RootPath = rootPath; 
      StartItem = startItem; 
      Language = lang; 
      SiteXml = siteXml; 


     } 
     public string Name { get; set; } 
     public string RootPath { get; set; } 
     public string StartItem { get; set; } 
     public string Language { get; set; } 
     public string TargetHostName { get;set; } 
     public string SiteXml { get; set; } 
    } 
-1

Wierzę, że to jest lepsze rozwiązanie http://firebreaksice.com/sitecore-context-site-resolution/

public static Sitecore.Web.SiteInfo GetSite(Sitecore.Data.Items.Item item) 
{ 
    var siteInfoList = Sitecore.Configuration.Factory.GetSiteInfoList(); 

    foreach (Sitecore.Web.SiteInfo siteInfo in siteInfoList) 
    { 
     var homePage = Sitecore.Context.Database.GetItem(siteInfo.RootPath + siteInfo.StartItem); 

     if (homePage != null && homePage.Axes.IsAncestorOf(item)) 
     { 
      return siteInfo; 
     } 
    } 
    return null; 
} 
+0

Dziękuję za ten fragment kodu, który może zapewnić pewne ograniczone, natychmiastowa pomoc. [właściwe wyjaśnienie] (https://meta.stackexchange.com/q/114762/349538) znacznie poprawiłoby jej długoterminowej wartości pokazując, dlaczego jest to dobre rozwiązanie problemu i może sprawić, że bardziej użyteczną do przyszłych czytelników z innymi, podobnymi pytaniami. Proszę [edytuj] odpowiedź na pytanie: , aby dodać wyjaśnienie, w tym przyjęte założenia. –

Powiązane problemy