Handling External URLs in Umbraco 6 页面重定向到外部URL

发布于:
分类: Microsoft.Net Tagged

copy from: http://www.theoutfield.net/blog/2013/10/handling-external-urls-in-umbraco-6

Umbraco 有一些特殊的别名,如:umbracoUrlName,能让你在当前网站中的页面间重定向。然而,他没有一个内置的方法将一个页面重定向到外部URL。我认为我想出了一个相当不错的办法,下面讲解如何做到:

创建一个属性(Property)

我们在文档类型中创建一个名为“umbracoExternalUrl”的文本字符串属性。

创建 IUrlProvider

  我已经设立我们需要的属性,现在我们要让umbraco知道,当这个属性值被设置的时候,就使用他的值来作为节点的URL而不是使用默认生的URL。我们将使用Umbraco一个很酷的新功能实现它,它是一个UrlProvider,该IUrlProvider接口能在生成一个节点的URL的时候定义我们自己的逻辑。继续,我们建立一个接口如下

using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Web;
using Umbraco.Web.Routing;
 
namespace TheOutfield.Routing
{
    public class ExternalUrlProvider : IUrlProvider
    {
        public string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode)
        {
            var node = umbracoContext.ContentCache.GetById(id);
            return node.HasValue("umbracoExternalUrl")
                ? node.GetPropertyValue<string>("umbracoExternalUrl")
                : null;
        }
 
        public IEnumerable<string> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current)
        {
            return Enumerable.Empty<string>();
        }
    }
}

接口本身是相当简单的,我们做的是执行getURL方法检查当前节点是否有umbracoExternalUrl属性,如果有,返回我们在umbracoExternalUrl属性中设置的URL,否则返回null(如果响应为null,则umbraco将移动到下一个UrlProvider寻找,所以最终会回落到默认的UrlProvider)。

上面我们已经定义了我们的UrlProvider,我们需要Umbraco意识到这一点,所以要做到这一点,创建一个ApplicationEventHandler:

using TheOutfield.Routing;
using Umbraco.Core;
using Umbraco.Web.Routing;
 
namespace TheOutfield
{
    public class Bootstrapper : IApplicationEventHandler
    {
        public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        { }
 
        public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            UrlProviderResolver.Current.InsertTypeBefore<DefaultUrlProvider, ExternalUrlProvider>();
        }
 
        public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        { }
    }
}

如果您现在检查你的内容节点的属性选项卡,你会看到,Umbraco确实返回外部URL作为节点的URL。

到现在看起来不错,但有一个小问题,如果你导航到节点内部网址,Umbraco还是会尝试渲染页面,而不是重定向到我们定义的外部URL。所以,我们将使用一个Umbraco 中一个方便的事件 request pipline,PublishedContentRequest.Prepared,请求的上下文被创建之后,它让我们执行一些代码,但在实际执行页面之前。我们要在我们的ApplicationEventHandler类中声明事件处理程序。

using TheOutfield.Routing;
using Umbraco.Core;
using Umbraco.Web;
using Umbraco.Web.Routing;
 
namespace TheOutfield
{
    public class Bootstrapper : IApplicationEventHandler
    {
        public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        { }
 
        public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            UrlProviderResolver.Current.InsertTypeBefore<DefaultUrlProvider, ExternalUrlProvider>();
            PublishedContentRequest.Prepared += (sender, args) =>
            {
                // Check to make sure the request is valid
                var request = sender as PublishedContentRequest;
                if (request == null || !request.HasPublishedContent)
                    return;
 
                // Check for external url
                var url = request.PublishedContent.GetPropertyValue<string>("umbracoExternalUrl");
                if (string.IsNullOrWhiteSpace(url))
                    return;
 
                // Perform the redirect
                request.SetRedirect(url, 301);
            };
        }
 
        public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        { }
    }
}

  所以,现在如果您尝试浏览到您的节点内部URL,你会发现Umbraco会很Happy地重定向你定义的外部URL。

收尾工作

  现在一切能够正常运行,但是作为一个强迫症患者,想直观地让自己和别人知道哪些页面被设置了重定向,办法是使用这家伙惊人的页面状态图标包 Page State Icons

安装后编辑PageStateIcons.config文件

<pageStateIconsConfigurationSection xmlns="UmBristol.PageStateIcons">
  <rules>
    <add name="umbracoNaviHide" xPath="umbracoNaviHide = '1'" overlayIconPath="/Umbraco/Plugins/PageStateIcons/UmbracoNaviHide.png"
      description="Adds overlay to show the page is hidden from navigation."
      top="7" left="11" />
    <add name="umbracoRedirect" xPath="self::*[@isDoc and (normalize-space(umbracoRedirect) or normalize-space(umbracoExternalUrl))]"
      overlayIconPath="/Umbraco/Plugins/PageStateIcons/UmbracoRedirect.png"
      description="Adds an overlay to show the page is a redirect page."
      top="0" left="22" />
    <add name="umbracoInternalRedirectId" xPath="self::*[@isDoc and normalize-space(umbracoInternalRedirectId) and not(normalize-space(umbracoRedirect) or normalize-space(umbracoExternalUrl))]"
      overlayIconPath="/Umbraco/Plugins/PageStateIcons/umbracoInternalRedirectId.png"
      description="Adds an overlay to show the page is a redirect page."
      top="0" left="22" />
  </rules>
</pageStateIconsConfigurationSection>

  现在的内容树中你会看到你的节点上叠加了一个可爱的小箭头,让你知道您的页面设置了重定向。

…….

  我希望你能找到它的用武之地了。

留下评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注