/// <summary> /// Gets the URL of a published content. /// </summary> /// <param name="id">The published content identifier.</param> /// <param name="mode">The URL mode.</param> /// <param name="culture">A culture.</param> /// <param name="current">The current absolute URL.</param> /// <returns>The URL for the published content.</returns> public string GetUrl(int id, UrlMode mode = UrlMode.Default, string?culture = null, Uri?current = null) => GetUrl(GetDocument(id), mode, culture, current);
/// <summary> /// Gets the url for a media. /// </summary> /// <param name="content">The content item.</param> /// <param name="publishedUrlProvider">The published url provider.</param> /// <param name="culture">The culture (use current culture by default).</param> /// <param name="mode">The url mode (use site configuration by default).</param> /// <param name="propertyAlias">The alias of the property (use 'umbracoFile' by default).</param> /// <returns>The url for the media.</returns> /// <remarks> /// <para>The value of this property is contextual. It depends on the 'current' request uri, /// if any. In addition, when the content type is multi-lingual, this is the url for the /// specified culture. Otherwise, it is the invariant url.</para> /// </remarks> public static string MediaUrl(this IPublishedContent content, IPublishedUrlProvider publishedUrlProvider, string?culture = null, UrlMode mode = UrlMode.Default, string propertyAlias = Constants.Conventions.Media.File) { if (publishedUrlProvider == null) { throw new ArgumentNullException(nameof(publishedUrlProvider)); } return(publishedUrlProvider.GetMediaUrl(content, mode, culture, propertyAlias)); }
private Uri AssembleUrl(DomainAndUri?domainUri, string path, Uri current, UrlMode mode) { Uri uri; // ignore vdir at that point, UriFromUmbraco will do it if (domainUri == null) // no domain was found { if (current == null) { mode = UrlMode.Relative; // best we can do } switch (mode) { case UrlMode.Absolute: uri = new Uri(current !.GetLeftPart(UriPartial.Authority) + path); break; case UrlMode.Relative: case UrlMode.Auto: uri = new Uri(path, UriKind.Relative); break; default: throw new ArgumentOutOfRangeException(nameof(mode)); } } else // a domain was found { if (mode == UrlMode.Auto) { //this check is a little tricky, we can't just compare domains if (current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority)) { mode = UrlMode.Relative; } else { mode = UrlMode.Absolute; } } switch (mode) { case UrlMode.Absolute: uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path)); break; case UrlMode.Relative: uri = new Uri(CombinePaths(domainUri.Uri.AbsolutePath, path), UriKind.Relative); break; default: throw new ArgumentOutOfRangeException(nameof(mode)); } } // UriFromUmbraco will handle vdir // meaning it will add vdir into domain URLs too! return(_uriUtility.UriFromUmbraco(uri, _requestSettings)); }
/// <summary> /// Gets the URL of a media item. /// </summary> /// <param name="id"></param> /// <param name="mode"></param> /// <param name="culture"></param> /// <param name="propertyAlias"></param> /// <param name="current"></param> /// <returns></returns> public string GetMediaUrl(Guid id, UrlMode mode = UrlMode.Default, string?culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri?current = null) => GetMediaUrl(GetMedia(id), mode, culture, propertyAlias, current);
/// <summary> /// Initializes a new instance of the <see cref="UrlProvider"/> class with an Umbraco context and a list of url providers. /// </summary> /// <param name="umbracoContext">The Umbraco context.</param> /// <param name="urlProviders">The list of url providers.</param> /// <param name="mediaUrlProviders">The list of media url providers</param> /// <param name="variationContextAccessor">The current variation accessor.</param> /// <param name="mode">An optional provider mode.</param> public UrlProvider(UmbracoContext umbracoContext, IEnumerable <IUrlProvider> urlProviders, IEnumerable <IMediaUrlProvider> mediaUrlProviders, IVariationContextAccessor variationContextAccessor, UrlMode mode = UrlMode.Auto) { _umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext)); _urlProviders = urlProviders; _mediaUrlProviders = mediaUrlProviders; _variationContextAccessor = variationContextAccessor; Mode = mode; }
internal UrlInfo GetUrlFromRoute(string route, UmbracoContext umbracoContext, int id, Uri current, UrlMode 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); } // 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 : DomainUtilities.DomainForNode(umbracoContext.PublishedSnapshot.Domains, _siteDomainHelper, 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 crop URL by using only the specified <paramref name="imageCropperValue" />. /// </summary> /// <param name="mediaItem">The media item.</param> /// <param name="imageCropperValue">The image cropper value.</param> /// <param name="cropAlias">The crop alias.</param> /// <param name="urlMode">The url mode.</param> /// <returns> /// The image crop URL. /// </returns> public static string GetCropUrl( this IPublishedContent mediaItem, ImageCropperValue imageCropperValue, string cropAlias, UrlMode urlMode = UrlMode.Default) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, imageCropperValue, cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider, urlMode);
/// <summary> /// Gets the underlying image processing service URL by the crop alias (from the "umbracoFile" property alias) on the /// IPublishedContent item. /// </summary> /// <param name="mediaItem">The IPublishedContent item.</param> /// <param name="cropAlias">The crop alias e.g. thumbnail.</param> /// <param name="urlMode">The url mode.</param> /// <returns> /// The URL of the cropped image. /// </returns> public static string?GetCropUrl( this IPublishedContent mediaItem, string cropAlias, UrlMode urlMode = UrlMode.Default) => mediaItem.GetCropUrl(cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider, urlMode);
public override UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current) { // If this is a virtual node itself, no need to handle it - should return normal URL var hasVirtualNodeInPath = false; foreach (var item in content.Ancestors()) { if (item.IsVirtualNode()) { hasVirtualNodeInPath = true; break; } } return(hasVirtualNodeInPath ? ConstructUrl(umbracoContext, content, mode, culture, current) : base.GetUrl(umbracoContext, content, mode, culture, current)); }
private UrlInfo ConstructUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current) { string path = content.Path; // Keep path items in par with path segments in url // If we are hiding the top node from path, then we'll have to skip one path item (the root). // If we are not, then we'll have to skip two path items (root and home) var hideTopNode = ConfigurationManager.AppSettings.Get("Umbraco.Core.HideTopLevelNodeFromPath"); if (String.IsNullOrEmpty(hideTopNode)) { hideTopNode = "false"; } var pathItemsToSkip = ((hideTopNode == "true") ? 2 : 1); // Get the path ids but skip what's needed in order to have the same number of elements in url and path ids var pathIds = path.Split(',').Skip(pathItemsToSkip).Reverse().ToArray(); // Get the default url // DO NOT USE THIS - RECURSES: string url = content.Url; // https://our.umbraco.org/forum/developers/extending-umbraco/73533-custom-url-provider-stackoverflowerror // https://our.umbraco.org/forum/developers/extending-umbraco/66741-iurlprovider-cannot-evaluate-expression-because-the-current-thread-is-in-a-stack-overflow-state var url = base.GetUrl(umbracoContext, content, mode, culture, current); var urlText = url.Text; // If we come from an absolute URL, strip the host part and keep it so that we can append // it again when returing the URL. var hostPart = ""; if (urlText.StartsWith("http")) { var uri = new Uri(url.Text); urlText = urlText.Replace(uri.GetLeftPart(UriPartial.Authority), ""); hostPart = uri.GetLeftPart(UriPartial.Authority); } // Strip leading and trailing slashes if (urlText.EndsWith("/")) { urlText = urlText.Substring(0, urlText.Length - 1); } if (urlText.StartsWith("/")) { urlText = urlText.Substring(1, urlText.Length - 1); } // Now split the url. We should have as many elements as those in pathIds. string[] urlParts = urlText.Split('/').Reverse().ToArray(); // Iterate the url parts. Check the corresponding path id and if the document that corresponds there // is of a type that must be excluded from the path, just make that url part an empty string. var i = 0; foreach (var urlPart in urlParts) { var currentItem = umbracoContext.Content.GetById(int.Parse(pathIds[i])); // Omit any virtual node unless it's leaf level (we still need this otherwise it will be pointing to parent's URL) if (currentItem.IsVirtualNode() && i > 0) { urlParts[i] = ""; } i++; } // Reconstruct the url, leaving out all parts that we emptied above. This // will be our final url, without the parts that correspond to excluded nodes. string finalUrl = String.Join("/", urlParts.Reverse().Where(x => x != "").ToArray()); // Just in case - check if there are trailing and leading slashes and add them if not if (!finalUrl.EndsWith("/") && _requestSettings.AddTrailingSlash) { finalUrl += "/"; } if (!finalUrl.StartsWith("/")) { finalUrl = "/" + finalUrl; } finalUrl = String.Concat(hostPart, finalUrl); // Voila return(new UrlInfo(finalUrl, true, culture)); }
/// <summary> /// Gets the url for a media. /// </summary> /// <param name="content">The content item.</param> /// <param name="culture">The culture (use current culture by default).</param> /// <param name="mode">The url mode (use site configuration by default).</param> /// <param name="propertyAlias">The alias of the property (use 'umbracoFile' by default).</param> /// <returns>The url for the media.</returns> /// <remarks> /// <para>The value of this property is contextual. It depends on the 'current' request uri, /// if any. In addition, when the content type is multi-lingual, this is the url for the /// specified culture. Otherwise, it is the invariant url.</para> /// </remarks> public static string MediaUrl(this IPublishedContent content, string culture = null, UrlMode mode = UrlMode.Default, string propertyAlias = Constants.Conventions.Media.File) { var umbracoContext = Composing.Current.UmbracoContext; if (umbracoContext == null) { throw new InvalidOperationException("Cannot resolve a Url when Current.UmbracoContext is null."); } if (umbracoContext.UrlProvider == null) { throw new InvalidOperationException("Cannot resolve a Url when Current.UmbracoContext.UrlProvider is null."); } return(umbracoContext.UrlProvider.GetMediaUrl(content, mode, culture, propertyAlias)); }
public static IHtmlContent GetCropUrl(this IUrlHelper urlHelper, IPublishedContent mediaItem, string propertyAlias, string cropAlias, bool htmlEncode = true, UrlMode urlMode = UrlMode.Default) { if (mediaItem == null) { return(HtmlString.Empty); } var url = mediaItem.GetCropUrl(propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true, urlMode: urlMode); return(CreateHtmlString(url, htmlEncode)); }
/// <summary> /// Gets the nice url of a custom routed published content item /// </summary> public UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current) { if (umbracoContext.PublishedRequest == null) { return(null); } if (umbracoContext.PublishedRequest.PublishedContent == null) { return(null); } var virtualPage = umbracoContext.PublishedRequest.PublishedContent as ArticulateVirtualPage; if (virtualPage == null) { return(null); } //if the ids match, then return the assigned url return(content.Id == virtualPage.Id ? UrlInfo.Url(virtualPage.Url, culture) : null); }
// note - at the moment we seem to accept pretty much anything as an alias // without any form of validation ... could even prob. kill the XPath ... // ok, this is somewhat experimental and is NOT enabled by default #region GetUrl /// <inheritdoc /> public UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current) { return(null); // we have nothing to say }
public static string GetCropUrl(this MediaWithCrops mediaWithCrops, string propertyAlias, string cropAlias, UrlMode urlMode = UrlMode.Default) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaWithCrops, propertyAlias, cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider, urlMode);
private static string?GetCropUrl( this IPublishedContent mediaItem, IImageUrlGenerator imageUrlGenerator, IPublishedValueFallback publishedValueFallback, IPublishedUrlProvider publishedUrlProvider, ImageCropperValue?localCrops, bool localCropsOnly, int?width = null, int?height = null, string propertyAlias = Constants.Conventions.Media.File, string?cropAlias = null, int?quality = null, ImageCropMode?imageCropMode = null, ImageCropAnchor?imageCropAnchor = null, bool preferFocalPoint = false, bool useCropDimensions = false, bool cacheBuster = true, string?furtherOptions = null, UrlMode urlMode = UrlMode.Default) { if (mediaItem == null) { throw new ArgumentNullException(nameof(mediaItem)); } if (mediaItem.HasProperty(propertyAlias) == false || mediaItem.HasValue(propertyAlias) == false) { return(null); } var mediaItemUrl = mediaItem.MediaUrl(publishedUrlProvider, propertyAlias: propertyAlias, mode: urlMode); // Only get crops from media when required and used if (localCropsOnly == false && (imageCropMode == ImageCropMode.Crop || imageCropMode == null)) { // Get the default cropper value from the value converter var cropperValue = mediaItem.Value(publishedValueFallback, propertyAlias); var mediaCrops = cropperValue as ImageCropperValue; if (mediaCrops == null && cropperValue is JObject jobj) { mediaCrops = jobj.ToObject <ImageCropperValue>(); } if (mediaCrops == null && cropperValue is string imageCropperValue && string.IsNullOrEmpty(imageCropperValue) == false && imageCropperValue.DetectIsJson()) { mediaCrops = imageCropperValue.DeserializeImageCropperValue(); } // Merge crops if (localCrops == null) { localCrops = mediaCrops; } else if (mediaCrops != null) { localCrops = localCrops.Merge(mediaCrops); } } var cacheBusterValue = cacheBuster ? mediaItem.UpdateDate.ToFileTimeUtc().ToString(CultureInfo.InvariantCulture) : null; return(GetCropUrl( mediaItemUrl, imageUrlGenerator, localCrops, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions)); }
/// <inheritdoc /> public virtual UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current) { if (!current.IsAbsoluteUri) { throw new ArgumentException("Current url must be absolute.", nameof(current)); } // will not use cache if previewing var route = umbracoContext.Content.GetRouteById(content.Id, culture); return(GetUrlFromRoute(route, umbracoContext, content.Id, current, mode, culture)); }
/// <summary> /// Gets the underlying image processing service URL by the crop alias (from the "umbracoFile" property alias in the /// MediaWithCrops content item) on the MediaWithCrops item. /// </summary> /// <param name="mediaWithCrops">The MediaWithCrops item.</param> /// <param name="cropAlias">The crop alias e.g. thumbnail.</param> /// <param name="urlMode">The url mode.</param> /// <returns> /// The URL of the cropped image. /// </returns> public static string?GetCropUrl(this MediaWithCrops mediaWithCrops, string cropAlias, UrlMode urlMode = UrlMode.Default) => mediaWithCrops.GetCropUrl(cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider, urlMode);
// note - at the moment we seem to accept pretty much anything as an alias // without any form of validation ... could even prob. kill the XPath ... // ok, this is somewhat experimental and is NOT enabled by default #region GetUrl /// <inheritdoc /> public UrlInfo?GetUrl(IPublishedContent content, UrlMode mode, string?culture, Uri current) { return(null); // we have nothing to say }