/// <summary> /// Generates url element /// </summary> /// <param name="url"></param> /// <param name="item"></param> /// <param name="sitemapSiteConfiguration"></param> /// <param name="xml"></param> protected virtual void GenerateUrlElement(String url, Item item, SitemapSiteConfiguration sitemapSiteConfiguration, XmlTextWriter xml) { sitemapSiteConfiguration.ItemsCount++; xml.WriteStartElement("url"); xml.WriteElementString("loc", url); if (item != null) { var lastModified = item.Statistics.Updated.ToString("yyyy-MM-ddThh:mm:sszzz"); xml.WriteElementString("lastmod", lastModified); String changeFrequency = sitemapSiteConfiguration.GetChangeFrequency(item); if (changeFrequency != String.Empty) { xml.WriteElementString("changefreq", changeFrequency); } String priority = sitemapSiteConfiguration.GetPriority(item); if (priority != String.Empty) { xml.WriteElementString("priority", priority); } } xml.WriteEndElement(); }
private bool MatchesTemplates(SitemapSiteConfiguration sitemapSiteConfiguration, Item item, Dictionary <Guid, bool> templateCache) { var templateId = item.TemplateID.Guid; if (templateCache.ContainsKey(templateId)) { return(templateCache[templateId]); } bool matchesTemplate; if (sitemapSiteConfiguration.IncludedTemplates.Contains(templateId)) { // matches the allowed templates matchesTemplate = true; } else { // slow - need local caching var baseTemplates = TemplateHelper.GetBaseTemplates(item); matchesTemplate = sitemapSiteConfiguration.IncludedBaseTemplates.Any(guid => baseTemplates.Contains(guid)); } templateCache.Add(templateId, matchesTemplate); return(matchesTemplate); }
/// <summary> /// Processes all items in site under root path /// </summary> /// <param name="items">List of Items</param> /// <param name="sitemapSiteConfiguration">Current sitemap configuration</param> /// <param name="options">Url Options</param> public List <UrlElement> ProcessItems(List <Item> items, SitemapSiteConfiguration sitemapSiteConfiguration, UrlOptions options) { var urlElements = new List <UrlElement>(); if (sitemapSiteConfiguration == null) { return(null); } Sitecore.Context.SetActiveSite(sitemapSiteConfiguration.Site.Name); foreach (Item item in items) { if (item.Versions.Count > 0) { if (IsIncluded(item, sitemapSiteConfiguration)) { sitemapSiteConfiguration.ItemsCount++; string url = LinkManager.GetItemUrl(item, options); if (string.IsNullOrEmpty(url)) { continue; } url = DynamicSitemapHelper.EnsureHttpPrefix(url, sitemapSiteConfiguration.ForceHttps); if (!String.IsNullOrEmpty(sitemapSiteConfiguration.ServerHost)) { url = DynamicSitemapHelper.ReplaceHost(url, sitemapSiteConfiguration.ServerHost); } if (string.IsNullOrEmpty(url)) { continue; } urlElements.Add( new UrlElement() { Location = url, LastModification = item.Statistics.Updated, ChangeFrequency = sitemapSiteConfiguration.GetChangeFrequency(item), Priority = sitemapSiteConfiguration.GetPriority(item) }); } } } if (sitemapSiteConfiguration.ItemsProcessor != null) { var urlItems = sitemapSiteConfiguration.ItemsProcessor.ProcessItems(sitemapSiteConfiguration); urlItems.AddRange(urlItems); } return(urlElements); }
/// <summary> /// Checks if Item can be included in sitemap /// </summary> /// <param name="item">Item</param> /// <param name="sitemapSiteConfiguration"></param> /// <param name="templateCache"></param> /// <param name="isDataSourceItem">Is item used only in wildcard</param> /// <returns>true if included</returns> protected bool IsIncluded(Item item, SitemapSiteConfiguration sitemapSiteConfiguration, Dictionary <Guid, bool> templateCache, bool isDataSourceItem = false) { return(sitemapSiteConfiguration.ExcludedItems.All(x => x != item.ID.ToString()) && this.MatchesTemplates(sitemapSiteConfiguration, item, templateCache) && !sitemapSiteConfiguration.ExcludedItemPaths.Any(x => item.Paths.FullPath.StartsWith(x.Paths.FullPath) && item.Paths.FullPath.Equals(x.Paths.FullPath)) && (item.Paths.FullPath.StartsWith(sitemapSiteConfiguration.RootItem.Paths.FullPath) || item.Paths.FullPath.Equals(sitemapSiteConfiguration.RootItem.Paths.FullPath) || isDataSourceItem)); }
/// <summary> /// Checks if Item can be included in sitemap /// </summary> /// <param name="item">Item</param> /// <param name="isDataSourceItem">Is item used only in wildcard</param> /// <returns>true if included</returns> protected virtual bool IsIncluded(Item item, SitemapSiteConfiguration sitemapSiteConfiguration, bool isDataSourceItem = false) { var result = false; if (!sitemapSiteConfiguration.ExcludedItems.Any(x => x == item.ID.ToString()) && sitemapSiteConfiguration.IncludedTemplates.Contains(item.TemplateID.ToString()) && !sitemapSiteConfiguration.ExcludedItemPaths.Any(x => item.Paths.FullPath.ToLower().StartsWith(x.Paths.FullPath.ToLower()) || item.Paths.FullPath.ToLower().Equals(x.Paths.FullPath.ToLower())) && (item.Paths.FullPath.StartsWith(sitemapSiteConfiguration.RootItem.Paths.FullPath) || item.Paths.FullPath.Equals(sitemapSiteConfiguration.RootItem.Paths.FullPath) || isDataSourceItem)) // - datasource items can be out of root item { result = true; } return(result); }
/// <summary> /// Processes all items in site under root path /// </summary> /// <param name="items">List of Items</param> /// <param name="sitemapSiteConfiguration">Current sitemap configuration</param> /// <param name="options">Url Options</param> public List <UrlElement> ProcessItems(List <Item> items, SitemapSiteConfiguration sitemapSiteConfiguration, UrlOptions options) { var urlElements = new List <UrlElement>(); foreach (var item in items) { if (item.Versions.Count > 0) { //if (DynamicSitemapHelper.IsWildcard(item)) //{ // PrepareDynamicItems(item, sitemapSiteConfiguration, xml); //} if (IsIncluded(item, sitemapSiteConfiguration)) { sitemapSiteConfiguration.ItemsCount++; var url = LinkManager.GetItemUrl(item, options); url = DynamicSitemapHelper.EnsureHttpPrefix(url, sitemapSiteConfiguration.ForceHttps); if (!String.IsNullOrEmpty(sitemapSiteConfiguration.ServerHost)) { url = DynamicSitemapHelper.ReplaceHost(url, sitemapSiteConfiguration.ServerHost); } urlElements.Add( new UrlElement() { Location = url, LastModification = item.Statistics.Updated, ChangeFrequency = sitemapSiteConfiguration.GetChangeFrequency(item), Priority = sitemapSiteConfiguration.GetPriority(item) }); } } } if (sitemapSiteConfiguration.ItemsProcessor != null) { var urlItems = sitemapSiteConfiguration.ItemsProcessor.ProcessItems(sitemapSiteConfiguration); urlItems.AddRange(urlItems); } return(urlElements); }
/// <summary> /// Builds sitemap structure /// </summary> /// <param name="sitemapSiteConfiguration">Sitemap site configuration</param> /// <param name="elements"></param> /// <returns>Sitemap content as string</returns> public virtual String BuildSitemap(SitemapSiteConfiguration sitemapSiteConfiguration, List <UrlElement> elements) { var result = String.Empty; //var options = GetUrlOptions(); var encoding = Encoding.UTF8; StringWriterWithEncoding stringWriter = new StringWriterWithEncoding(encoding); // - Creating the XML Header - var xml = new XmlTextWriter(stringWriter); xml.WriteStartDocument(); xml.WriteStartElement("urlset", DynamicSitemapConfiguration.XmlnsTpl); try { //options.Site = sitemapSiteConfiguration.Site; //options.Language = sitemapSiteConfiguration.Language; foreach (var urlElement in elements) { WriteUrlElement(urlElement, xml); } } catch (Exception exc) { Sitecore.Diagnostics.Log.Error(String.Format(Messages.ExceptionWhileBuilding, sitemapSiteConfiguration.Site.Name, exc.Message, exc.StackTrace), this); } finally { xml.WriteEndElement(); xml.WriteEndDocument(); xml.Flush(); result = stringWriter.ToString(); Sitecore.Diagnostics.Log.Info(String.Format(Messages.SitemapBuildSuccess, sitemapSiteConfiguration), this); } return(result); }
/// <summary> /// Builds sitemap structure /// </summary> /// <param name="sitemapSiteConfiguration">Sitemap site configuration</param> /// <returns>Sitemap content</returns> public String BuildSitemap(SitemapSiteConfiguration sitemapSiteConfiguration) { var result = String.Empty; var options = this.GetUrlOptions(); var encoding = Encoding.UTF8; StringWriterWithEncoding stringWriter = new StringWriterWithEncoding(encoding); // - Creating the XML Header - var xml = new XmlTextWriter(stringWriter); xml.WriteStartDocument(); xml.WriteStartElement("urlset", DynamicSitemapConfiguration.XmlnsTpl); try { options.Site = sitemapSiteConfiguration.Site; options.Language = sitemapSiteConfiguration.Language; List <Item> items = this.GetItems(sitemapSiteConfiguration.Site.RootPath, sitemapSiteConfiguration.Language); this.ProcessItems(items, sitemapSiteConfiguration, options, xml); } catch (Exception exc) { Diagnostics.Log.Error(String.Format(Messages.ExceptionWhileBuilding, sitemapSiteConfiguration.Site.Name, exc.Message, exc.StackTrace), this); } finally { xml.WriteEndElement(); xml.WriteEndDocument(); xml.Flush(); result = stringWriter.ToString(); Diagnostics.Log.Info(String.Format(Messages.SitemapBuidSuccess, sitemapSiteConfiguration), this); } return(result); }
/// <summary> /// Prepares dynamic items - items accessed by wildcard /// </summary> /// <param name="wildcardItem">Wildcard Item</param> /// <param name="sitemapSiteConfiguration">Sitemap site configuration</param> /// <param name="xml">XmlTextWriter object</param> protected virtual void PrepareDynamicItems(Item wildcardItem, SitemapSiteConfiguration sitemapSiteConfiguration, XmlTextWriter xml) { var dynamicRoute = sitemapSiteConfiguration.DynamicRoutes.SingleOrDefault(x => x["Dynamic Item"] == wildcardItem.ID.ToString()); if (dynamicRoute != null) { var datasource = Database.GetItem(dynamicRoute["Data Source"]); if (datasource != null && datasource.HasChildren) { UrlOptions options = GetUrlOptions(); options.Site = sitemapSiteConfiguration.Site; var dynamicItemActualUrl = LinkManager.GetItemUrl(wildcardItem, options); foreach (var item in datasource.Children.ToList()) { if (item.Versions.Count > 0 && IsIncluded(item, sitemapSiteConfiguration, true)) { var lastSegment = item.Name; lastSegment = options.LowercaseUrls ? lastSegment.ToLower() : lastSegment; var url = dynamicItemActualUrl .Replace(",-w-,", lastSegment) .Replace("*", lastSegment); url = DynamicSitemapHelper.EnsureHttpPrefix(url, sitemapSiteConfiguration.ForceHttps); if (!String.IsNullOrEmpty(sitemapSiteConfiguration.ServerHost)) { url = DynamicSitemapHelper.ReplaceHost(url, sitemapSiteConfiguration.ServerHost); } GenerateUrlElement(url, item, sitemapSiteConfiguration, xml); } } } } }
/// <summary> /// Processes all items in site under root path /// </summary> /// <param name="items">List of Items</param> /// <param name="sitemapSiteConfiguration">Current sitemap configuration</param> /// <param name="options">Url Options</param> /// <param name="xml">Xml Text Writer object</param> public void ProcessItems(List <Item> items, SitemapSiteConfiguration sitemapSiteConfiguration, UrlOptions options, XmlTextWriter xml) { var templateCache = new Dictionary <Guid, bool>(); foreach (var item in items) { if (item.Versions.Count > 0) { if (DynamicSitemapHelper.IsWildcard(item)) { this.PrepareDynamicItems(item, sitemapSiteConfiguration, xml, templateCache); } else if (this.IsIncluded(item, sitemapSiteConfiguration, templateCache)) { var url = LinkManager.GetItemUrl(item, options); url = DynamicSitemapHelper.EnsureHttpPrefix(url, sitemapSiteConfiguration.ForceHttps); if (!String.IsNullOrEmpty(sitemapSiteConfiguration.ServerHost)) { url = DynamicSitemapHelper.ReplaceHost(url, sitemapSiteConfiguration.ServerHost); } this.GenerateUrlElement(url, item, sitemapSiteConfiguration, xml); } } } if (sitemapSiteConfiguration.ItemsProcessor != null) { var urlItems = sitemapSiteConfiguration.ItemsProcessor.ProcessItems(sitemapSiteConfiguration); foreach (var urlItem in urlItems) { this.GenerateUrlElement(urlItem, sitemapSiteConfiguration, xml); } } }
/// <summary> /// Generates url element /// </summary> /// <param name="urlElement"></param> /// <param name="sitemapSiteConfiguration"></param> /// <param name="xml"></param> protected virtual void GenerateUrlElement(UrlElement urlElement, SitemapSiteConfiguration sitemapSiteConfiguration, XmlTextWriter xml) { sitemapSiteConfiguration.ItemsCount++; xml.WriteStartElement("url"); xml.WriteElementString("loc", urlElement.Location); var lastModified = urlElement.LastModification.ToString("yyyy-MM-ddThh:mm:sszzz"); xml.WriteElementString("lastmod", lastModified); if (urlElement.ChangeFrequency != String.Empty) { xml.WriteElementString("changefreq", urlElement.ChangeFrequency); } if (urlElement.Priority != String.Empty) { xml.WriteElementString("priority", urlElement.Priority); } xml.WriteEndElement(); }
/// <summary> /// Method that will process your items /// </summary> /// <param name="sitemapSiteConfiguration">Sitemap site configuration to which items will be added</param> /// <returns>List of your items</returns> public List <UrlElement> ProcessItems(SitemapSiteConfiguration sitemapSiteConfiguration) { var items = new List <UrlElement>(); // - Let's check for specific language - if (sitemapSiteConfiguration.LanguageName == "en") { // - Add your own elements packed into object of UrlElement class - items.Add(new UrlElement { Location = "http://mysite.com/some-custom-static-page.html", Priority = "0.7", LastModification = new DateTime(2016, 03, 01), ChangeFrequency = "yearly" }); } // - Return collected items - return(items); }
/// <summary> /// Reads configurations from Sitecore /// </summary> public virtual void ReadConfigurations() { ReadGlobalSitecoreConfiguration(); SiteConfigurations = new List <SitemapSiteConfiguration>(); if (SitecoreConfiguration.DisableSitemap) { Sitecore.Diagnostics.Log.Warn(Messages.SitemapDisabled, this); return; } Item[] configurationItems = Database.SelectItems(DynamicSitemapConfiguration.SitemapConfigurationItemPath + DynamicSitemapConfiguration.SitemapConfigurationSitesFolderName + "/*[@@templateid='" + TemplateIds.SiteConfigurationTemplateId + "']"); if (!configurationItems.Any()) { Sitecore.Diagnostics.Log.Warn(Messages.NoConfigurations, this); return; } if (!SitecoreConfiguration.ProcessedLanguages.Any()) { Sitecore.Diagnostics.Log.Warn(Messages.NoProcessedLanguages, this); return; } foreach (var configurationItem in configurationItems) { var languageItems = configurationItem.Languages.Where(x => SitecoreConfiguration.ProcessedLanguages.Contains(x.Name)).ToList(); foreach (var languageItem in languageItems) { var item = configurationItem.Database.GetItem(configurationItem.ID, languageItem); if (item.Versions.Count > 0) { var site = configurationItem.Name.ToLower(); var sitemapSiteConfiguration = new SitemapSiteConfiguration(item); sitemapSiteConfiguration.SitemapFileName = sitemapSiteConfiguration.SitemapFileName != String.Empty ? sitemapSiteConfiguration.SitemapFileName : String.Format(_sitemapFileNameFormat, site, languageItem.Name.ToLower()); sitemapSiteConfiguration.SitemapFilePath = DynamicSitemapConfiguration.SitemapConfigurationOutputFolder + "/" + sitemapSiteConfiguration.SitemapFileName; // - Load ItemsProcessor - if (!String.IsNullOrWhiteSpace(sitemapSiteConfiguration.ItemsProcessorTypeToLoad)) { var loader = new ItemsProcessorLoader(); var itemsProcessor = loader.Load(sitemapSiteConfiguration.ItemsProcessorTypeToLoad); if (itemsProcessor != null) { sitemapSiteConfiguration.ItemsProcessor = itemsProcessor; } else { Sitecore.Diagnostics.Log.Warn(String.Format(Messages.CannotLoadItemsProcessor, sitemapSiteConfiguration.ItemsProcessorTypeToLoad), this); } } SiteConfigurations.Add(sitemapSiteConfiguration); } } } SitecoreConfiguration.MainSiteConfiguration = SiteConfigurations.FirstOrDefault(x => String.Equals(x.Site.Name, SitecoreConfiguration.MainSiteConfigurationItem.Name, StringComparison.CurrentCultureIgnoreCase)); if (SitecoreConfiguration.MainSiteConfiguration == null) { Sitecore.Diagnostics.Log.Warn("No main site configuration", this); } SitemapIndex = new SitemapIndexConfiguration { ServerHost = SitecoreConfiguration.MainSiteConfiguration != null ? SitecoreConfiguration.MainSiteConfiguration.ServerHost : SiteConfigurations.FirstOrDefault()?.ServerHost, FileName = _sitemapIndexFileName }; }
/// <summary> /// Reads configurations from Sitecore /// </summary> public void ReadConfigurations() { this.ReadGlobalSitecoreConfiguration(); Item[] configurationItems = this.Database.SelectItems(DynamicSitemapConfiguration.SitemapConfigurationItemPath + DynamicSitemapConfiguration.SitemapConfigurationSitesFolderName + "/*[@@templateid='" + TemplateIds.SiteConfigurationTemplateId + "']"); if (configurationItems.Count() == 0) { Diagnostics.Log.Warn(Messages.NoConfigurations, this); return; } this.SiteConfigurations = new List <SitemapSiteConfiguration>(); foreach (var configurationItem in configurationItems) { var languageItems = configurationItem.Languages.Where(x => this.SitecoreConfiguration.ProcessedLanguages.Contains(x.Name)).ToList(); foreach (var languageItem in languageItems) { var item = configurationItem.Database.GetItem(configurationItem.ID, languageItem); if (item.Versions.Count > 0) { var site = configurationItem.Name.ToLower(); var sitemapSiteConfiguration = new SitemapSiteConfiguration(item); sitemapSiteConfiguration.SitemapFileName = sitemapSiteConfiguration.SitemapFileName != String.Empty ? sitemapSiteConfiguration.SitemapFileName : String.Format(this._sitemapFileNameFormat, site, languageItem.Name.ToLower()); sitemapSiteConfiguration.SitemapFilePath = DynamicSitemapConfiguration.SitemapConfigurationOutputFolder + "/" + sitemapSiteConfiguration.SitemapFileName; // - Load ItemsProcessor - if (!String.IsNullOrWhiteSpace(sitemapSiteConfiguration.ItemsProcessorTypeToLoad)) { var loader = new ItemsProcessorLoader(); var itemsProcessor = loader.Load(sitemapSiteConfiguration.ItemsProcessorTypeToLoad); if (itemsProcessor != null) { sitemapSiteConfiguration.ItemsProcessor = itemsProcessor; } else { Diagnostics.Log.Warn(String.Format(Messages.CannotLoadItemsProcessor, sitemapSiteConfiguration.ItemsProcessorTypeToLoad), this); } } this.SiteConfigurations.Add(sitemapSiteConfiguration); } } } this.SitecoreConfiguration.MainSiteConfiguration = this.SiteConfigurations.FirstOrDefault(x => x.Site.Name.ToLower() == this.SitecoreConfiguration.MainSiteConfigurationItem.Name.ToLower()); this.SitemapIndex = new SitemapIndexConfiguration(); var siteConfiguration = this.SitecoreConfiguration.MainSiteConfiguration ?? this.SiteConfigurations.FirstOrDefault(); if (siteConfiguration != null) { this.SitemapIndex.ServerHost = siteConfiguration.ServerHost; this.SitemapIndex.ForceHttps = siteConfiguration.ForceHttps; this.SitemapIndex.TargetHostName = siteConfiguration.TargetHost; } this.SitemapIndex.FileName = this._sitemapIndexFileName; }