Episerver Adaptive Images add-on
Developer documentation
- Introduction
- Installing
- Adding adaptive image properties
- Rendering adaptive images
- Configuration and settings
- Image providers
- Local development
See the web editor documentation on how to use the add-on in edit mode.
Introduction
This add-on makes it easy to add a new type of image property to content types, with a user-friendly user interface for web editors.
Developers are able to easily define image constraints, such as minimum size and proportions, and web editors can customize images for different screen sizes without risk of violating those restrictions.
Images can reside in Episerver or in external systems for digital asset management (DAM).
End-user images are automatically optimized, cropped, and rescaled, and served through a CDN.
Note: This is optional for local development, but production/high-load environments should always use a CDN for image transformation and delivery.
Installation
- Add NuGet package TedGustaf.Episerver.AdaptiveImages to your Episerver website
- For TinyMCE support, add TinyMCE plugin TinyMceAdaptiveImagePlugin to applicable editor instances (optional)
- Restart the website
Add an adaptive image property
public virtual AdaptiveImage HomePageHero { get; set; }
Set minimum image size
[Size(1024, 768, FormFactor.Small | FormFactor.Medium)] // Mobile and tablet images must be at least 1024x768 pixels
[Size(1920, 1080, FormFactor.Large)] // Desktop image must be at least 1920x1080 pixels
public virtual AdaptiveImage HomePageHero { get; set; }
Set proportion constraints
[Proportions(16, 9, FormFactor.Large)] // Desktop image should have widescreen proportions
[Proportions(1, 1, FormFactor.Small | FormFactor.Medium)] // Square images for mobile and tablet
public virtual AdaptiveImage HomePageHero { get; set; }
Combining constraints
When a web editor selects or crops images they're validated against these constraints:
[Proportions(16, 9, FormFactor.Large)] // Widescreen proportions
[Size(1920, FormFactor = FormFactor.Large)] // Minimum width of 1920 pixels (height determined by proportions constraint)
public virtual AdaptiveImage HomePageHero { get; set; }
Customize form factor display names
The default display names are "Desktop", "Tablet", and "Mobile" for the Large, Medium, and Small form factors, respectively.
You can customize form factor display names on a per-property basis by using the DisplayNames attribute:
[DisplayNames(Large = "Widescreen", Medium = "Standard", Small = "Square")]
public virtual AdaptiveImage MyAdaptiveImage { get; set; }
To localize form factor names, you can also use localization keys:
[DisplayNames(Large = "/path/to/translation/for/large")]
public virtual AdaptiveImage MyAdaptiveImage { get; set; }
You can also change and/or translate form factor display names site-wide by adding appropriate translations, for example through an XML language file like the following:
<?xml version="1.0" encoding="utf-8" ?>
<languages>
<language name="English" id="en">
<ContentTypes>
<AdaptiveImage>
<properties>
<Large>
<caption>Desktop</caption>
</Large>
<Medium>
<caption>Tablet</caption>
</Medium>
<Small>
<caption>Mobile</caption>
</Small>
</properties>
</AdaptiveImage>
</ContentTypes>
</language>
</languages>
Add a single image property
public virtual SingleImage OpenGraphImage { get; set; }
Setting constraints
For single images, you cannot specify form factor for the Size or Proportions attributes. You may also only include one of each attribute:
[Size(1920)]
[Proportions(16, 9)]
public virtual SingleImage OpenGraphImage { get; set; }
Rendering adaptive images
Default rendering
This will render the image(s) using default breakpoints, automatically cropped according to any constraints:
@Html.PropertyFor(x => x.HomePageHero)
See the Configuration section on how to change the default breakpoints and other settings.
Override default breakpoints and image width(s)
You can specify desired image widths and/or breakpoints, if different from the defaults:
@Html.PropertyFor(m => m.HomePageHero, new {
largeBreakpoint: 1280, // Desktop breakpoint
mediumBreakpoint: 768, // Tablet breakpoint (767 and below is considered mobile)
largeWidth = 1920, // Desktop image width
mediumWidth = 1279, // Tablet image width
smallWidth = 500, // Mobile image width
altText = "An adaptive image", // Overrides any alt text specified by web editor
cssClass = "hero-image" // CSS class applied to the picture element
})
Apply image transformations
For other custom rendering scenarios, apply transformations using a fluent syntax:
// Get the large ("desktop") image, cropped according to constraints and resized to a width of 1280 pixels
var largeImage = currentContent.GetImageRenderSettings(x => x.HomePageHero.Large)
.ResizeToWidth(1280);
// Create a 300x300 square version of the medium ("tablet") image, overriding any proportions constraints
var squareImage = currentContent.GetImageRenderSettings(x => x.HomePageHero.Medium)
.Crop(new Proportions(1, 1))
.ResizeToWidth(300);
Note: When retrieving render settings for an AdaptiveImage form factor, the expression needs to include the parent AdaptiveImage object in order to be able to resolve any constraints. Otherwise an exception will be thrown.
You can also create an ImageRenderSettings instance manually to circument any image constraints, for example to render an image with its original proportions, regardless of constraints:
// Create a 300px wide image with its original proportions preserved, ignoring any proportions constraints
var imageWithoutConstraints = new ImageRenderSettings(currentContent.HomePageHero.Large).ResizeToWidth(300);
Render a specific image
You can render an <img> element based on above render settings:
@Html.RenderImage(squareImage)
Get image URLs
If you need to get the final URL of an image, for example to set a background image, first apply any transformations and then call GetUrl():
@{
// Get the large ("desktop") image scaled to a width of 1920 pixels
var backgroundImageUrl = startPage.GetImageRenderSettings(x => x.HomePageHero.Large)
.ResizeToWidth(1920)
.GetUrl();
}
<div style="background-image: url(@backgroundImageUrl)"></div>
Resolving property image constraints and settings
When creating a view with a model type of AdaptiveImage, size and proportion constraints are not accessible as they're defined through attributes on the parent content, i.e. block or page, instance. However, constraints and crop settings can be retrieved like:
// "currentContent" below is a page or block instance with an AdaptiveImage property:
// Get all applicable constraints for all form factors
var imageConstraints = currentContent.GetImageConstraints(x => x.HomePageHero);
// Get crop settings for the large, i.e. "desktop", image
var largeImageCropSettings = currentContent.GetCropSettings(x => x.HomePageHero.Large);
// Get proportions constraints for the medium, i.e. "tablet", image
var mediumImageProportionsConstraints = currentContent.GetProportionsConstraint(m => m.HomePageHero.Medium);
// Get size constraints for the small, i.e. "mobile", image
var smallImageSizeConstraints = currentContent.GetSizeConstraint(m => m.HomePageHero.Small);
Make images required
To make a property required, use the RequiredImage property:
[RequiredImage]
public virtual AdaptiveImage Logotype { get; set; }
To only make specific form factors required, specify the FormFactor attribute property (not applicable for SingleImage properties):
[RequiredImage(FormFactor = FormFactor.Large | FormFactor.Medium)]
public virtual AdaptiveImage Logotype { get; set; }
To make the image description (i.e. alt text) required, you set the AlternateText property on the attribute:
[RequiredImage(AlternateText = true)]
public virtual AdaptiveImage Logotype { get; set; }
Make images localizable
To make a property culture-specific, use the CultureSpecificImage property:
[CultureSpecificImage]
public virtual AdaptiveImage Banner { get; set; }
You can choose to only make images or alternate text localizable by specifying the Images and/or AlternateText attribute properties. For example to use the same images for all languages but be able to localize the alternate text:
[CultureSpecificImage(Images = false, AlternateText = true)]
public virtual AdaptiveImage Banner { get; set; }
Rendering single images
Default rendering
This will render a SingleImage property, automatically cropped according to any constraints:
@Html.PropertyFor(x => x.OpenGraphImage)
You can optionally specify desired image width and CSS classes:
@Html.PropertyFor(m => m.OpenGraphImage, new {
width = 1920,
cssClass = "og-image" // CSS class applied to the img element
altText = "A single image", // Overrides any alt text specified by web editor
})
Configuration and settings
Add-on settings
Global add-on settings, such as default breakpoints, are configured through the static AddonSettings class:
AddonSettings.LargeBreakpoint = 1200;
AddonSettings.MediumBreakpoint = 800;
AddonSettings.MaximumWidth = 1920;
TinyMCE settings
TinyMCE settings, such as behavior when standard images are inserted, are configured through the static AddonTinyMceSettings class:
AddonTinyMceSettings.BlockContentTypeId = contentTypeRepository.Load(typeof(CustomTinyMceAdaptiveImageBlock)).ID;
AddonTinyMceSettings.ImageConversionBehavior = ImageConversionBehavior.AlwaysConvert;
License file
The license file, called AdaptiveImagesLicense.xml is expected to be found in the website root. You may specify a different path to the license file by setting an app setting like:
<add key="AdaptiveImages:LicenseFile" value="~/App_Data/AdaptiveImagesLicense.xml" />
Image providers
The add-on supports multiple image providers.
There are ready-made image providers for some digital asset management (DAM) systems. Please contact us if you want to integrate an existing DAM or looking for a suitable one.
Add/remove image providers
Image providers are types implenting the IImageProvider interface:
var customProvider = new MyCustomProvider();
ImageProviderFactory.Instance.Register(customProvider);
To remove an image provider:
ImageProviderFactory.Instance.Remove(customProvider.Name);
The user interface lists image providers in the order they appear in ImageProviderFactory:
Dropdowns are displayed for the selected image provider's options. For hierarchical options, multiple dropdowns are displayed.
Note: Only image providers with at least one searchable option (ImageProviderOptionCapability.Search capability) are displayed.
Note that commercial use of image providers requires a "Standard" add-on license or above. Visit episerverimages.com for more information.
Development environment
When using a CDN, it requires access to the website to retrieve images for transformation, so your development environment needs to be accessible over the internet.
In other words, if the website is run locally on localhost, you need to make it accessible over the internet when CDN features are enabled.
For local development, we recommend disabling CDN features by removing or clearing the the Cloudinary:CloudName app settings. However, this will affect auto-cropping features. Note that production or high-load environments should always have a CDN enabled.
ngrok is one viable option for enabling a proxy to make your local development environment accessible over the internet.