/// <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);
        }
Beispiel #13
0
        /// <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;
        }