Пример #1
0
 /// <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));
        }
Пример #4
0
 /// <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);
Пример #5
0
        /// <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);
Пример #9
0
        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));
        }
Пример #10
0
        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));
        }
Пример #11
0
        /// <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));
        }
Пример #12
0
        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));
        }
Пример #13
0
        /// <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);
        }
Пример #14
0
        // 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
        }