Last active
September 12, 2023 18:04
-
-
Save MineshS/7aeb9eb73192bc00147ca469c8880a31 to your computer and use it in GitHub Desktop.
Edge Image Tag Helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Reflection; | |
using EPiServer.Core; | |
using EPiServer.Web.Routing; | |
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.AspNetCore.Mvc.ViewFeatures; | |
using Microsoft.AspNetCore.Razor.TagHelpers; | |
using Microsoft.Extensions.Hosting; | |
using Netcel.Optimizely.Core.Interfaces; | |
using Netcel.Optimizely.Domain.Attributes; | |
using Netcel.Optimizely.Domain.Models.Interfaces; | |
using Netcel.Optimizely.Domain.Models.Media; | |
namespace Netcel.Optimizely.Core.TagHelpers; | |
[HtmlTargetElement("img", Attributes = "image-for")] | |
public class EdgeImageTagHelper : TagHelper | |
{ | |
private readonly IUrlResolver _urlResolver; | |
private readonly IContentLoaderService _contentLoader; | |
private readonly IWebHostEnvironment _webHostEnvironment; | |
public ModelExpression ImageFor { get; set; } | |
public string CssClass { get; set; } | |
public string Fit {get; set; } | |
public EdgeImageTagHelper(IUrlResolver urlResolver, IContentLoaderService contentLoader, IWebHostEnvironment webHostEnvironment) | |
{ | |
_urlResolver = urlResolver; | |
_contentLoader = contentLoader; | |
_webHostEnvironment = webHostEnvironment; | |
} | |
public override void Process(TagHelperContext context, TagHelperOutput output) | |
{ | |
if (ImageFor.Model is not ContentReference edgeImage) return; | |
if(ContentReference.IsNullOrEmpty(edgeImage)) return; | |
if(!_contentLoader.TryGet(edgeImage, out ImageFile imageFile)) return; | |
var actualUrl = _urlResolver.GetUrl(edgeImage); | |
var property = ImageFor | |
.Metadata | |
.ContainerType | |
.GetProperties() | |
.FirstOrDefault(x => x.Name == ImageFor.Metadata.PropertyName); | |
if (property == null) | |
{ | |
RenderNonResponsiveImage(output, actualUrl); | |
return; | |
} | |
var shouldSkipEdgeResizing = _webHostEnvironment.IsDevelopment() || _contentLoader.IsContentInEditMode; | |
var imageSize = property.GetCustomAttributes<ImageSizeAttribute>().ToList(); | |
var imageSizes = property.GetCustomAttribute<ImageSizesAttribute>(); | |
var defaultImageSize = imageSize.FirstOrDefault(x => x.IsDefault); | |
if (defaultImageSize == null) | |
{ | |
RenderNonResponsiveImage(output, actualUrl); | |
return; | |
} | |
var srcSetUrls = imageSize | |
.OrderBy(x => x.Width) | |
.Select(s => GetEdgeUrl(actualUrl, s.Width, shouldSkipEdgeResizing)).ToList(); | |
SetAttribute(output, "src", GetEdgeUrl(actualUrl, defaultImageSize.Width, shouldSkipEdgeResizing, true)); | |
SetAttribute(output, "srcset", string.Join(",", srcSetUrls)); | |
if (imageSizes != null) SetAttribute(output, "sizes", imageSizes.Sizes); | |
SetAttribute(output, "alt", imageFile.AlternativeText); | |
SetAttribute(output, "loading", "lazy"); | |
SetAttribute(output, "decoding", "auto"); | |
SetAttribute(output, "fetchpriority", "auto"); | |
SetAttribute(output, "class", CssClass); | |
if (imageFile is not IHasPixelSize pixelSize) return; | |
if (pixelSize.Width > 0) | |
{ | |
SetAttribute(output,"width", pixelSize.Width.ToString()); | |
} | |
if (pixelSize.Height > 0) | |
{ | |
SetAttribute(output, "height", pixelSize.Height.ToString()); | |
} | |
} | |
private void RenderNonResponsiveImage(TagHelperOutput output, string url) | |
{ | |
SetAttribute(output, "src", url); | |
SetAttribute(output, "class", CssClass); | |
} | |
private string GetEdgeUrl(string actualUrl, int width, bool isLocal, bool isDefault = false) | |
{ | |
if (!isLocal) | |
{ | |
return isDefault | |
? $"/cdn-cgi/image/{GetEdgeImageOptions(width)}{actualUrl}" | |
: $"/cdn-cgi/image/{GetEdgeImageOptions(width)}{actualUrl} {width}w"; | |
} | |
else | |
{ | |
return isDefault | |
? $"{actualUrl}?{GetLocalImageOptions(width)}" | |
: $"{actualUrl}?{GetLocalImageOptions(width)} {width}w"; | |
} | |
} | |
private string GetLocalImageOptions(int width) | |
{ | |
var options = $"width={width}"; | |
if (!string.IsNullOrWhiteSpace(Fit)) | |
{ | |
options += $"&fit={Fit}"; | |
} | |
return options; | |
} | |
private string GetEdgeImageOptions(int width) | |
{ | |
var options = string.Empty; | |
if (!string.IsNullOrWhiteSpace(Fit)) | |
{ | |
options = $"fit={Fit},"; | |
} | |
options += $"width={width}"; | |
return options; | |
} | |
private void SetAttribute(TagHelperOutput output, string key, string value) | |
{ | |
if (!string.IsNullOrWhiteSpace(value)) | |
{ | |
output.Attributes.SetAttribute(key, value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment