Updates DefaultUrlProvider so that hieararchy of nodes that are variant and invariant still generate URLs correctly

This commit is contained in:
Shannon
2018-04-26 23:34:06 +10:00
parent ffd85b4e94
commit cb3cba5b05
2 changed files with 44 additions and 87 deletions

View File

@@ -326,19 +326,23 @@
//get the selected variant and build the additional published variants
saveModel.publishVariations = [];
_.each(displayModel.variants,
function (d) {
//set the selected variant if this is current
if (d.current === true) {
saveModel.languageId = d.language.id;
}
if (d.publish === true) {
saveModel.publishVariations.push({
languageId: d.language.id,
segment: d.segment
});
}
});
//if there's more than 1 variant than we need to set the language and include the variants to publish
if (displayModel.variants.length > 1) {
_.each(displayModel.variants,
function (d) {
//set the selected variant if this is current
if (d.current === true) {
saveModel.languageId = d.language.id;
}
if (d.publish === true) {
saveModel.publishVariations.push({
languageId: d.language.id,
segment: d.segment
});
}
});
}
var propExpireDate = displayModel.removeDate;
var propReleaseDate = displayModel.releaseDate;

View File

@@ -7,6 +7,7 @@ using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.Routing
{
@@ -96,75 +97,43 @@ namespace Umbraco.Web.Routing
var node = umbracoContext.ContentCache.GetById(id);
var domainHelper = umbracoContext.GetDomainHelper(_siteDomainHelper);
//if this is invariant, continue as we used to
if (!node.ContentType.Variations.Has(ContentVariation.CultureNeutral))
var n = node;
var domainUris = domainHelper.DomainsForNode(n.Id, current, false);
while (domainUris == null && n != null) // n is null at root
{
// will not use cache if previewing
var route = umbracoContext.ContentCache.GetRouteById(id);
return GetOtherUrlsForSinglePath(route, id, domainHelper, current);
// move to parent node
n = n.Parent;
domainUris = n == null ? null : domainHelper.DomainsForNode(n.Id, current);
}
else
if (domainUris == null)
{
//this is variant, so we need to find the domains and use the cultures assigned to get the route/paths
//there are no domains, exit
return Enumerable.Empty<string>();
}
var n = node;
var domainUris = domainHelper.DomainsForNode(n.Id, current, false);
while (domainUris == null && n != null) // n is null at root
{
// move to parent node
n = n.Parent;
domainUris = n == null ? null : domainHelper.DomainsForNode(n.Id, current);
}
var result = new List<string>();
foreach (var d in domainUris)
{
//although we are passing in culture here, if any node in this path is invariant, it ignores the culture anyways so this is ok
var route = umbracoContext.ContentCache.GetRouteById(id, d.Culture);
if (route == null) continue;
if (domainUris == null)
{
//we can't continue, there are no domains assigned but this is a culture variant node
return Enumerable.Empty<string>();
}
//need to strip off the leading ID for the route
//TODO: Is there a nicer way to deal with this?
var pos = route.IndexOf('/');
var path = pos == 0 ? route : route.Substring(pos);
var result = new List<string>();
foreach(var d in domainUris)
{
var route = umbracoContext.ContentCache.GetRouteById(id, d.Culture);
if (route == null) continue;
//need to strip off the leading ID for the route
//TODO: Is there a nicer way to deal with this?
var pos = route.IndexOf('/');
var path = pos == 0 ? route : route.Substring(pos);
var uri = new Uri(CombinePaths(d.Uri.GetLeftPart(UriPartial.Path), path));
uri = UriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings);
result.Add(uri.ToString());
}
return result;
}
var uri = new Uri(CombinePaths(d.Uri.GetLeftPart(UriPartial.Path), path));
uri = UriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings);
result.Add(uri.ToString());
}
return result;
}
#endregion
#region Utilities
private IEnumerable<string> GetOtherUrlsForSinglePath(string route, int id, DomainHelper domainHelper, Uri current)
{
if (string.IsNullOrWhiteSpace(route))
{
_logger.Debug<DefaultUrlProvider>(() =>
$"Couldn't find any page with nodeId={id}. This is most likely caused by the page not being published.");
return null;
}
// extract domainUri and path
// route is /<path> or <domainRootId>/<path>
var pos = route.IndexOf('/');
var path = pos == 0 ? route : route.Substring(pos);
var domainUris = pos == 0 ? null : domainHelper.DomainsForNode(int.Parse(route.Substring(0, pos)), current);
// assemble the alternate urls from domainUris (maybe empty) and path
return AssembleUrls(domainUris, path).Select(uri => uri.ToString());
}
Uri AssembleUrl(DomainAndUri domainUri, string path, Uri current, UrlProviderMode mode)
{
@@ -231,22 +200,6 @@ namespace Umbraco.Web.Routing
return path == "/" ? path : path.TrimEnd('/');
}
// always build absolute urls unless we really cannot
IEnumerable<Uri> AssembleUrls(IEnumerable<DomainAndUri> domainUris, string path)
{
// no domain == no "other" url
if (domainUris == null)
return Enumerable.Empty<Uri>();
// if no domain was found and then we have no "other" url
// else return absolute urls, ignoring vdir at that point
var uris = domainUris.Select(domainUri => new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path)));
// UriFromUmbraco will handle vdir
// meaning it will add vdir into domain urls too!
return uris.Select(x => UriUtility.UriFromUmbraco(x, _globalSettings, _requestSettings));
}
#endregion
}
}