fix NiceUrl and add more tests
This commit is contained in:
@@ -312,16 +312,21 @@ namespace Umbraco.Core.Configuration
|
||||
get { return "packages.umbraco.org"; }
|
||||
}
|
||||
|
||||
static bool? _useDomainPrefixes = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether umbraco will use domain prefixes.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco will use domain prefixes; otherwise, <c>false</c>.</value>
|
||||
// TODO rename as EnforceAbsoluteUrls
|
||||
public static bool UseDomainPrefixes
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_useDomainPrefixes.HasValue)
|
||||
return _useDomainPrefixes.Value;
|
||||
bool result;
|
||||
if (bool.TryParse(GetKey("/settings/requestHandler/useDomainPrefixes"), out result))
|
||||
return result;
|
||||
@@ -332,6 +337,11 @@ namespace Umbraco.Core.Configuration
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// for unit tests only
|
||||
internal set
|
||||
{
|
||||
_useDomainPrefixes = value;
|
||||
}
|
||||
}
|
||||
|
||||
static bool? _addTrailingSlash = null;
|
||||
@@ -365,6 +375,7 @@ namespace Umbraco.Core.Configuration
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// for unit tests only
|
||||
internal set
|
||||
{
|
||||
_addTrailingSlash = value;
|
||||
|
||||
@@ -78,23 +78,6 @@ namespace Umbraco.Tests.Routing
|
||||
}
|
||||
}
|
||||
|
||||
//[TestCase(1046, "/home.aspx")]
|
||||
//[TestCase(1173, "/home/sub1.aspx")]
|
||||
//[TestCase(1174, "/home/sub1/sub2.aspx")]
|
||||
//[TestCase(1176, "/home/sub1/sub-3.aspx")]
|
||||
//[TestCase(1177, "/home/sub1/custom-sub-1.aspx")]
|
||||
//[TestCase(1178, "/home/sub1/custom-sub-2.aspx")]
|
||||
//[TestCase(1175, "/home/sub-2.aspx")]
|
||||
//[TestCase(1172, "/test-page.aspx")]
|
||||
//public void Get_Nice_Url_Not_Hiding_Top_Level_No_Directory_Urls(int nodeId, string niceUrlMatch)
|
||||
//{
|
||||
// var routingContext = GetRoutingContext("/test", 1111);
|
||||
|
||||
// var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId);
|
||||
|
||||
// Assert.AreEqual(niceUrlMatch, result);
|
||||
//}
|
||||
|
||||
// test hideTopLevelNodeFromPath false
|
||||
[TestCase(1046, "/home")]
|
||||
[TestCase(1173, "/home/sub1")]
|
||||
@@ -111,6 +94,7 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false");
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
|
||||
var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId);
|
||||
Assert.AreEqual(niceUrlMatch, result);
|
||||
@@ -118,25 +102,6 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
// no need for umbracoUseDirectoryUrls test = should be handled by UriUtilityTests
|
||||
|
||||
//[TestCase(1046, "/")]
|
||||
//[TestCase(1173, "/sub1.aspx")]
|
||||
//[TestCase(1174, "/sub1/sub2.aspx")]
|
||||
//[TestCase(1176, "/sub1/sub-3.aspx")]
|
||||
//[TestCase(1177, "/sub1/custom-sub-1.aspx")]
|
||||
//[TestCase(1178, "/sub1/custom-sub-2.aspx")]
|
||||
//[TestCase(1175, "/sub-2.aspx")]
|
||||
//[TestCase(1172, "/test-page.aspx")]
|
||||
//public void Get_Nice_Url_Hiding_Top_Level_No_Directory_Urls(int nodeId, string niceUrlMatch)
|
||||
//{
|
||||
// var routingContext = GetRoutingContext("/test", 1111);
|
||||
|
||||
// ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true");
|
||||
|
||||
// var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId);
|
||||
|
||||
// Assert.AreEqual(niceUrlMatch, result);
|
||||
//}
|
||||
|
||||
// test hideTopLevelNodeFromPath true
|
||||
[TestCase(1046, "/")]
|
||||
[TestCase(1173, "/sub1")]
|
||||
@@ -153,9 +118,46 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true");
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
|
||||
var result = routingContext.NiceUrlProvider.GetNiceUrl(nodeId);
|
||||
Assert.AreEqual(niceUrlMatch, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Nice_Url_Relative_Or_Absolute()
|
||||
{
|
||||
var routingContext = GetRoutingContext("http://example.com/test", 1111);
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false");
|
||||
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
Assert.AreEqual("/home/sub1/custom-sub-1", routingContext.NiceUrlProvider.GetNiceUrl(1177));
|
||||
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true;
|
||||
Assert.AreEqual("http://example.com/home/sub1/custom-sub-1", routingContext.NiceUrlProvider.GetNiceUrl(1177));
|
||||
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true;
|
||||
Assert.AreEqual("http://example.com/home/sub1/custom-sub-1", routingContext.NiceUrlProvider.GetNiceUrl(1177));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Nice_Url_Unpublished()
|
||||
{
|
||||
var routingContext = GetRoutingContext("http://example.com/test", 1111);
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false");
|
||||
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999));
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true;
|
||||
Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999));
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true;
|
||||
Assert.AreEqual("#", routingContext.NiceUrlProvider.GetNiceUrl(999999));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,6 +91,22 @@ namespace Umbraco.Tests.Routing
|
||||
Domain.MakeNew("http://domain3.com/fr", 10032, langFr.id);
|
||||
}
|
||||
|
||||
void SetDomains5()
|
||||
{
|
||||
var langEn = Language.GetByCultureCode("en-US");
|
||||
var langFr = Language.GetByCultureCode("fr-FR");
|
||||
|
||||
Domain.MakeNew("http://domain1.com/en", 10011, langEn.id);
|
||||
Domain.MakeNew("http://domain1a.com/en", 10011, langEn.id);
|
||||
Domain.MakeNew("http://domain1b.com/en", 10011, langEn.id);
|
||||
Domain.MakeNew("http://domain1.com/fr", 10012, langFr.id);
|
||||
Domain.MakeNew("http://domain1a.com/fr", 10012, langFr.id);
|
||||
Domain.MakeNew("http://domain1b.com/fr", 10012, langFr.id);
|
||||
|
||||
Domain.MakeNew("http://domain3.com/en", 10031, langEn.id);
|
||||
Domain.MakeNew("http://domain3.com/fr", 10032, langFr.id);
|
||||
}
|
||||
|
||||
protected override string GetXmlContent(int templateId)
|
||||
{
|
||||
return @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
@@ -194,6 +210,7 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
|
||||
InitializeLanguagesAndDomains();
|
||||
SetDomains1();
|
||||
@@ -223,6 +240,7 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
|
||||
InitializeLanguagesAndDomains();
|
||||
SetDomains2();
|
||||
@@ -244,6 +262,7 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
|
||||
InitializeLanguagesAndDomains();
|
||||
SetDomains3();
|
||||
@@ -268,6 +287,7 @@ namespace Umbraco.Tests.Routing
|
||||
public void Get_Nice_Url_NestedDomains(int nodeId, string currentUrl, bool absolute, string expected)
|
||||
{
|
||||
var routingContext = GetRoutingContext("/test", 1111);
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains
|
||||
@@ -287,6 +307,7 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false"); // ignored w/domains
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
|
||||
InitializeLanguagesAndDomains();
|
||||
SetDomains4();
|
||||
@@ -337,5 +358,52 @@ namespace Umbraco.Tests.Routing
|
||||
Assert.IsTrue(ids.ContainsKey(route));
|
||||
Assert.AreEqual(id, ids[route]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Nice_Url_Relative_Or_Absolute()
|
||||
{
|
||||
var routingContext = GetRoutingContext("http://domain1.com/test", 1111);
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false");
|
||||
|
||||
InitializeLanguagesAndDomains();
|
||||
SetDomains4();
|
||||
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
Assert.AreEqual("/en/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111));
|
||||
Assert.AreEqual("http://domain3.com/en/1003-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100311));
|
||||
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = true;
|
||||
Assert.AreEqual("http://domain1.com/en/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111));
|
||||
Assert.AreEqual("http://domain3.com/en/1003-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100311));
|
||||
|
||||
Umbraco.Core.Configuration.UmbracoSettings.UseDomainPrefixes = false;
|
||||
routingContext.NiceUrlProvider.EnforceAbsoluteUrls = true;
|
||||
Assert.AreEqual("http://domain1.com/en/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111));
|
||||
Assert.AreEqual("http://domain3.com/en/1003-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100311));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Nice_Url_Alternate()
|
||||
{
|
||||
var routingContext = GetRoutingContext("http://domain1.com/test", 1111);
|
||||
|
||||
ConfigurationManager.AppSettings.Set("umbracoUseDirectoryUrls", "true");
|
||||
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "false");
|
||||
|
||||
InitializeLanguagesAndDomains();
|
||||
SetDomains5();
|
||||
|
||||
var result = routingContext.NiceUrlProvider.GetAllAbsoluteNiceUrls(100111);
|
||||
|
||||
// will always get absolute urls
|
||||
// all of them
|
||||
// including the local one - duplicate?! - then must manually exclude?
|
||||
Assert.AreEqual(3, result.Count());
|
||||
Assert.IsTrue(result.Contains("http://domain1.com/en/1001-1-1"));
|
||||
Assert.IsTrue(result.Contains("http://domain1a.com/en/1001-1-1"));
|
||||
Assert.IsTrue(result.Contains("http://domain1b.com/en/1001-1-1"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,5 +86,37 @@ namespace Umbraco.Tests
|
||||
{
|
||||
return new Uri(url, url.StartsWith("http:") ? UriKind.Absolute : UriKind.Relative);
|
||||
}
|
||||
|
||||
//
|
||||
[TestCase("/", "/", "/")]
|
||||
[TestCase("/", "/foo", "/foo")]
|
||||
[TestCase("/", "~/foo", "/foo")]
|
||||
[TestCase("/vdir", "/", "/vdir/")]
|
||||
[TestCase("/vdir", "/foo", "/vdir/foo")]
|
||||
[TestCase("/vdir", "/foo/", "/vdir/foo/")]
|
||||
[TestCase("/vdir", "~/foo", "/vdir/foo")]
|
||||
|
||||
public void Uri_To_Absolute(string virtualPath, string sourceUrl, string expectedUrl)
|
||||
{
|
||||
UriUtility.SetAppDomainAppVirtualPath(virtualPath);
|
||||
var resultUrl = UriUtility.ToAbsolute(sourceUrl);
|
||||
Assert.AreEqual(expectedUrl, resultUrl);
|
||||
}
|
||||
|
||||
//
|
||||
[TestCase("/", "/", "/")]
|
||||
[TestCase("/", "/foo", "/foo")]
|
||||
[TestCase("/", "/foo/", "/foo/")]
|
||||
[TestCase("/vdir", "/vdir", "/")]
|
||||
[TestCase("/vdir", "/vdir/", "/")]
|
||||
[TestCase("/vdir", "/vdir/foo", "/foo")]
|
||||
[TestCase("/vdir", "/vdir/foo/", "/foo/")]
|
||||
|
||||
public void Url_To_App_Relative(string virtualPath, string sourceUrl, string expectedUrl)
|
||||
{
|
||||
UriUtility.SetAppDomainAppVirtualPath(virtualPath);
|
||||
var resultUrl = UriUtility.ToAppRelative(sourceUrl);
|
||||
Assert.AreEqual(expectedUrl, resultUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ namespace Umbraco.Web.Routing
|
||||
/// </summary>
|
||||
internal class NiceUrlProvider
|
||||
{
|
||||
|
||||
internal const string NullUrl = "#";
|
||||
|
||||
/// <summary>
|
||||
@@ -30,37 +29,56 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
_umbracoContext = umbracoContext;
|
||||
_publishedContentStore = publishedContentStore;
|
||||
this.EnforceAbsoluteUrls = false;
|
||||
}
|
||||
|
||||
private readonly UmbracoContext _umbracoContext;
|
||||
private readonly IPublishedContentStore _publishedContentStore;
|
||||
|
||||
|
||||
public bool EnforceAbsoluteUrls { get; set; }
|
||||
|
||||
#region GetNiceUrl
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nice url of a node.
|
||||
/// </summary>
|
||||
/// <param name="nodeId">The node id.</param>
|
||||
/// <param name="nodeId">The node identifier.</param>
|
||||
/// <returns>The nice url for the node.</returns>
|
||||
/// <remarks>The url is absolute or relative depending on the current url.</remarks>
|
||||
/// <remarks>The url is absolute or relative depending on the current url, settings, and options.</remarks>
|
||||
public string GetNiceUrl(int nodeId)
|
||||
{
|
||||
return GetNiceUrl(nodeId, _umbracoContext.UmbracoUrl, false);
|
||||
var absolute = UmbracoSettings.UseDomainPrefixes || this.EnforceAbsoluteUrls;
|
||||
return GetNiceUrl(nodeId, _umbracoContext.UmbracoUrl, absolute);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nice url of a node.
|
||||
/// </summary>
|
||||
/// <param name="nodeId">The node identifier.</param>
|
||||
/// <param name="absolute">A value indicating whether the url should be absolute in any case.</param>
|
||||
/// <returns>The nice url for the node.</returns>
|
||||
/// <remarks>The url is absolute or relative depending on the current url, unless <c>absolute</c> is true, in which case the url is always absolute.</remarks>
|
||||
public string GetNiceUrl(int nodeId, bool absolute)
|
||||
{
|
||||
return GetNiceUrl(nodeId, _umbracoContext.UmbracoUrl, absolute);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nice url of a node.
|
||||
/// </summary>
|
||||
/// <param name="nodeId">The node id.</param>
|
||||
/// <param name="current">The current url.</param>
|
||||
/// <param name="current">The current absolute url.</param>
|
||||
/// <param name="absolute">A value indicating whether the url should be absolute in any case.</param>
|
||||
/// <returns>The nice url for the node.</returns>
|
||||
/// <remarks>The url is absolute or relative depending on the current url, unless absolute is true, and then it is always absolute.</remarks>
|
||||
/// <remarks>The url is absolute or relative depending on url indicated by <c>current</c>, unless <c>absolute</c> is true, in which case the url is always absolute.</remarks>
|
||||
public string GetNiceUrl(int nodeId, Uri current, bool absolute)
|
||||
{
|
||||
Uri domainUri;
|
||||
string path;
|
||||
|
||||
if (!current.IsAbsoluteUri)
|
||||
throw new ArgumentException("Current url must be absolute.", "current");
|
||||
|
||||
// do not read cache if previewing
|
||||
var route = _umbracoContext.InPreviewMode
|
||||
? null
|
||||
@@ -105,26 +123,7 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
// no domain, respect HideTopLevelNodeFromPath for legacy purposes
|
||||
if (domainUri == null && global::umbraco.GlobalSettings.HideTopLevelNodeFromPath)
|
||||
{
|
||||
// in theory if hideTopLevelNodeFromPath is true, then there should be only once
|
||||
// top-level node, or else domains should be assigned. but for backward compatibility
|
||||
// we add this check - we look for the document matching "/" and if it's not us, then
|
||||
// we do not hide the top level path
|
||||
// it has to be taken care of in IPublishedContentStore.GetDocumentByRoute too so if
|
||||
// "/foo" fails (looking for "/*/foo") we try also "/foo".
|
||||
// this does not make much sense anyway esp. if both "/foo/" and "/bar/foo" exist, but
|
||||
// that's the way it works pre-4.10 and we try to be backward compat for the time being
|
||||
if (node.Parent == null)
|
||||
{
|
||||
var rootNode = _publishedContentStore.GetDocumentByRoute(_umbracoContext, "/", true);
|
||||
if (rootNode.Id == node.Id) // remove only if we're the default node
|
||||
pathParts.RemoveAt(pathParts.Count - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pathParts.RemoveAt(pathParts.Count - 1);
|
||||
}
|
||||
}
|
||||
ApplyHideTopLevelNodeFromPath(node, pathParts);
|
||||
|
||||
// assemble the route
|
||||
pathParts.Reverse();
|
||||
@@ -140,6 +139,15 @@ namespace Umbraco.Web.Routing
|
||||
return AssembleUrl(domainUri, path, current, absolute).ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetAlternateNiceUrls
|
||||
|
||||
public IEnumerable<string> GetAllAbsoluteNiceUrls(int nodeId)
|
||||
{
|
||||
return GetAlternateNiceUrls(nodeId, _umbracoContext.UmbracoUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nice urls of a node.
|
||||
/// </summary>
|
||||
@@ -147,7 +155,7 @@ namespace Umbraco.Web.Routing
|
||||
/// <param name="current">The current url.</param>
|
||||
/// <returns>An enumeration of all valid urls for the node.</returns>
|
||||
/// <remarks>The urls are absolute. A node can have more than one url if more than one domain is defined.</remarks>
|
||||
public IEnumerable<string> GetNiceUrls(int nodeId, Uri current)
|
||||
public IEnumerable<string> GetAlternateNiceUrls(int nodeId, Uri current)
|
||||
{
|
||||
// this is for editContent.aspx which had its own, highly buggy, implementation of NiceUrl...
|
||||
//TODO: finalize & test implementation then replace in editContent.aspx
|
||||
@@ -160,55 +168,77 @@ namespace Umbraco.Web.Routing
|
||||
? null
|
||||
: _umbracoContext.RoutesCache.GetRoute(nodeId);
|
||||
|
||||
if (route != null)
|
||||
if (!string.IsNullOrEmpty(route))
|
||||
{
|
||||
// route is <id>/<path> eg "-1/", "-1/foo", "123/", "123/foo/bar"...
|
||||
// there was a route in the cache - extract domainUri and path
|
||||
// route is /<path> or <domainRootId>/<path>
|
||||
int pos = route.IndexOf('/');
|
||||
path = route.Substring(pos);
|
||||
int id = int.Parse(route.Substring(0, pos)); // will be -1 or 1234
|
||||
domainUris = id > 0 ? DomainUrisAtNode(id, current) : new Uri[] { };
|
||||
path = pos == 0 ? route : route.Substring(pos);
|
||||
domainUris = pos == 0 ? new Uri[] { } : DomainUrisAtNode(int.Parse(route.Substring(0, pos)), current);
|
||||
}
|
||||
else
|
||||
{
|
||||
// there was no route in the cache - create a route
|
||||
var node = _publishedContentStore.GetDocumentById(_umbracoContext, nodeId);
|
||||
if (node == null)
|
||||
return new string[] { NullUrl }; // legacy wrote to the log here...
|
||||
|
||||
var pathParts = new List<string>();
|
||||
int id = nodeId;
|
||||
domainUris = DomainUrisAtNode(id, current);
|
||||
while (!domainUris.Any() && id > 0)
|
||||
{
|
||||
LogHelper.Warn<NiceUrlProvider>(
|
||||
"Couldn't find any page with nodeId={0}. This is most likely caused by the page not being published.",
|
||||
nodeId);
|
||||
|
||||
return new string[] { NullUrl };
|
||||
}
|
||||
|
||||
// walk up from that node until we hit a node with domains,
|
||||
// or we reach the content root, collecting urls in the way
|
||||
var pathParts = new List<string>();
|
||||
var n = node;
|
||||
domainUris = DomainUrisAtNode(n.Id, current);
|
||||
while (!domainUris.Any() && n != null) // n is null at root
|
||||
{
|
||||
// get the url
|
||||
var urlName = node.UrlName;
|
||||
pathParts.Add(urlName);
|
||||
node = node.Parent; //set to parent node
|
||||
id = node.Id;
|
||||
domainUris = id > 0 ? DomainUrisAtNode(id, current) : new Uri[] { };
|
||||
|
||||
// move to parent node
|
||||
n = n.Parent;
|
||||
domainUris = n == null ? new Uri[] { } : DomainUrisAtNode(n.Id, current);
|
||||
}
|
||||
|
||||
// no domain, respect HideTopLevelNodeFromPath for legacy purposes
|
||||
if (!domainUris.Any() && global::umbraco.GlobalSettings.HideTopLevelNodeFromPath)
|
||||
pathParts.RemoveAt(pathParts.Count - 1);
|
||||
ApplyHideTopLevelNodeFromPath(node, pathParts);
|
||||
|
||||
// assemble the route
|
||||
pathParts.Reverse();
|
||||
path = "/" + string.Join("/", pathParts); // will be "/" or "/foo" or "/foo/bar" etc
|
||||
route = id.ToString() + path;
|
||||
route = (n == null ? "" : n.Id.ToString()) + path;
|
||||
|
||||
// do not store if previewing
|
||||
if (!_umbracoContext.InPreviewMode)
|
||||
_umbracoContext.RoutesCache.Store(nodeId, route);
|
||||
}
|
||||
|
||||
// assemble the alternate urls from domainUris (maybe empty) and path
|
||||
return AssembleUrls(domainUris, path, current).Select(uri => uri.ToString());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Utilities
|
||||
|
||||
Uri AssembleUrl(Uri domainUri, string path, Uri current, bool absolute)
|
||||
{
|
||||
Uri uri;
|
||||
|
||||
if (domainUri == null)
|
||||
{
|
||||
// no domain was found : return a relative url, add vdir if any
|
||||
uri = new Uri(SystemDirectories.Root + path, UriKind.Relative);
|
||||
// no domain was found : return an absolute or relative url
|
||||
// handle vdir if any
|
||||
if (!absolute || current == null)
|
||||
uri = new Uri(UriUtility.ToAbsolute(path), UriKind.Relative);
|
||||
else
|
||||
uri = new Uri(current.GetLeftPart(UriPartial.Authority) + UriUtility.ToAbsolute(path));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -229,17 +259,26 @@ namespace Umbraco.Web.Routing
|
||||
return path == "/" ? path : path.TrimEnd('/');
|
||||
}
|
||||
|
||||
// always build absolute urls unless we really cannot
|
||||
IEnumerable<Uri> AssembleUrls(IEnumerable<Uri> domainUris, string path, Uri current)
|
||||
{
|
||||
if (domainUris.Any())
|
||||
List<Uri> uris = new List<Uri>();
|
||||
if (!domainUris.Any())
|
||||
{
|
||||
return domainUris.Select(domainUri => new Uri(domainUri.GetLeftPart(UriPartial.Path).TrimEnd('/') + path));
|
||||
// no domain was found : return an absolute or relative url
|
||||
// handle vdir if any
|
||||
if (current == null)
|
||||
uris.Add(new Uri(UriUtility.ToAbsolute(path), UriKind.Relative));
|
||||
else
|
||||
uris.Add(new Uri(current.GetLeftPart(UriPartial.Authority) + UriUtility.ToAbsolute(path)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// no domain was found : return a relative url, add vdir if any
|
||||
return new Uri[] { new Uri(SystemDirectories.Root + path, UriKind.Relative) };
|
||||
// domains were found : return -- FIXME?
|
||||
uris.AddRange(domainUris.Select(domainUri => new Uri(domainUri.GetLeftPart(UriPartial.Path).TrimEnd('/') + path)));
|
||||
}
|
||||
|
||||
return uris.Select(uri => UriUtility.UriFromUmbraco(uri));
|
||||
}
|
||||
|
||||
Uri DomainUriAtNode(int nodeId, Uri current)
|
||||
@@ -263,6 +302,28 @@ namespace Umbraco.Web.Routing
|
||||
return domainAndUris.Select(d => d.Uri);
|
||||
}
|
||||
|
||||
void ApplyHideTopLevelNodeFromPath(Core.Models.IDocument node, List<string> pathParts)
|
||||
{
|
||||
// in theory if hideTopLevelNodeFromPath is true, then there should be only once
|
||||
// top-level node, or else domains should be assigned. but for backward compatibility
|
||||
// we add this check - we look for the document matching "/" and if it's not us, then
|
||||
// we do not hide the top level path
|
||||
// it has to be taken care of in IPublishedContentStore.GetDocumentByRoute too so if
|
||||
// "/foo" fails (looking for "/*/foo") we try also "/foo".
|
||||
// this does not make much sense anyway esp. if both "/foo/" and "/bar/foo" exist, but
|
||||
// that's the way it works pre-4.10 and we try to be backward compat for the time being
|
||||
if (node.Parent == null)
|
||||
{
|
||||
var rootNode = _publishedContentStore.GetDocumentByRoute(_umbracoContext, "/", true);
|
||||
if (rootNode.Id == node.Id) // remove only if we're the default node
|
||||
pathParts.RemoveAt(pathParts.Count - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pathParts.RemoveAt(pathParts.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -317,7 +317,7 @@ namespace Umbraco.Web
|
||||
public string NiceUrlWithDomain(int nodeId)
|
||||
{
|
||||
var niceUrlsProvider = UmbracoContext.Current.NiceUrlProvider;
|
||||
return niceUrlsProvider.GetNiceUrl(nodeId, UmbracoContext.Current.UmbracoUrl, true);
|
||||
return niceUrlsProvider.GetNiceUrl(nodeId, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -7,47 +7,58 @@ using umbraco;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
static class UriUtility
|
||||
public static class UriUtility
|
||||
{
|
||||
static readonly string _appVirtualPath;
|
||||
static readonly string _appVirtualPathPrefix;
|
||||
static string _appPath;
|
||||
static string _appPathPrefix;
|
||||
|
||||
static UriUtility()
|
||||
{
|
||||
// Virtual path
|
||||
_appVirtualPath = HttpRuntime.AppDomainAppVirtualPath ?? "/";
|
||||
_appVirtualPathPrefix = _appVirtualPath;
|
||||
if (_appVirtualPathPrefix == "/")
|
||||
_appVirtualPathPrefix = String.Empty;
|
||||
SetAppDomainAppVirtualPath(HttpRuntime.AppDomainAppVirtualPath);
|
||||
}
|
||||
|
||||
// internal for unit testing only
|
||||
internal static void SetAppDomainAppVirtualPath(string appPath)
|
||||
{
|
||||
_appPath = appPath ?? "/";
|
||||
_appPathPrefix = _appPath;
|
||||
if (_appPathPrefix == "/")
|
||||
_appPathPrefix = String.Empty;
|
||||
}
|
||||
|
||||
// will be "/" or "/foo"
|
||||
public static string AppVirtualPath
|
||||
public static string AppPath
|
||||
{
|
||||
get { return _appVirtualPath; }
|
||||
get { return _appPath; }
|
||||
}
|
||||
|
||||
// will be "" or "/foo"
|
||||
public static string AppVirtualPathPrefix
|
||||
public static string AppPathPrefix
|
||||
{
|
||||
get { return _appVirtualPathPrefix; }
|
||||
get { return _appPathPrefix; }
|
||||
}
|
||||
|
||||
public static string ToAbsolute(string url)
|
||||
// adds the virtual directory if any
|
||||
// see also VirtualPathUtility.ToAbsolute
|
||||
// FIXME
|
||||
public static string ToAbsolute(string url)
|
||||
{
|
||||
return ResolveUrl(url);
|
||||
//return ResolveUrl(url);
|
||||
url = url.TrimStart('~');
|
||||
return _appPathPrefix + url;
|
||||
}
|
||||
|
||||
public static string ToAppRelative(string url)
|
||||
// strips the virtual directory if any
|
||||
// see also VirtualPathUtility.ToAppRelative
|
||||
public static string ToAppRelative(string virtualPath)
|
||||
{
|
||||
if (url.StartsWith(_appVirtualPathPrefix))
|
||||
url = url.Substring(_appVirtualPathPrefix.Length);
|
||||
return url;
|
||||
if (virtualPath.StartsWith(_appPathPrefix))
|
||||
virtualPath = virtualPath.Substring(_appPathPrefix.Length);
|
||||
return virtualPath;
|
||||
}
|
||||
|
||||
// fixme - what about vdir?
|
||||
// path = path.Substring(UriUtility.AppVirtualPathPrefix.Length); // remove virtual directory
|
||||
|
||||
// maps an internal umbraco uri to a public uri
|
||||
// ie with virtual directory, .aspx if required...
|
||||
public static Uri UriFromUmbraco(Uri uri)
|
||||
{
|
||||
var path = uri.GetSafeAbsolutePath();
|
||||
@@ -59,19 +70,19 @@ namespace Umbraco.Web
|
||||
else if (UmbracoSettings.AddTrailingSlash)
|
||||
path += "/";
|
||||
|
||||
path = ToAbsolute(path);
|
||||
|
||||
return uri.Rewrite(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Uri to a path based URI that is lower cased
|
||||
/// </summary>
|
||||
/// <param name="uri"></param>
|
||||
/// <returns></returns>
|
||||
public static Uri UriToUmbraco(Uri uri)
|
||||
// maps a public uri to an internal umbraco uri
|
||||
// ie no virtual directory, no .aspx, lowercase...
|
||||
public static Uri UriToUmbraco(Uri uri)
|
||||
{
|
||||
var path = uri.GetSafeAbsolutePath();
|
||||
|
||||
path = path.ToLower();
|
||||
path = ToAppRelative(path); // strip vdir if any
|
||||
|
||||
//we need to check if the path is /default.aspx because this will occur when using a
|
||||
//web server pre IIS 7 when requesting the root document
|
||||
@@ -116,7 +127,7 @@ namespace Umbraco.Web
|
||||
}
|
||||
|
||||
StringBuilder sbUrl = new StringBuilder();
|
||||
sbUrl.Append(HttpRuntime.AppDomainAppVirtualPath);
|
||||
sbUrl.Append(_appPathPrefix);
|
||||
if (sbUrl.Length == 0 || sbUrl[sbUrl.Length - 1] != '/') sbUrl.Append('/');
|
||||
|
||||
// found question mark already? query string, do not touch!
|
||||
|
||||
@@ -20,6 +20,7 @@ using umbraco.cms.businesslogic.web;
|
||||
using umbraco.presentation;
|
||||
using umbraco.cms.businesslogic.skinning;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace umbraco.cms.presentation
|
||||
{
|
||||
@@ -180,7 +181,7 @@ namespace umbraco.cms.presentation
|
||||
publishProps.addProperty(ui.Text("content", "expireDate", base.getUser()), dpExpire);
|
||||
|
||||
// url's
|
||||
updateLinks();
|
||||
UpdateNiceUrls();
|
||||
linkProps.addProperty(ui.Text("content", "urls", base.getUser()), l);
|
||||
|
||||
if (domainText.Text != "")
|
||||
@@ -323,7 +324,7 @@ namespace umbraco.cms.presentation
|
||||
UnPublish.Visible = true;
|
||||
|
||||
_documentHasPublishedVersion = _document.HasPublishedVersion();
|
||||
updateLinks();
|
||||
UpdateNiceUrls();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -353,57 +354,36 @@ namespace umbraco.cms.presentation
|
||||
|
||||
}
|
||||
|
||||
private void updateLinks()
|
||||
{
|
||||
if (_documentHasPublishedVersion)
|
||||
{
|
||||
// zb-00007 #29928 : refactor
|
||||
string currentLink = library.NiceUrl(_document.Id);
|
||||
l.Text = "<a href=\"" + currentLink + "\" target=\"_blank\">" + currentLink + "</a>";
|
||||
void UpdateNiceUrls()
|
||||
{
|
||||
if (!_documentHasPublishedVersion)
|
||||
{
|
||||
l.Text = "<i>" + ui.Text("content", "itemNotPublished", base.getUser()) + "</i>";
|
||||
return;
|
||||
}
|
||||
|
||||
// domains
|
||||
domainText.Text = "";
|
||||
foreach (string s in _document.Path.Split(','))
|
||||
{
|
||||
if (int.Parse(s) > -1)
|
||||
{
|
||||
cms.businesslogic.web.Document dChild = new cms.businesslogic.web.Document(int.Parse(s));
|
||||
if (dChild.Published)
|
||||
{
|
||||
cms.businesslogic.web.Domain[] domains = cms.businesslogic.web.Domain.GetDomainsById(int.Parse(s));
|
||||
if (domains.Length > 0)
|
||||
{
|
||||
for (int i = 0; i < domains.Length; i++)
|
||||
{
|
||||
string tempLink = "";
|
||||
if (library.NiceUrl(int.Parse(s)) == "")
|
||||
tempLink = "<em>N/A</em>";
|
||||
else if (int.Parse(s) != _document.Id)
|
||||
{
|
||||
string tempNiceUrl = library.NiceUrl(int.Parse(s));
|
||||
var niceUrlProvider = Umbraco.Web.UmbracoContext.Current.RoutingContext.NiceUrlProvider;
|
||||
var url = niceUrlProvider.GetNiceUrl(_document.Id);
|
||||
|
||||
string niceUrl = tempNiceUrl != "/" ? currentLink.Replace(tempNiceUrl.Replace(".aspx", ""), "") : currentLink;
|
||||
if (!niceUrl.StartsWith("/"))
|
||||
niceUrl = "/" + niceUrl;
|
||||
if (url == "#")
|
||||
{
|
||||
var parent = _document;
|
||||
while (parent.Published && parent.ParentId > 0)
|
||||
parent = new Document(_document.ParentId);
|
||||
if (parent.Published)
|
||||
l.Text = "<i>" + ui.Text("content", "parentNotPublished", "???", base.getUser()) + "</i>";
|
||||
else
|
||||
l.Text = "<i>" + ui.Text("content", "parentNotPublished", parent.Text, base.getUser()) + "</i>";
|
||||
return;
|
||||
}
|
||||
|
||||
tempLink = "http://" + domains[i].Name + niceUrl;
|
||||
}
|
||||
else
|
||||
tempLink = "http://" + domains[i].Name;
|
||||
l.Text = string.Format("<a href=\"{0}\" target=\"_blank\">{0}</a>", url);
|
||||
|
||||
domainText.Text += "<a href=\"" + tempLink + "\" target=\"_blank\">" + tempLink + "</a><br/>";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
l.Text = "<i>" + ui.Text("content", "parentNotPublished", dChild.Text, base.getUser()) + "</i>";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
l.Text = "<i>" + ui.Text("content", "itemNotPublished", base.getUser()) + "</i>";
|
||||
}
|
||||
var lb = new System.Text.StringBuilder();
|
||||
foreach (var altUrl in niceUrlProvider.GetAllAbsoluteNiceUrls(_document.Id).Where(u => u != url))
|
||||
lb.AppendFormat("<a href=\"{0}\" target=\"_blank\">{0}</a><br />", altUrl);
|
||||
domainText.Text = lb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the page of all controls and shows a simple message. Used if users don't have visible access to the page.
|
||||
|
||||
Reference in New Issue
Block a user