/// <summary> /// Gets the other urls of a published content. /// </summary> /// <param name="umbracoContext">The Umbraco context.</param> /// <param name="id">The published content id.</param> /// <param name="current">The current absolute url.</param> /// <returns>The other urls for the published content.</returns> /// <remarks> /// <para>Other urls are those that <c>GetUrl</c> would not return in the current context, but would be valid /// urls for the node in other contexts (different domain for current request, umbracoUrlAlias...).</para> /// </remarks> public virtual IEnumerable <UrlInfo> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current) { var node = umbracoContext.ContentCache.GetById(id); if (node == null) { yield break; } var domainHelper = umbracoContext.GetDomainHelper(_siteDomainHelper); // look for domains, walking up the tree var n = node; var domainUris = domainHelper.DomainsForNode(n.Id, current, false); while (domainUris == null && n != null) // n is null at root { n = n.Parent; // move to parent node domainUris = n == null ? null : domainHelper.DomainsForNode(n.Id, current, excludeDefault: true); } // no domains = exit if (domainUris == null) { yield break; } foreach (var d in domainUris) { var culture = d?.Culture?.Name; //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, culture); if (route == null) { continue; } //need to strip off the leading ID for the route if it exists (occurs if the route is for a node with a domain assigned) 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); yield return(UrlInfo.Url(uri.ToString(), culture)); } }
internal UrlInfo GetUrlFromRoute(string route, UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode, string culture) { if (string.IsNullOrWhiteSpace(route)) { _logger.Debug <DefaultUrlProvider>("Couldn't find any page with nodeId={NodeId}. This is most likely caused by the page not being published.", id); return(null); } var domainHelper = umbracoContext.GetDomainHelper(_siteDomainHelper); // extract domainUri and path // route is /<path> or <domainRootId>/<path> var pos = route.IndexOf('/'); var path = pos == 0 ? route : route.Substring(pos); var domainUri = pos == 0 ? null : domainHelper.DomainForNode(int.Parse(route.Substring(0, pos)), current, culture); // assemble the url from domainUri (maybe null) and path var url = AssembleUrl(domainUri, path, current, mode).ToString(); return(UrlInfo.Url(url, culture)); }
/// <summary> /// Gets the other urls of a published content. /// </summary> /// <param name="umbracoContext">The Umbraco context.</param> /// <param name="id">The published content id.</param> /// <param name="current">The current absolute url.</param> /// <returns>The other urls for the published content.</returns> /// <remarks> /// <para>Other urls are those that <c>GetUrl</c> would not return in the current context, but would be valid /// urls for the node in other contexts (different domain for current request, umbracoUrlAlias...).</para> /// </remarks> public IEnumerable <UrlInfo> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current) { var node = umbracoContext.ContentCache.GetById(id); if (node == null) { yield break; } if (!node.HasProperty(Constants.Conventions.Content.UrlAlias)) { yield break; } var domainHelper = umbracoContext.GetDomainHelper(_siteDomainHelper); // look for domains, walking up the tree 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, excludeDefault: false); } // determine whether the alias property varies var varies = node.GetProperty(Constants.Conventions.Content.UrlAlias).PropertyType.VariesByCulture(); if (domainUris == null) { // no domain // if the property is invariant, then url "/<alias>" is ok // if the property varies, then what are we supposed to do? // the content finder may work, depending on the 'current' culture, // but there's no way we can return something meaningful here if (varies) { yield break; } var umbracoUrlName = node.Value <string>(Constants.Conventions.Content.UrlAlias); if (string.IsNullOrWhiteSpace(umbracoUrlName)) { yield break; } var path = "/" + umbracoUrlName; var uri = new Uri(path, UriKind.Relative); yield return(UrlInfo.Url(UriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString())); } else { // some domains: one url per domain, which is "<domain>/<alias>" foreach (var domainUri in domainUris) { // if the property is invariant, get the invariant value, url is "<domain>/<invariant-alias>" // if the property varies, get the variant value, url is "<domain>/<variant-alias>" // but! only if the culture is published, else ignore if (varies && !node.HasCulture(domainUri.Culture.Name)) { continue; } var umbracoUrlName = varies ? node.Value <string>(Constants.Conventions.Content.UrlAlias, culture: domainUri.Culture.Name) : node.Value <string>(Constants.Conventions.Content.UrlAlias); if (string.IsNullOrWhiteSpace(umbracoUrlName)) { continue; } var path = "/" + umbracoUrlName; var uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path)); yield return(UrlInfo.Url(UriUtility.UriFromUmbraco(uri, _globalSettings, _requestConfig).ToString(), domainUri.Culture.Name)); } } }