For developers: Add a thumbnail profile selector to the widget designer
Sitefinity CMS enables you to add a thumbnail functionality to any new widget you create that displays images. You do this by adding thumbnail profile selector in the widget designer and new properties to the widget to display the required thumbnail profile.
Implement the widget properties
In the code-behind of your widget, you must implement the following properties:
/// <summary>
/// Gets or sets the display mode that specify the size of the image to be rendered (original, thumbnail or custom).
/// By default the original size is shown.
/// </summary>
public ImageDisplayMode DisplayMode { get; set; }
/// <summary>
/// Gets or sets the name of the thumbnail.
/// </summary>
/// <value>The name of the thumbnail.</value>
public string ThumbnailName { get; set; }
These properties will hold the:
- Image display mode (original, thumbnail, or custom)
- Thumbnail name – the name of the selected thumbnail profile
Next, you associate your widget with the widget designer holding the new functionality.
You do this by adding the ControlDesigner attribute to the widget class:
[ControlDesigner(typeof(NameOfYourDesignerClass))]
Implement the widget designer code-behind
In the InitializeControls method, depending on the selected DisplayMode, the image URL is generated. Add the following code that specifies which image URL is returned based on the selected thumbnail profile:
protected override void InitializeControls(GenericContainer container)
{
LibrariesManager librariesManager = LibrariesManager.GetManager(this.ProviderName);
Image image = librariesManager.GetImages()
.Where(i => i.Id == this.ImageId)
.Where(PredefinedFilters.PublishedItemsFilter<Image>())
.FirstOrDefault();
string imageUrl;
var urlAsAbsolute = Config.Get<SystemConfig>().SiteUrlSettings.GenerateAbsoluteUrls;
if (this.DisplayMode == ImageDisplayMode.Thumbnail)
{
imageUrl = image.ResolveThumbnailUrl(this.ThumbnailName, urlAsAbsolute);
}
else if (this.DisplayMode == ImageDisplayMode.Custom)
{
// Custom properties Url generation
}
else
{
imageUrl = image.ResolveMediaUrl(urlAsAbsolute);
}
}
You must add a CustomImageSizeView property to enable users to manage thumbnail size. Next, override the GetScriptDescriptors() method and use the ScriptControlDescriptor class to add a component property for the size choice dropdown menu, the thumbnail service URL, and the library type. Thus, they can be used on the client side.
/// <summary>
/// The control that manages the custom image size case.
/// </summary>
protected virtual CustomImageSizeView CustomImageSizeViewControl
{
get
{
return Container.GetControl<CustomImageSizeView>("customImageSizeView", true);
}
}
public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
var descriptor = new ScriptControlDescriptor(this.GetType().FullName, this.ClientID);
descriptor.AddComponentProperty("customImageSizeViewControl", this.CustomImageSizeViewControl.ClientID);
return new[] { descriptor };
}
Implement the markup
In the markup file, add the following code to register a dropdown ChoiceField for selecting the size of the thumbnail:
<%@ Register TagPrefix="sfFields" Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields" %>
<sfFields:ChoiceField ID="sizesChoiceField" runat="server" DisplayMode="Write" RenderChoicesAs="DropDown" />
Implement the client-side
In the JavaScript file, add the get and set methods for the size choice dropdown, thumbnail service URL, and the library type:
//gets the ChoiceField used for choosing image size
get_sizesChoiceField: function () { return this._sizesChoiceField; },
set_sizesChoiceField: function (value) { this._sizesChoiceField = value; },
// gets the library type
get_libraryType: function () { return this._libraryType; },
set_libraryType: function (value) { this._libraryType = value; },
// gets the thumbnail service URL
get_thumbnailServiceUrl: function () { return this._thumbnailServiceUrl; },
set_thumbnailServiceUrl: function (value) { this._thumbnailServiceUrl = value; }
On the refreshUI event of the widget designer, the sizesChoiceField needs to be populated and display the value that was set last:
refreshUI: function () {
var controlData = this.get_controlData();
var selectedThumbnailName;
if (controlData.ThumbnailName) {
selectedThumbnailName = controlData.ThumbnailName;
} else if (controlData.DisplayMode === "Custom") {
selectedThumbnailName = this._customSizeOptionValue;
}
this.bindThumbnailSizesChoiceFields(selectedThumbnailName);
}
bindThumbnailSizesChoiceFields: function (selectedThumbnailName) {
var that = this;
this._getAvailableThumbnailProfilesAsync(function (profiles) {
var selectThumbSizeField = that.get_sizesChoiceField();
selectThumbSizeField.clearListItems();
var choices = that._getThumbnailChoices(profiles);
for (var i = 0; i < choices.length; i++) {
selectThumbSizeField.addListItem(choices[i].key, choices[i].value);
}
selectThumbSizeField.set_value(selectedThumbnailName);
});
},
_getThumbnailChoices: function (profiles) {
var originalSizeChoice = {
key: "",
value: "OriginalSize" };
// Here add custom thumbnail profile choice if required
var customSizeChoice = {
key: this._customSizeOptionValue,
value: "CustomSize" };
if (profiles[0] && profiles[0].key != originalSizeChoice.key && profiles[0].value != originalSizeChoice.value) {
profiles.splice(0, 0, originalSizeChoice);
profiles.push(customSizeChoice);
} else if (profiles.length < 1) {
profiles.push(originalSizeChoice);
profiles.push(customSizeChoice);
}
return profiles;
},
_getAvailableThumbnailProfilesAsync: function (callback) {
var profiles = [];
var requestUrl = String.format(
"{0}/thumbnail-profiles/?libraryType={1}&viewType={2}",
this.get_thumbnailServiceUrl(),
this.get_libraryType(),
this.get_viewType());
jQuery.ajax({
type: 'GET',
url: requestUrl,
processData: false,
contentType: "application/json",
success: function (data) {
var result = [];
for (var i = 0; i < data.Items.length; i++) {
var name = data.Items[i].Id;
var title = data.Items[i].Title;
result.push({ key: name, value: title });
}
profiles = result;
},
complete: function () {
callback(profiles);
}
});
},
On an applyChanges event, you need to get the selected thumbnail size and set it to the controlData object. You also set the DisplayMode:
var thumbnailName = this.get_sizesChoiceField().get_value();
// DisplayMode following the enum Telerik.Sitefinity.Web.UI.PublicControls.Enums.ImageDisplayMode
var displayMode = "Original";
if (thumbnailName) {
if (thumbnailName == this._customSizeOptionValue) {
displayMode = "Custom";
// Add custom properties if required
}
else
displayMode = "Thumbnail";
}
controlData.ThumbnailName = thumbnailName;
controlData.DisplayMode = displayMode;
Optionally, you can also enable users to specify a custom thumbnail profile. For more information, see For developers: Add a custom thumbnail profile to the widget designer.