Merge branch 'v9/dev' into v9/task/package-refactor
# Conflicts: # src/Umbraco.Web.BackOffice/Controllers/PackageController.cs # src/Umbraco.Web.BackOffice/Controllers/PackageInstallController.cs
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
using System.Net;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.ActionsResults
|
||||
{
|
||||
// TODO: What is the purpose of this? Doesn't seem to add any benefit
|
||||
public class UmbracoProblemResult : ObjectResult
|
||||
{
|
||||
public UmbracoProblemResult(string message, HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError) : base(new {Message = message})
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.ActionsResults
|
||||
{
|
||||
// TODO: This should probably follow the same conventions as in aspnet core and use ProblemDetails
|
||||
// and ProblemDetails factory. See https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ControllerBase.cs#L1977
|
||||
// ProblemDetails is explicitly checked for in the application model.
|
||||
// In our base class UmbracoAuthorizedApiController the logic is there to create a ProblemDetails.
|
||||
// However, to do this will require changing how angular deals with errors since the response will
|
||||
// probably be different. Would just be better to follow the aspnet patterns.
|
||||
|
||||
/// <summary>
|
||||
/// Custom result to return a validation error message with required headers
|
||||
/// </summary>
|
||||
@@ -13,6 +22,11 @@ namespace Umbraco.Cms.Web.Common.ActionsResults
|
||||
/// </remarks>
|
||||
public class ValidationErrorResult : ObjectResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Typically this should not be used and just use the ValidationProblem method on the base controller class.
|
||||
/// </summary>
|
||||
/// <param name="errorMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static ValidationErrorResult CreateNotificationValidationErrorResult(string errorMessage)
|
||||
{
|
||||
var notificationModel = new SimpleNotificationModel
|
||||
@@ -23,6 +37,9 @@ namespace Umbraco.Cms.Web.Common.ActionsResults
|
||||
return new ValidationErrorResult(notificationModel);
|
||||
}
|
||||
|
||||
public ValidationErrorResult(ModelStateDictionary modelState)
|
||||
: this(new SimpleValidationModel(modelState.ToErrorDictionary())) { }
|
||||
|
||||
public ValidationErrorResult(object value, int statusCode) : base(value)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
@@ -32,6 +49,7 @@ namespace Umbraco.Cms.Web.Common.ActionsResults
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: Like here, shouldn't we use ProblemDetails?
|
||||
public ValidationErrorResult(string errorMessage, int statusCode) : base(new { Message = errorMessage })
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
|
||||
@@ -122,5 +122,27 @@ namespace Umbraco.Extensions
|
||||
true,
|
||||
constraints);
|
||||
}
|
||||
|
||||
public static void MapUmbracoSurfaceRoute(
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
Type controllerType,
|
||||
string rootSegment,
|
||||
string areaName,
|
||||
string defaultAction = "Index",
|
||||
bool includeControllerNameInRoute = true,
|
||||
object constraints = null)
|
||||
{
|
||||
// If there is an area name it's a plugin controller, and we should use the area name instead of surface
|
||||
string prefixPathSegment = areaName.IsNullOrWhiteSpace() ? "Surface" : areaName;
|
||||
|
||||
endpoints.MapUmbracoRoute(
|
||||
controllerType,
|
||||
rootSegment,
|
||||
areaName,
|
||||
prefixPathSegment,
|
||||
defaultAction,
|
||||
includeControllerNameInRoute,
|
||||
constraints);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Media;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Web.Common.DependencyInjection;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
{
|
||||
@@ -37,12 +38,23 @@ namespace Umbraco.Extensions
|
||||
string cropAlias) =>
|
||||
mediaItem.GetCropUrl(cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider);
|
||||
|
||||
public static string GetCropUrl(this MediaWithCrops mediaWithCrops, string cropAlias)
|
||||
=> ImageCropperTemplateCoreExtensions.GetCropUrl(mediaWithCrops, cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider);
|
||||
|
||||
/// <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>
|
||||
/// <returns>
|
||||
/// The image crop URL.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(
|
||||
this IPublishedContent mediaItem,
|
||||
string cropAlias,
|
||||
ImageCropperValue imageCropperValue)
|
||||
=> mediaItem.GetCropUrl(cropAlias, ImageUrlGenerator, imageCropperValue);
|
||||
ImageCropperValue imageCropperValue,
|
||||
string cropAlias)
|
||||
=> ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, imageCropperValue, cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying image processing service URL by the crop alias using the specified property containing the image cropper Json data on the IPublishedContent item.
|
||||
@@ -65,6 +77,9 @@ namespace Umbraco.Extensions
|
||||
string cropAlias) =>
|
||||
mediaItem.GetCropUrl(propertyAlias, cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider);
|
||||
|
||||
public static string GetCropUrl(this MediaWithCrops mediaWithCrops, string propertyAlias, string cropAlias)
|
||||
=> ImageCropperTemplateCoreExtensions.GetCropUrl(mediaWithCrops, propertyAlias, cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying image processing service URL from the IPublishedContent item.
|
||||
/// </summary>
|
||||
@@ -326,6 +341,6 @@ namespace Umbraco.Extensions
|
||||
this MediaWithCrops mediaWithCrops,
|
||||
string alias,
|
||||
string cacheBusterValue = null)
|
||||
=> mediaWithCrops.GetLocalCropUrl(alias, ImageUrlGenerator, cacheBusterValue);
|
||||
=> mediaWithCrops.GetLocalCropUrl(alias, cacheBusterValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Web.Common.DependencyInjection;
|
||||
|
||||
@@ -70,5 +72,11 @@ namespace Umbraco.Extensions
|
||||
public static bool IsVisible(this IPublishedElement content) => content.IsVisible(PublishedValueFallback);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a property.
|
||||
/// </summary>
|
||||
public static TValue ValueFor<TModel, TValue>(this TModel model, Expression<Func<TModel, TValue>> property, string culture = null, string segment = null, Fallback fallback = default, TValue defaultValue = default)
|
||||
where TModel : IPublishedElement =>
|
||||
model.ValueFor(PublishedValueFallback, property, culture, segment, fallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Media;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
{
|
||||
@@ -36,9 +38,35 @@ namespace Umbraco.Extensions
|
||||
return mediaItem.GetCropUrl(imageUrlGenerator, publishedValueFallback, publishedUrlProvider, cropAlias: cropAlias, useCropDimensions: true);
|
||||
}
|
||||
|
||||
public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias, IImageUrlGenerator imageUrlGenerator, ImageCropperValue imageCropperValue)
|
||||
public static string GetCropUrl(
|
||||
this MediaWithCrops mediaWithCrops,
|
||||
string cropAlias,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
IPublishedValueFallback publishedValueFallback,
|
||||
IPublishedUrlProvider publishedUrlProvider)
|
||||
{
|
||||
return mediaItem.Url().GetCropUrl(imageUrlGenerator, imageCropperValue, cropAlias: cropAlias, useCropDimensions: true);
|
||||
return mediaWithCrops.GetCropUrl(imageUrlGenerator, publishedValueFallback, publishedUrlProvider, cropAlias: cropAlias, useCropDimensions: true);
|
||||
}
|
||||
|
||||
/// <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="imageUrlGenerator">The image URL generator.</param>
|
||||
/// <returns>
|
||||
/// The image crop URL.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(
|
||||
this IPublishedContent mediaItem,
|
||||
ImageCropperValue imageCropperValue,
|
||||
string cropAlias,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
IPublishedValueFallback publishedValueFallback,
|
||||
IPublishedUrlProvider publishedUrlProvider)
|
||||
{
|
||||
return mediaItem.GetCropUrl(imageUrlGenerator, publishedValueFallback, publishedUrlProvider, imageCropperValue, true, cropAlias: cropAlias, useCropDimensions: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -70,6 +98,16 @@ namespace Umbraco.Extensions
|
||||
return mediaItem.GetCropUrl( imageUrlGenerator, publishedValueFallback, publishedUrlProvider, propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
|
||||
}
|
||||
|
||||
public static string GetCropUrl(this MediaWithCrops mediaWithCrops,
|
||||
IPublishedValueFallback publishedValueFallback,
|
||||
IPublishedUrlProvider publishedUrlProvider,
|
||||
string propertyAlias,
|
||||
string cropAlias,
|
||||
IImageUrlGenerator imageUrlGenerator)
|
||||
{
|
||||
return mediaWithCrops.GetCropUrl(imageUrlGenerator, publishedValueFallback, publishedUrlProvider, propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying image processing service URL from the IPublishedContent item.
|
||||
/// </summary>
|
||||
@@ -145,7 +183,55 @@ namespace Umbraco.Extensions
|
||||
ImageCropRatioMode? ratioMode = null,
|
||||
bool upScale = true)
|
||||
{
|
||||
if (mediaItem == null) throw new ArgumentNullException("mediaItem");
|
||||
return mediaItem.GetCropUrl(imageUrlGenerator, publishedValueFallback, publishedUrlProvider, null, false, width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
public static string GetCropUrl(
|
||||
this MediaWithCrops mediaWithCrops,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
IPublishedValueFallback publishedValueFallback,
|
||||
IPublishedUrlProvider publishedUrlProvider,
|
||||
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,
|
||||
ImageCropRatioMode? ratioMode = null,
|
||||
bool upScale = true)
|
||||
{
|
||||
if (mediaWithCrops == null) throw new ArgumentNullException(nameof(mediaWithCrops));
|
||||
|
||||
return mediaWithCrops.Content.GetCropUrl(imageUrlGenerator, publishedValueFallback, publishedUrlProvider, mediaWithCrops.LocalCrops, false, width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
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,
|
||||
ImageCropRatioMode? ratioMode = null,
|
||||
bool upScale = true)
|
||||
{
|
||||
if (mediaItem == null) throw new ArgumentNullException(nameof(mediaItem));
|
||||
|
||||
var cacheBusterValue = cacheBuster ? mediaItem.UpdateDate.ToFileTimeUtc().ToString(CultureInfo.InvariantCulture) : null;
|
||||
|
||||
@@ -154,31 +240,38 @@ namespace Umbraco.Extensions
|
||||
|
||||
var mediaItemUrl = mediaItem.MediaUrl(publishedUrlProvider, propertyAlias: propertyAlias);
|
||||
|
||||
//get the default obj from the value converter
|
||||
var cropperValue = mediaItem.Value(publishedValueFallback, propertyAlias);
|
||||
|
||||
//is it strongly typed?
|
||||
var stronglyTyped = cropperValue as ImageCropperValue;
|
||||
if (stronglyTyped != null)
|
||||
// Only get crops from media when required and used
|
||||
if (localCropsOnly == false && (imageCropMode == ImageCropMode.Crop || imageCropMode == null))
|
||||
{
|
||||
return GetCropUrl(
|
||||
mediaItemUrl, imageUrlGenerator, stronglyTyped, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
|
||||
cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
//this shouldn't be the case but we'll check
|
||||
var jobj = cropperValue as JObject;
|
||||
if (jobj != null)
|
||||
{
|
||||
stronglyTyped = jobj.ToObject<ImageCropperValue>();
|
||||
return GetCropUrl(
|
||||
mediaItemUrl, imageUrlGenerator, stronglyTyped, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
|
||||
cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
//it's a single string
|
||||
return GetCropUrl(
|
||||
mediaItemUrl, imageUrlGenerator, width, height, mediaItemUrl, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
|
||||
mediaItemUrl, imageUrlGenerator, localCrops, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
|
||||
cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
@@ -259,6 +352,7 @@ namespace Umbraco.Extensions
|
||||
{
|
||||
cropDataSet = imageCropperValue.DeserializeImageCropperValue();
|
||||
}
|
||||
|
||||
return GetCropUrl(
|
||||
imageUrl, imageUrlGenerator, cropDataSet, width, height, cropAlias, quality, imageCropMode,
|
||||
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
@@ -402,11 +496,5 @@ namespace Umbraco.Extensions
|
||||
|
||||
return imageUrlGenerator.GetImageUrl(options);
|
||||
}
|
||||
|
||||
public static string GetLocalCropUrl(this MediaWithCrops mediaWithCrops, string alias, IImageUrlGenerator imageUrlGenerator, string cacheBusterValue)
|
||||
{
|
||||
return mediaWithCrops.LocalCrops.Src + mediaWithCrops.LocalCrops.GetCropUrl(alias, imageUrlGenerator, cacheBusterValue: cacheBusterValue);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
55
src/Umbraco.Web.Common/Extensions/ModelStateExtensions.cs
Normal file
55
src/Umbraco.Web.Common/Extensions/ModelStateExtensions.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
{
|
||||
public static class ModelStateExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if there are any model errors on any fields containing the prefix
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
/// <param name="prefix"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValid(this ModelStateDictionary state, string prefix) =>
|
||||
state.Where(v => v.Key.StartsWith(prefix + ".")).All(v => !v.Value.Errors.Any());
|
||||
|
||||
public static IDictionary<string, object> ToErrorDictionary(this ModelStateDictionary modelState)
|
||||
{
|
||||
var modelStateError = new Dictionary<string, object>();
|
||||
foreach (KeyValuePair<string, ModelStateEntry> keyModelStatePair in modelState)
|
||||
{
|
||||
var key = keyModelStatePair.Key;
|
||||
ModelErrorCollection errors = keyModelStatePair.Value.Errors;
|
||||
if (errors != null && errors.Count > 0)
|
||||
{
|
||||
modelStateError.Add(key, errors.Select(error => error.ErrorMessage));
|
||||
}
|
||||
}
|
||||
return modelStateError;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the ModelState to JSON for JavaScript to interrogate the errors
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
/// <returns></returns>
|
||||
public static JsonResult ToJsonErrors(this ModelStateDictionary state) =>
|
||||
new JsonResult(new
|
||||
{
|
||||
success = state.IsValid.ToString().ToLower(),
|
||||
failureType = "ValidationError",
|
||||
validationErrors = from e in state
|
||||
where e.Value.Errors.Count > 0
|
||||
select new
|
||||
{
|
||||
name = e.Key,
|
||||
errors = e.Value.Errors.Select(x => x.ErrorMessage)
|
||||
.Concat(
|
||||
e.Value.Errors.Where(x => x.Exception != null).Select(x => x.Exception.Message))
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Cms.Core.WebAssets;
|
||||
using Umbraco.Cms.Web.Common.Controllers;
|
||||
@@ -204,6 +205,56 @@ namespace Umbraco.Extensions
|
||||
return $"{version}.{runtimeMinifier.CacheBuster}".GenerateHash();
|
||||
}
|
||||
|
||||
public static IHtmlContent GetCropUrl(this IUrlHelper urlHelper, IPublishedContent mediaItem, string cropAlias, bool htmlEncode = true)
|
||||
{
|
||||
if (mediaItem == null)
|
||||
{
|
||||
return HtmlString.Empty;
|
||||
}
|
||||
|
||||
var url = mediaItem.GetCropUrl(cropAlias: cropAlias, useCropDimensions: true);
|
||||
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
|
||||
}
|
||||
|
||||
public static IHtmlContent GetCropUrl(this IUrlHelper urlHelper, IPublishedContent mediaItem, string propertyAlias, string cropAlias, bool htmlEncode = true)
|
||||
{
|
||||
if (mediaItem == null)
|
||||
{
|
||||
return HtmlString.Empty;
|
||||
}
|
||||
|
||||
var url = mediaItem.GetCropUrl(propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
|
||||
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
|
||||
}
|
||||
|
||||
public static IHtmlContent GetCropUrl(this IUrlHelper urlHelper,
|
||||
IPublishedContent mediaItem,
|
||||
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,
|
||||
ImageCropRatioMode? ratioMode = null,
|
||||
bool upScale = true,
|
||||
bool htmlEncode = true)
|
||||
{
|
||||
if (mediaItem == null)
|
||||
{
|
||||
return HtmlString.Empty;
|
||||
}
|
||||
|
||||
var url = mediaItem.GetCropUrl(width, height, propertyAlias, cropAlias, quality, imageCropMode,
|
||||
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode,
|
||||
upScale);
|
||||
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
|
||||
}
|
||||
|
||||
public static IHtmlContent GetCropUrl(this IUrlHelper urlHelper,
|
||||
ImageCropperValue imageCropperValue,
|
||||
string cropAlias,
|
||||
|
||||
@@ -362,7 +362,7 @@ namespace Umbraco.Cms.Web.Common.Macros
|
||||
$"Executing PartialView: MacroSource=\"{model.MacroSource}\".",
|
||||
"Executed PartialView.",
|
||||
() => _partialViewMacroEngine.Execute(model, content),
|
||||
() => _textService.Localize("errors/macroErrorLoadingPartialView", new[] { model.MacroSource }));
|
||||
() => _textService.Localize("errors", "macroErrorLoadingPartialView", new[] { model.MacroSource }));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user