Skip to content

Instantly share code, notes, and snippets.

@thomassvensen
Last active August 11, 2017 18:01
Show Gist options
  • Save thomassvensen/4c53b8abe9a9c077dec6079acb83c998 to your computer and use it in GitHub Desktop.
Save thomassvensen/4c53b8abe9a9c077dec6079acb83c998 to your computer and use it in GitHub Desktop.
Image handling in EPiServer
namespace MyProject.Infrastructure.EPiServer.Attributes
{
public interface IImageRequirement
{
string GetRequirement();
}
}
@using MyProject.Infrastructure.EPiServer.Extensions
@using MyProject.Infrastructure.EPiServer.Models.Media
@using MyProject.Web.Components.Image
@using EPiServer
@using EPiServer.Editor
@using EPiServer.ServiceLocation
@model EPiServer.Core.ContentReference
@if (Model != null)
{
var imageFile = ServiceLocator.Current.GetInstance<IContentLoader>().Get<ImageFile>(Model);
var imageDimensions = imageFile.GetDimensions();
var halfWidth = imageDimensions.Width/2;
var halfHeight = imageDimensions.Height/2;
<img class="@ViewData["class"]" src="@Url.ContentUrl(Model)"
srcset="@Url.ContentUrl(Model) 2x, @Url.ContentUrl(Model)?width=@halfWidth&amp;height=@halfHeight 1x"
alt="@imageFile.Description" title="@imageFile.Credits"/>
}
else if (PageEditing.PageIsInEditMode)
{
<text>Currently no picture - size requirement: @ViewData[ImageHelper.ImageConstraints]</text>
}
using System.ComponentModel.DataAnnotations;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using EPiServer.Framework.DataAnnotations;
namespace MyProject.Infrastructure.EPiServer.Models.Media
{
[ContentType(DisplayName = "Image", GUID = "BE8C5F3B-8AA4-4870-AFF3-5F1208015722")]
[MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png")]
public class ImageFile : ImageData
{
[CultureSpecific]
[Editable(true)]
[Display(
Name = "Alternate text",
Description = "Description of the image",
GroupName = SystemTabNames.Content,
Order = 10)]
public virtual string Description { get; set; }
[CultureSpecific]
[Editable(true)]
[Display(
Name = "Credits",
GroupName = SystemTabNames.Content,
Order = 20)]
public virtual string Credits { get; set; }
}
}
using System;
using System.Linq;
using System.Reflection;
using MyProject.Infrastructure.EPiServer.Attributes;
namespace MyProject.Web.Components.Image
{
public static class ImageHelper
{
public static string GetImageRequirement(this PropertyInfo property)
{
return property
.GetCustomAttributes(false)
.OfType<IImageRequirement>()
.First()
.GetRequirement();
}
public const string ImageConstraints = "constraints";
}
}
@model ImageBlockViewModel
<div class="image">
@Html.PropertyFor(m => m.CurrentBlock.Image, new
{
constraints = Model.GetImageConstraints
} )
</div>
using System;
using System.ComponentModel.DataAnnotations;
using MyProject.Infrastructure.EPiServer.Models.Media;
using EPiServer;
using EPiServer.Core;
using EPiServer.ServiceLocation;
namespace MyProject.Infrastructure.EPiServer.Attributes
{
[AttributeUsage(AttributeTargets.Property)]
public class RequiredAltTextAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
var contentReference = value as ContentReference;
if (contentReference == null)
{
return true;
}
var imageFile = ServiceLocator.Current.GetInstance<IContentLoader>().Get<ImageFile>(contentReference);
if (imageFile == null)
{
ErrorMessage = "The content selected for property '{0}' cannot be found!";
return false;
}
if (string.IsNullOrEmpty(imageFile.Description))
{
ErrorMessage =
$"The item referenced by '{{0}}' has no description. Please add a description to '{imageFile.Name}' before use.";
return false;
}
return true;
}
}
}
using System;
using System.ComponentModel.DataAnnotations;
using MyProject.Infrastructure.EPiServer.Extensions;
using MyProject.Infrastructure.EPiServer.Models.Media;
using EPiServer;
using EPiServer.Core;
using EPiServer.ServiceLocation;
namespace MyProject.Infrastructure.EPiServer.Attributes
{
// Adapted from https://github.com/markeverard/Chief2moro.ImageDataExtensions
[AttributeUsage(AttributeTargets.Property)]
public class RequiredImageSizeAttribute : ValidationAttribute, IImageRequirement
{
public int Width { get; set; }
public int Height { get; set; }
public override bool IsValid(object value)
{
if (value == null)
{
return true;
}
if (Height < 1 && Width < 1)
{
return true;
}
var contentReference = value as ContentReference;
var imageFile = ServiceLocator.Current.GetInstance<IContentLoader>().Get<ImageFile>(contentReference);
if (imageFile == null)
{
ErrorMessage = "The content selected for property '{0}' cannot be found!";
return false;
}
var dimensions = imageFile.GetDimensions();
if (IsNotRequiredHeight(dimensions) && IsNotRequiredWidth(dimensions))
{
ErrorMessage = $"The image used in reference '{{0}}' is {dimensions}, but must have a size of {Width}x{Height} pixels";
return false;
}
if (IsNotRequiredHeight(dimensions))
{
ErrorMessage = $"The image used in property {{0}} is {dimensions}, but must have a height of {Height} pixels";
return false;
}
if (IsNotRequiredWidth(dimensions))
{
ErrorMessage = $"The image used in property {{0}} is {dimensions}, but must have a width of {Width} pixels";
return false;
}
return true;
}
private bool IsNotRequiredWidth(Dimensions dimensions)
{
return IsNonZero(Width) && Width != dimensions.Width;
}
private bool IsNotRequiredHeight(Dimensions dimensions)
{
return IsNonZero(Height) && Height != dimensions.Height;
}
private bool IsNonZero(int size)
{
return size > 0;
}
public string GetRequirement()
{
return $"{Width}x{Height}";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment