diff --git a/sample/SitemapifyUmbracoSample/App_Data/Umbraco.sdf b/sample/SitemapifyUmbracoSample/App_Data/Umbraco.sdf index 82a2ac5..9dec340 100644 Binary files a/sample/SitemapifyUmbracoSample/App_Data/Umbraco.sdf and b/sample/SitemapifyUmbracoSample/App_Data/Umbraco.sdf differ diff --git a/sample/SitemapifyUmbracoSample/Code/SitemapifyApplicationEventHandler.cs b/sample/SitemapifyUmbracoSample/Code/SitemapifyApplicationEventHandler.cs index 817604f..649552c 100644 --- a/sample/SitemapifyUmbracoSample/Code/SitemapifyApplicationEventHandler.cs +++ b/sample/SitemapifyUmbracoSample/Code/SitemapifyApplicationEventHandler.cs @@ -1,25 +1,23 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Xml.Linq; -using Sitemapify; -using Sitemapify.Providers; -using Sitemapify.Providers.Impl; +using Sitemapify.Config; using Sitemapify.Umbraco; -using Umbraco.Core; -using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix; +using Sitemapify.Umbraco.Events; namespace SitemapifyUmbracoSample.Code { - public class SitemapifyApplicationEventHandler : ApplicationEventHandler + public class MySitemapifyUmbracoContentProvider : SitemapifyUmbracoContentProvider { - protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + protected override Uri GetBaseUrl(Uri baseUri) { - Configure.With(config => config.UsingContentProvider(new SitemapifyUmbracoContentProvider())); + return new Uri("https://github.com/stormid/sitemapify", UriKind.Absolute); } + } - protected override bool ExecuteWhenApplicationNotConfigured { get; } = false; - protected override bool ExecuteWhenDatabaseNotConfigured { get; } = false; + public class SitemapifyApplicationEventHandler : AbstractSitemapifyApplicationEventHandler + { + protected override void ConfigureWith(ISitemapifyConfigurer configure) + { + configure.UsingContentProvider(new MySitemapifyUmbracoContentProvider()); + } } } \ No newline at end of file diff --git a/src/Sitemapify.Umbraco/Events/AbstractSitemapifyApplicationEventHandler.cs b/src/Sitemapify.Umbraco/Events/AbstractSitemapifyApplicationEventHandler.cs new file mode 100644 index 0000000..a32ae6f --- /dev/null +++ b/src/Sitemapify.Umbraco/Events/AbstractSitemapifyApplicationEventHandler.cs @@ -0,0 +1,31 @@ +using Sitemapify.Config; +using Umbraco.Core; + +namespace Sitemapify.Umbraco.Events +{ + public abstract class AbstractSitemapifyApplicationEventHandler : ApplicationEventHandler + { + protected sealed override void ApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + base.ApplicationInitialized(umbracoApplication, applicationContext); + } + + protected sealed override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + base.ApplicationStarted(umbracoApplication, applicationContext); + } + + protected sealed override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + Configure.With(ConfigureWith); + } + + protected virtual void ConfigureWith(ISitemapifyConfigurer configure) + { + configure.UsingContentProvider(new SitemapifyUmbracoContentProvider()); + } + + protected sealed override bool ExecuteWhenApplicationNotConfigured { get; } = false; + protected sealed override bool ExecuteWhenDatabaseNotConfigured { get; } = false; + } +} diff --git a/src/Sitemapify.Umbraco/Events/SitemapifyApplicationEventHandler.cs b/src/Sitemapify.Umbraco/Events/SitemapifyApplicationEventHandler.cs deleted file mode 100644 index e290bd0..0000000 --- a/src/Sitemapify.Umbraco/Events/SitemapifyApplicationEventHandler.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core; - -namespace Sitemapify.Umbraco.Events -{ - public class SitemapifyApplicationEventHandler : ApplicationEventHandler - { - protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) - { - Configure.With(config => config.UsingContentProvider(new SitemapifyUmbracoContentProvider())); - } - - protected override bool ExecuteWhenApplicationNotConfigured { get; } = false; - protected override bool ExecuteWhenDatabaseNotConfigured { get; } = false; - } -} diff --git a/src/Sitemapify.Umbraco/Sitemapify.Umbraco.csproj b/src/Sitemapify.Umbraco/Sitemapify.Umbraco.csproj index d4765da..88e171f 100644 --- a/src/Sitemapify.Umbraco/Sitemapify.Umbraco.csproj +++ b/src/Sitemapify.Umbraco/Sitemapify.Umbraco.csproj @@ -228,7 +228,7 @@ - + diff --git a/src/Sitemapify.Umbraco/SitemapifyUmbracoContentProvider.cs b/src/Sitemapify.Umbraco/SitemapifyUmbracoContentProvider.cs index 8eb7cd9..3145923 100644 --- a/src/Sitemapify.Umbraco/SitemapifyUmbracoContentProvider.cs +++ b/src/Sitemapify.Umbraco/SitemapifyUmbracoContentProvider.cs @@ -5,6 +5,7 @@ using System.Web; using Sitemapify.Models; using Sitemapify.Providers; +using Sitemapify.Providers.Impl; using Sitemapify.Umbraco.Config; using Sitemapify.Umbraco.Extensions; using Umbraco.Core; @@ -14,7 +15,7 @@ namespace Sitemapify.Umbraco { - public class SitemapifyUmbracoContentProvider : ISitemapContentProvider + public class SitemapifyUmbracoContentProvider : EmptySitemapContentProvider { private readonly ISitemapifyUmbracoContentProviderSettings _settings; @@ -31,32 +32,72 @@ protected UmbracoContext GetUmbracoContext() return UmbracoContext.EnsureContext(httpContextWrapper, ApplicationContext.Current, new WebSecurity(httpContextWrapper, ApplicationContext.Current)); } - public IEnumerable GetSitemapUrls() + public sealed override IEnumerable GetSitemapUrls(Uri baseUrl) { var ctx = GetUmbracoContext(); if (ctx != null) { - var home = FromContent(ctx); - return home - .DescendantSitemapNodes(_settings.ExcludedFromSitemapPropertyAlias, _settings.ExcludedChildrenFromSitemapPropertyAlias) - .Where(node => node.ItemType == PublishedItemType.Content) - .Select(CreateSitemapUrlForContent); + var root = FromContent(ctx); + if (root.ItemType != PublishedItemType.Content) + { + return Enumerable.Empty(); + } + + var overrideBaseUrl = GetBaseUrl(baseUrl); + if (overrideBaseUrl.IsAbsoluteUri) + { + return root + .DescendantSitemapNodes(_settings.ExcludedFromSitemapPropertyAlias, _settings.ExcludedChildrenFromSitemapPropertyAlias) + .Where(node => node.ItemType == PublishedItemType.Content) + .Select(content => CreateSitemapUrlForContent(content, overrideBaseUrl)); + } } return Enumerable.Empty(); } + /// + /// Must return an absolute uri, otherwise the sitemap will be returned blank + /// + /// + /// + protected virtual Uri GetBaseUrl(Uri baseUri) + { + return baseUri; + } + + /// + /// The content node from which the sitemap should start + /// + /// The Umbraco context + /// A content node, media nodes are not supported protected virtual IPublishedContent FromContent(UmbracoContext context) { return context.ContentCache.GetByRoute("/"); } - public virtual bool Cacheable { get; } = true; + public override bool Cacheable { get; } = true; - public virtual DateTime CacheUntil { get; } = DateTime.UtcNow.AddHours(1); + public override DateTime CacheUntil { get; } = DateTime.UtcNow.AddHours(1); - protected virtual SitemapUrl CreateSitemapUrlForContent(IPublishedContent content) + private static SitemapUrl CreateSitemapUrlForContent(IPublishedContent content, Uri authorityUri) { - return SitemapUrl.Create(content.UrlAbsolute(), content.UpdateDate); + var ub = new UriBuilder(authorityUri) + { + Path = content.Url() + }; + var absoluteUri = ub.Uri.ToString().TrimEnd("/"); + return SitemapUrl.Create(absoluteUri, content.UpdateDate); + + //var absoluteUri = content.UrlAbsolute(); + //if (!Uri.IsWellFormedUriString(absoluteUri, UriKind.Absolute)) + //{ + // var ub = new UriBuilder(authorityUri) + // { + // Path = content.Url() + // }; + // absoluteUri = ub.ToString().TrimEnd("/"); + //} + //return SitemapUrl.Create(absoluteUri, content.UpdateDate); } } } \ No newline at end of file diff --git a/src/Sitemapify/Builders/Impl/DefaultSitemapDocumentBuilder.cs b/src/Sitemapify/Builders/Impl/DefaultSitemapDocumentBuilder.cs index dd3d1f6..f6a8a59 100644 --- a/src/Sitemapify/Builders/Impl/DefaultSitemapDocumentBuilder.cs +++ b/src/Sitemapify/Builders/Impl/DefaultSitemapDocumentBuilder.cs @@ -27,6 +27,6 @@ public XDocument BuildSitemapXmlDocument(IEnumerable sitemapUrls) }; return new XDocument(new XDeclaration("1.0", "utf-8", "yes"), headerComments, new XElement(XName.Get("urlset", SitemapUrl.SitemapNs), elements)); - } + } } } \ No newline at end of file diff --git a/src/Sitemapify/Providers/ISitemapContentProvider.cs b/src/Sitemapify/Providers/ISitemapContentProvider.cs index 5fc8c52..9a34543 100644 --- a/src/Sitemapify/Providers/ISitemapContentProvider.cs +++ b/src/Sitemapify/Providers/ISitemapContentProvider.cs @@ -6,7 +6,7 @@ namespace Sitemapify.Providers { public interface ISitemapContentProvider { - IEnumerable GetSitemapUrls(); + IEnumerable GetSitemapUrls(Uri baseUrl); bool Cacheable { get; } DateTime CacheUntil { get; } } diff --git a/src/Sitemapify/Providers/Impl/EmptySitemapContentProvider.cs b/src/Sitemapify/Providers/Impl/EmptySitemapContentProvider.cs index f3baedf..06b39c4 100644 --- a/src/Sitemapify/Providers/Impl/EmptySitemapContentProvider.cs +++ b/src/Sitemapify/Providers/Impl/EmptySitemapContentProvider.cs @@ -6,9 +6,10 @@ namespace Sitemapify.Providers.Impl { public class EmptySitemapContentProvider : ISitemapContentProvider { - public virtual IEnumerable GetSitemapUrls() + public virtual IEnumerable GetSitemapUrls(Uri baseUrl) { - yield return SitemapUrl.Create("/"); + var ub = new UriBuilder(baseUrl) {Path = "/"}; + yield return SitemapUrl.Create(ub.ToString()); } public virtual bool Cacheable { get; } = true; diff --git a/src/Sitemapify/SitemapifyHttpHandler.cs b/src/Sitemapify/SitemapifyHttpHandler.cs index b68fa1a..e111d7a 100644 --- a/src/Sitemapify/SitemapifyHttpHandler.cs +++ b/src/Sitemapify/SitemapifyHttpHandler.cs @@ -1,3 +1,4 @@ +using System; using System.Text; using System.Web; using System.Web.Routing; @@ -30,7 +31,7 @@ public void ProcessRequest(HttpContextBase context) context.Response.Buffer = true; context.Response.BufferOutput = true; context.Response.ContentEncoding = Encoding.UTF8; - var document = GetSitemapContent(); + var document = GetSitemapContent(context.Request); document.Save(context.Response.Output, SaveOptions.OmitDuplicateNamespaces); if (_contentProvider.Cacheable) { @@ -39,17 +40,22 @@ public void ProcessRequest(HttpContextBase context) } } - private XDocument GetSitemapContent() + private XDocument GetSitemapContent(HttpRequestBase contextRequest) { if (!_sitemapCacheProvider.IsCached || ResetCache) { - var document = _documentBuilder.BuildSitemapXmlDocument(_contentProvider.GetSitemapUrls()); - if (_contentProvider.Cacheable) + var baseUrl = contextRequest.Url?.GetLeftPart(UriPartial.Authority); + if (!string.IsNullOrWhiteSpace(baseUrl) && Uri.IsWellFormedUriString(baseUrl, UriKind.Absolute)) { - _sitemapCacheProvider.Add(document, _contentProvider.CacheUntil); - ResetCache = false; + var authorityUri = new Uri(baseUrl, UriKind.Absolute); + var document = _documentBuilder.BuildSitemapXmlDocument(_contentProvider.GetSitemapUrls(authorityUri)); + if (_contentProvider.Cacheable) + { + _sitemapCacheProvider.Add(document, _contentProvider.CacheUntil); + ResetCache = false; + } + return document; } - return document; } return _sitemapCacheProvider.Get(); }