Cut Requirement Bloat and Speed Up Feature Delivery
Overcomplicated requirements are slowing you down. Here’s how trimming the excess can help you launc
Optimizely Most Valued Professional (OMVP), Subject Matter Expert (SME), CMS and Commerce certified
Contact MeOver the last couple of years, usage of srcset has picked up traction with clients as an easy way to implement responsive images. You can empower the requesting browser to select an image from a list you specify. This example contains two images the browser can pick between depending on if the viewport has hit at least 480px or 800px.
<img srcset="ImageOne.jpg 480w, ImageTwo.jpg 800w" sizes="auto" src="ImageFallBack.jpg">
Using Image Processor we can optimize the editor experience. Optimizely editors can upload a single image but specify different widths which is generated on the fly.
<img srcset="ImageExample.jpg?width=480 480w, ImageExample.jpg?width=800 800w" sizes="auto" src="ImageFallBack.jpg">
Use this markup to render images so Optimizely can do it through a display template @Html.PropertyFor(x => x.Image) This code goes into your Shared\DisplayTemplates folder.
var imgUrl = @Url.ContentUrl(Model);
<img srcset="@imgUrl?width=480 480w, @imgUrl?width=800 800w" sizes="auto" src="@imgUrl">
Call this extension method on each url in your razor template
public static string SrcSet(this string imageUrl)
{
return string.IsNullOrEmpty(imageUrl) ? imageUrl : $"{imageUrl}?width=320 320w, "
+ $"{imageUrl}?width=640 640w, "
+ $"{imageUrl}?width=780 780w, "
+ $"{imageUrl}?width=960 960w, "
+ $"{imageUrl}?width=1280 1280w, "
+ $"{imageUrl}?width=1440 1440w, "
+ $"{imageUrl}?width=1600 1600w, "
+ $"{imageUrl}?width=1920 1920w";
}
Create a TinyMCE plugin and then register it. Credit to Ynze for pointing me in the right direction in this blog post.
edit 14/03/21: Modified the example markup to now support images being dragged in from assets pane or into the browser from an external source via drag and drop.
"use strict";
var tinymce = tinymce || {};
tinymce.PluginManager.add("addsrcset", function (editor, url) {
editor.on("NodeChange", function (e) {
if (e.element.tagName.toLowerCase() === "p") {
var imgElements = e.element.getElementsByTagName("img");
if (imgElements !== undefined) {
Array.from(imgElements).forEach((img) => {
var src = img.attributes.getNamedItem("src").value;
var srcFriendlyUrl = src.replace("/EPiServer/CMS/Content", "").split(",,")[0];
var srcset = getSrcSetMarkup(srcFriendlyUrl);
img.setAttribute("srcset", srcset);
img.setAttribute("sizes", "auto");
img.setAttribute("width", "100%");
img.setAttribute("height", "");
});
}
}
});
function getSrcSetMarkup(src) {
return (
src +
"?width=320 320w, " +
src +
"?width=640 640w, " +
src +
"?width=780 780w, " +
src +
"?width=1280 1280w, " +
src +
"?width=1440 1440w, " +
src +
"?width=1600 1600w, " +
src +
"?width=1920 1920w"
);
}
return {
getMetadata: function () {
return {
name: "Add SrcSet to Img",
url: "https://www.hiddenfoundry.com",
};
},
};
});
Image Processor will resize an image using the width you specify. If you have an image where the width is smaller than the requested width then it will be upscaled.You can disable this default behaviour by using the following initialization module.
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class ImageProcessorInitialization : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
ImageProcessingModule.ValidatingRequest += DisableUpscaling;
}
public void Uninitialize(InitializationEngine context)
{
ImageProcessingModule.ValidatingRequest -= DisableUpscaling;
}
private void DisableUpscaling(object sender, ValidatingRequestEventArgs args)
{
if (string.IsNullOrWhiteSpace(args.QueryString))
{
return;
}
var queryCollection = HttpUtility.ParseQueryString(args.QueryString);
queryCollection.Set("upscale", "false");
args.QueryString = queryCollection.ToString();
}
}
Overcomplicated requirements are slowing you down. Here’s how trimming the excess can help you launc
I discuss our experiences not validating business features early which result in delayed projects
Best practice of managing your Optimizely nuget packages
Demystify Image Resizing on the edge for your Optimizely solution
Critical parts of an upgrade can help you understand the different stages of an upgrade. Let's discu
Optimizely Customers now have a choice between using CMS on either PaaS or SaaS
SaaS Core is Optimizely's latest CMS offering as part of its composable architecture
We describe Optimizely's newest Content as a Service offering Optimizely Graph and how you should be
Straightforward RSS feed generation for your Optimizely solution with this NuGet package
Headless vs Traditional doesn't have to be a hard choice. An Optionality approach gives you the best
We are proud to announce Optimizely has awarded Hidden Foundry with Specializations
We discuss our experiences of working with Navico to refactor their single site into a multi-site so
We summerize our experience of working with FirstMile and helping them move over to Optimizely Comme
Grasp ODP and how it's AI and data consolidation enables insight driven conversions
We outline the benefits of upgrading your Optimizely solution to ASP.NET Core
Expand content area properties to load nested contact areas recursively to a customizable level
Redirect the user elsewhere instead of the default Optimizely login page when attempting to access a
Learn to use CLI and dotnet command to create new cms / commerce projects and perform admin actions.
How to use friendly segments instead of query strings as parameters in your action method