2013-01-07 18 views
10

Abbiamo una soluzione multi-sito (Sito 1 e Sito 2), e devo essere in grado di determinare se un oggetto per il quale stiamo ottenendo l'URL (in LinkProvider, che è personalizzato) appartiene al contesto attuale sito (Sitecore.Context.Site) o fa parte di un sito diverso. C'è un buon modo per farlo?Come scoprire con quale sito Sitecore è associato un articolo?

Fondamentalmente, dobbiamo solo essere in grado di scoprire a quale sito l'articolo è associato. Possiamo fare il confronto tra quel valore e l'attuale sito di contesto.

+3

Un articolo può "appartenere" a più siti. Non penso che ci sarà una soluzione generica per questo, dipenderà dalla tua configurazione. – Bryan

+1

Sì, definire "appartiene a". Se intendi "è al di sotto dell'attuale percorso root del sito di contesto", la risposta di Ruud è ciò di cui hai bisogno. –

risposta

8

Suggerisco di creare un metodo di estensione per la classe Articolo che restituisce un oggetto SiteInfo contenente la definizione del sito a cui appartiene.

Purtroppo non ho il mio laptop qui con tutto il mio codice, in modo ho scritto in Visual Studio e fatto in modo che a costruire, ma sono abbastanza sicuro che funziona:

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

Così ora puoi chiamare il metodo GetSite() su tutti gli oggetti Item e recuperare lo SiteInfo per quell'elemento. È possibile utilizzare che per verificare se corrisponde il vostro Sitecore.Context.Site, ad esempio facendo:

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

EDIT: Ho solo pensato che si potrebbe anche farlo più breve, come questo:

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

in modo da scegliere Qualunque cosa ti piace di più :)

+0

Questo funziona solo se esiste un solo sito di contesto per elemento, che non è il caso se si dispone di più domini che puntano allo stesso articolo locale (ad esempio, per supportare domini specifici per paese/lingua). Ci sono in realtà diversi problemi nella domanda: 1) questo elemento fa parte dell'albero del contenuto attuale del sito e 2) se no, a quale sito appartiene. –

+3

L'ordine delle definizioni del sito in web.config è importante in quanto determina come vengono risolti gli elementi che "appartengono" a più di un sito. –

+1

se si dispone di più siti, alcuni dei quali hanno percorsi più brevi che sono in conflitto con altri, è possibile eseguire OrderByDescending su RootPath.Length in modo da abbinare prima il sito più specifico. – BraveNewMath

0

Questo è quello che uso per la nostra soluzione multisito.

FormatWith è solo un helper per string.Format.

public static SiteInfo GetSite(this Item item) 
    { 
     List<SiteInfo> siteInfoList = Factory.GetSiteInfoList(); 
     SiteInfo site = null; 
     foreach (SiteInfo siteInfo in siteInfoList) 
     { 
      var siteFullPath = "{0}{1}".FormatWith(siteInfo.RootPath, siteInfo.StartItem); 
      if (string.IsNullOrWhiteSpace(siteFullPath)) 
      { 
       continue; 
      } 
      if (item.Paths.FullPath.StartsWith(siteFullPath, StringComparison.InvariantCultureIgnoreCase)) 
      { 
       site = siteInfo; 
       break; 
      } 
     } 
     return site; 
    } 
5

ho upvoted risposta di Ruud van Falier poi dopo alcuni round di test ho capito che funziona solo in determinati scenari. Impossibile annullare il voto, quindi ho fatto qualche modifica al codice qui:

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

Quindi il problema era che altri built-in siti normalmente hanno percorsi più brevi come "/ Sitecore/contenuti", che abbinerà con il vostro percorso del contenuto prima che raggiunga la configurazione del sito reale. Quindi questo codice sta cercando di restituire la migliore corrispondenza.

+0

'public statico SiteInfo GetSite (questo articolo articolo) { 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

Scavalo @BraveNewMath –

0

E per evitare le dipendenze, per scopi di unit test, ho creato un metodo per estrarre queste informazioni dal web.config direttamente:

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

Credo che questa sia la soluzione migliore 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

Grazie per questo snippet di codice, che potrebbe fornire un aiuto limitato e immediato. A [spiegazione corretta] (https://meta.stackexchange.com/q/114762/349538) migliorerebbe notevolmente il suo valore a lungo termine, mostrando perché questa è una buona soluzione al problema e renderebbe più utile ai futuri lettori con altre domande simili. Per favore [modifica] la tua risposta per aggiungere qualche spiegazione, incluse le ipotesi che hai fatto. –

Problemi correlati