Create the custom editor dojo widget
First, let's create a new JavaScript file for our custom editor:
Make sure you have a dojo namespace mapped in module.config in your site root:
<?xml version="1.0" encoding="utf-8"?>
<module>
<dojo>
<paths>
<!-- Add a default namespace mapping for ~/ClientResources to the dojo loader configuration -->
<add name="tedgustaf" path="" />
</paths>
</dojo>
</module>
Next, add the custom editor code to the ImageContentSelector.js file:
define([
"dojo/_base/declare",
"dojo/dom-style",
"dojo/aspect",
"epi-cms/widget/ContentSelector"
],
function (
declare,
domStyle,
aspect,
ContentSelector
) {
return declare([ContentSelector], {
thumbnail: null,
content: null,
constructor: function() {
this.inherited(arguments);
// List for when the previewUrl property is set through the inherited _setValueAndFireOnChange method
aspect.after(this, "set", function (name, value) {
if (name === 'previewUrl' && value) {
this.updateThumbnail();
}
// No need to return - set method does not return anything
}, true);
// Create thumbnail element
this.thumbnail = dojo.create("img");
domStyle.set(this.thumbnail, 'borderBottom', '1px solid #929ba4');
domStyle.set(this.thumbnail, 'display', 'none');
},
postCreate: function () {
this.inherited(arguments);
dojo.place(this.thumbnail, this.displayNode, "first");
},
_updateDisplayNode: function (content) {
// Inherited from _SelectorBase through ContentSelector
this.inherited(arguments);
this.content = content;
this.updateThumbnail();
},
updateThumbnail: function () {
var content = this.content;
var thumbnail = this.thumbnail;
var clearThumbnail = function () {
dojo.attr(thumbnail, 'src', '');
domStyle.set(thumbnail, 'display', 'none');
}
if (content && thumbnail) {
if (content.previewUrl && content.publicUrl) {
var previewUrlWithScaling = content.previewUrl;
var fileName = content.publicUrl.substr(content.publicUrl.lastIndexOf("/") + 1);
var fileExtension;
var indexOfLastDot = fileName.lastIndexOf('.');
if (indexOfLastDot != -1)
{
fileExtension = fileName.substring(indexOfLastDot + 1);
}
if (!fileExtension) {
var previewUrlSuffix = ',,' + content.contentLink;
var endOfFileNamePosition = content.previewUrl.lastIndexOf(previewUrlSuffix);
if (endOfFileNamePosition != -1) {
// Assume .jpg extension if no file extension in URL
previewUrlWithScaling = content.previewUrl.substring(0, endOfFileNamePosition) + '.jpg' + content.previewUrl.substring(endOfFileNamePosition);
}
}
previewUrlWithScaling += '&width=195';
dojo.attr(thumbnail, 'src', previewUrlWithScaling);
domStyle.set(thumbnail, 'display', '');
}
else {
clearThumbnail();
}
} else {
clearThumbnail();
}
}
});
});
Replace the default editor for image properties
We want our custom editor to be used for all image properties, i.e. ContentReference properties with a UI hint of UIHint.Image.
We do this by adding an editor descriptor class for UIHint.Image like so:
/// <summary>
/// Replaces the default editor for image properties
/// </summary>
[EditorDescriptorRegistration(TargetType = typeof(ContentReference), UIHint = UIHint.Image)]
public class ImageEditorDescriptor : EditorDescriptor
{
public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
{
base.ModifyMetadata(metadata, attributes);
metadata.ClientEditingClass = "tedgustaf.editors.ImageContentSelector";
}
}
This sets the editor widget to our custom editor for all properties of type ContentReference that have a UIHint of UIHint.Image.
Some things to note about dojo namespaces in Episerver
Since our widget is in a file called ImageContentSelector.js in the /ClientResources/Editors folder, we can now reference our editor, i.e. dojo class, like: tedgustaf.editors.ImageContentSelector (note that the namespace must be lower-case in dojo).
This is because the root namespace ("tedgustaf") is mapped to the ClientResources folder in module.config. This means a reference like tedgustaf.somethingelse.ClassName will resolve to /ClientResources/SomethingElse/ClassName.js.
The finished result
Final note on image resizing
The editor code is based on the assumption that an image resizer is present. In our case we use Image Resizer, which allows the thumbnail to be generated by simply adding a query string parameter to the preview URL.