| name | sitefinity-designer-attributes |
| description | Comprehensive reference for every attribute available in Sitefinity's autogenerated widget property editors (MVC and ASP.NET Core renderer) - field types, display/validation attributes, sections, conditional visibility, content selectors, LinkModel, TableView, choices, and KnownFieldTypes string values. Use when building or configuring widget designer fields. |
Sitefinity Widget Designer Attributes Reference
Comprehensive reference for all attributes available when building autogenerated widget property editors. These attributes control how properties appear in the Sitefinity admin widget designer UI.
Source: Official Sitefinity Documentation and GitHub Samples
Table of Contents
Namespaces
For MVC (.NET Framework 4.8):
using Telerik.Sitefinity.Web.Services.PropertyEditor.Attributes;
using Telerik.Sitefinity.Frontend.Mvc.Infrastructure.Controllers.Attributes;
using Telerik.Sitefinity.Web.UI;
using Progress.Sitefinity.Renderer.Designers;
using Progress.Sitefinity.Renderer.Designers.Attributes;
using Progress.Sitefinity.Renderer.Models;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
Important: Progress.Sitefinity.Renderer.dll ships with Sitefinity 14.3+ — reference it from the project where your widget controllers live. The types in Progress.Sitefinity.Renderer.Designers.Attributes work in MVC controllers (with the exceptions explicitly flagged below, e.g. [ColorPalette] which is ASP.NET Core renderer-only).
KnownFieldTypes and PropertyCategory are classes with string constants — use them directly via using Progress.Sitefinity.Renderer.Designers;. Raw string values are documented in the KnownFieldTypes Reference section for reference.
Field Types
| C# Type | Designer UI | Notes |
|---|
string | Text input | Default for unknown types too |
bool | Yes/No radio buttons | Use [DataType(customDataType: KnownFieldTypes.CheckBox)] for checkbox |
int | Number input | |
double | Decimal number input | |
DateTime | Date-time picker | Use [DateSettings(ShowTime = false)] for date only |
DateTime? | Nullable date picker | |
bool? | Nullable boolean | |
int? | Nullable number | |
enum | Dropdown selector | Single selection by default |
[Flags] enum | Multi-select checkboxes | Use [Flags] attribute on the enum |
LinkModel | Link picker | |
MixedContentContext | Content item selector | Requires [Content] attribute |
| Complex objects | Expandable section | Properties of the object shown inline |
IList<T> | List builder | Add/remove/reorder items |
IDictionary<K,V> | Key-value editor | |
Docs: Autogenerated field types
Display Attributes
[DisplayName("Label")]
Controls the label shown in the designer UI.
[DisplayName("Hero Heading")]
public string Heading { get; set; }
[Description("Helper text")]
Shows helper/instructional text below the field.
[Description("The main heading displayed in the hero section")]
public string Heading { get; set; }
[DescriptionExtended("...", InlineDescription = "...", InstructionalNotes = "...")]
Extended description with additional UI elements.
[DescriptionExtended("Extended info", InlineDescription = "Inline hint", InstructionalNotes = "Additional notes")]
public string Description { get; set; }
[Placeholder("Hint text")]
Shows placeholder text inside string input fields. Disappears when user types.
[Placeholder("Enter your heading here...")]
public string Heading { get; set; }
[DefaultValue("value")]
Sets the initial value when the widget is first added to a page.
[DefaultValue("Build something amazing")]
public string Heading { get; set; }
[DefaultValue(true)]
public bool ShowButton { get; set; }
[DefaultValue(42)]
public int MaxItems { get; set; }
[DefaultValue("2020-09-11T06:38:11.170Z")]
public DateTime StartDate { get; set; }
[DefaultValue(EnumSingle.Value2)]
public EnumSingle Layout { get; set; }
[FallbackToDefaultValueWhenEmpty]
When combined with [DefaultValue], falls back to the default if the user clears the field.
[DefaultValue("Default heading")]
[FallbackToDefaultValueWhenEmpty]
public string Heading { get; set; }
[Browsable(false)]
Hides the property from the designer entirely. Also prevents database persistence.
[Browsable(false)]
public string InternalId { get; set; }
[ReadOnly(true)]
Shows the property but makes it non-editable.
[ReadOnly(true)]
public string WidgetVersion { get; set; }
[DisplaySettings(Hide = true)]
Hides a field from the designer (alternative to [Browsable(false)]).
[DisplaySettings(Hide = true)]
public string HiddenField { get; set; }
[DisplaySettings(HideContent = true)]
Hides the field content but keeps the label visible.
[Mirror(fieldName, fieldProperty)]
Auto-populates this field from another property's value. User can override.
| Constructor Param | Type | Description |
|---|
mirrorFieldName | string | Source property name |
mirrorFieldProperty | string | Which sub-property to mirror (for complex types) |
| Property | Type | Description |
|---|
FieldName | string | Source field name |
FieldProperty | string | Source field sub-property |
EnableMirroring | bool | Enable/disable mirroring (default: true) |
public string Title { get; set; }
[Mirror(nameof(Title), null)]
public string SlugUrl { get; set; }
[Copy(Exclude = true)]
Excludes this property when the widget is duplicated/copied.
[Copy(Exclude = true)]
public int UniqueCounter { get; set; }
[Suffix("unit")]
Shows a unit label next to Range fields.
[DataType(customDataType: KnownFieldTypes.Range)]
[Suffix("px")]
public NumericRange Padding { get; set; }
[DataType(customDataType: KnownFieldTypes.Range)]
[Suffix("MB")]
public NumericRange FileSize { get; set; }
[ContentContainer]
Marks an HTML field as a content container (enables special content editing features).
[DataType(customDataType: KnownFieldTypes.Html)]
[ContentContainer]
public string RichContent { get; set; }
[DynamicLinksContainer]
Marks a complex object property as containing dynamic links. Used with LinkModel inside complex objects.
[DynamicLinksContainer]
public ComplexObjectWithLinks ObjectWithLinks { get; set; }
[DynamicLinksContainer]
public IList<ComplexObjectWithLinks> ArrayOfObjectWithLinks { get; set; }
[ViewSelector]
Enables the template/view selector dropdown. Shows available .cshtml views.
Limitation in MVC: The [ViewSelector] attribute (from Telerik.Sitefinity.Frontend) only discovers views in the ResourcePackages theme folder (ResourcePackages/{Theme}/MVC/Views/{Widget}/), NOT in the standard Mvc/Views/ folder. If your custom widget views live in Mvc/Views/, the dropdown appears empty.
Workaround: Use an enum property instead — enums render as dropdown selectors automatically, and are more reliable than file-system scanning.
[ViewSelector]
public string TemplateName { get; set; }
public enum HeroTemplate
{
[Description("Centered")]
Centered,
[Description("Split (Text + Image)")]
Split,
[Description("Gradient Overlay")]
Gradient
}
[DisplayName("Template")]
[DefaultValue(HeroTemplate.Centered)]
public HeroTemplate Template { get; set; } = HeroTemplate.Centered;
[Browsable(false)]
public string TemplateName => $"Hero.{this.Template}";
Docs: Customize autogenerated fields
Validation Attributes
Standard System.ComponentModel.DataAnnotations attributes:
[Required(ErrorMessage = "Heading is required.")]
public string Heading { get; set; }
[StringLength(100, ErrorMessage = "Must be between {1} and {2} characters.", MinimumLength = 5)]
public string Title { get; set; }
[MinLength(2, ErrorMessage = "At least {1} characters required.")]
[MaxLength(500, ErrorMessage = "Must be less than {1} characters.")]
public string Description { get; set; }
[Range(1, 20, ErrorMessage = "Value must be between {1} and {2}.")]
public int ItemCount { get; set; }
[Range(1, 20, ErrorMessage = "Value must be between {1} and {2}.")]
public double Opacity { get; set; }
[EmailAddress(ErrorMessage = "Enter a valid email address.")]
public string ContactEmail { get; set; }
[Url(ErrorMessage = "Enter a valid URL.")]
public string ExternalLink { get; set; }
[RegularExpression(@"^#[0-9A-Fa-f]{6}$", ErrorMessage = "Enter a valid hex color.")]
public string CustomColor { get; set; }
Docs: Field validations
Sections and Views
Basic vs. Advanced Views
Properties default to the Basic view. Use [Category(PropertyCategory.Advanced)] to move to the Advanced tab.
public string Heading { get; set; }
[Category(PropertyCategory.Advanced)]
public string CssClass { get; set; }
Content Sections (Collapsible Groups)
Use [ContentSection("Section Name", order)] to group properties into collapsible sections within a view. The second parameter controls ordering within that section.
private const string AppearanceSection = "Appearance";
private const string ContentSection = "Content";
[ContentSection(ContentSection, 0)]
public string Heading { get; set; }
[ContentSection(ContentSection, 1)]
public string Description { get; set; }
[ContentSection(AppearanceSection, 0)]
public string BackgroundColor { get; set; }
[ContentSection(AppearanceSection, 1)]
public string TextAlignment { get; set; }
[Category(PropertyCategory.Advanced)]
[ContentSection("SEO Settings", 0)]
public string MetaTitle { get; set; }
[Category(PropertyCategory.Advanced)]
[ContentSection("SEO Settings", 1)]
public string MetaDescription { get; set; }
Group (Visual Grouping for Checkboxes)
[Group("Display Options")]
[DisplayName("Show title")]
[DataType(customDataType: KnownFieldTypes.CheckBox)]
[DefaultValue(true)]
public bool ShowTitle { get; set; }
[Group("Display Options")]
[DisplayName("Show description")]
[DataType(customDataType: KnownFieldTypes.CheckBox)]
[DefaultValue(true)]
public bool ShowDescription { get; set; }
Docs: Sections and views
Conditional Visibility
Show/hide properties based on the value of another property. Uses ConditionalVisibilityAttribute with a JSON condition string.
JSON Format
{
"conditions": [
{
"fieldName": "PropertyName",
"operator": "Equals",
"value": "ExpectedValue"
}
]
}
Single Condition
[ConditionalVisibility("{\"conditions\":[{\"fieldName\":\"TemplateName\",\"operator\":\"Equals\",\"value\":\"Split\"}]}")]
public string BackgroundImageUrl { get; set; }
Boolean Condition
[DefaultValue(false)]
public bool ShowSecondaryButton { get; set; }
[ConditionalVisibility("{\"conditions\":[{\"fieldName\":\"ShowSecondaryButton\",\"operator\":\"Equals\",\"value\":\"true\"}]}")]
public string SecondaryButtonText { get; set; }
[ConditionalVisibility("{\"conditions\":[{\"fieldName\":\"ShowSecondaryButton\",\"operator\":\"Equals\",\"value\":\"true\"}]}")]
public string SecondaryButtonUrl { get; set; }
Namespace
MVC/.NET Framework: Telerik.Sitefinity.Web.Services.PropertyEditor.Attributes.ConditionalVisibilityAttribute
ASP.NET Core: Progress.Sitefinity.Renderer.Designers.Attributes.ConditionalVisibilityAttribute
Docs: Conditional fields
Content Selectors
Select Sitefinity content items (pages, images, news, dynamic content, taxonomies).
[Content(Type = KnownContentTypes.Images)]
public MixedContentContext HeroImage { get; set; }
[Content(Type = KnownContentTypes.Images, AllowMultipleItemsSelection = true)]
public MixedContentContext GalleryImages { get; set; }
[Content(Type = KnownContentTypes.Pages, AllowMultipleItemsSelection = false, ShowSiteSelector = true)]
public MixedContentContext TargetPage { get; set; }
[Content(Type = KnownContentTypes.Pages, AllowMultipleItemsSelection = false, DisableInteraction = true, ShowSiteSelector = true)]
public MixedContentContext SinglePage { get; set; }
[Content(Type = KnownContentTypes.DocumentLibraries, AllowMultipleItemsSelection = false, AllowCreate = false, Provider = "secondlibraries")]
public MixedContentContext DocumentLibrary { get; set; }
[Content(Type = KnownContentTypes.News, LiveData = true)]
public MixedContentContext PublishedNews { get; set; }
[Content(Type = "Telerik.Sitefinity.DynamicTypes.Model.Pressreleases.PressRelease")]
public MixedContentContext PressReleases { get; set; }
[Content(Type = KnownContentTypes.Albums)]
public MixedContentContext Albums { get; set; }
[Content]
public MixedContentContext AnyContent { get; set; }
[TaxonomyContent(Type = KnownContentTypes.Tags)]
public MixedContentContext Tags { get; set; }
[TaxonomyContent(Type = KnownContentTypes.Categories)]
public MixedContentContext Categories { get; set; }
[TaxonomyContent(Type = "geographical-regions")]
public MixedContentContext CustomTaxonomy { get; set; }
Content Selector Options
| Option | Type | Description |
|---|
Type | string | Content type (use KnownContentTypes.* constants or full type name) |
AllowMultipleItemsSelection | bool | Allow selecting multiple items (default: true) |
AllowCreate | bool | Show "Create" button in selector (default: true) |
DisableInteraction | bool | Disable click-to-edit on selected items |
ShowSiteSelector | bool | Show site selector for multisite setups |
LiveData | bool | Show only published/live items (not drafts) |
Provider | string | Specific content provider name |
IsFilterable | bool | Enable filtering in the selector (verified by reflection) |
OpenMultipleItemsSelection | bool | Open in multi-select mode (verified by reflection) |
ForceShouldShowAll | bool | Force "show all" in the selector (verified by reflection) |
TypeBlacklist | string[] | Types to exclude from the selector (verified by reflection) |
ManualSelectionMainFieldName / ManualSelectionTabTitle / ManualSelectionIconClass / ManualSelectionBreadcrumbText / ManualSelectionEntityType | string | Manual-selection tab configuration (verified by reflection) |
Color Palettes
NOT AVAILABLE IN MVC (.NET Framework 4.8) — verified by reflection: ColorPaletteAttribute does not exist in Progress.Sitefinity.Renderer.dll (15.4) or any other assembly in an MVC site's bin\. It ships only in the ASP.NET Core renderer packages (Progress.Sitefinity.AspNetCore). Do not add it to MVC widgets — it will not compile. The samples below are ASP.NET Core renderer only.
MVC alternatives: [DataType(customDataType: KnownFieldTypes.Color)] for a free color picker, or [Choice] with a JSON list of brand colors for a constrained palette.
[ColorPalette("Default")]
public string BackgroundColor { get; set; }
[ColorPalette("Company")]
public string BrandColor { get; set; }
Docs: Color palettes sample
Complex Objects and Table View
Properties that contain sub-properties, rendered as expandable sections.
public class ButtonConfig
{
[DisplayName("Button text")]
[DefaultValue("Click me")]
public string Text { get; set; }
[DisplayName("Button URL")]
public string Url { get; set; }
[DisplayName("Open in new tab")]
[DefaultValue(false)]
public bool OpenInNewTab { get; set; }
}
public ButtonConfig PrimaryButton { get; set; }
[TableView] — Collapsed Table Layout for Lists
Namespace: Progress.Sitefinity.Renderer.Designers.Attributes
Shows IList<T> items in a compact table with configurable visible columns instead of rendering all fields inline. Hidden columns are accessible via a "More details" edit button (pencil icon).
| Property | Type | Default | Description |
|---|
ColumnTitle | string | null | Header title for the table (also available as constructor param) |
Enabled | bool | true | Enable/disable table view |
Reorderable | bool | false | Allow drag-and-drop reordering of rows |
Selectable | bool | false | Allow row selection |
MultipleSelect | bool | false | Allow selecting multiple rows (requires Selectable = true) |
AllowEmptyState | bool | false | Allow the list to be empty |
AddManyFileName | string | null | File name for "Add many" import functionality |
ColumnCount | int | 0 | Number of columns to show in table rows. 0 = show all. 1 = show only the first property (rest behind "More details") |
HideRowsIfEmpty | bool | false | Hide table rows when the list is empty (verified by reflection, undocumented by Progress) |
[TableView(Reorderable = true, ColumnCount = 1)]
public IList<FeatureItem> Features { get; set; } = new List<FeatureItem>();
[TableView(Reorderable = true, Selectable = true, MultipleSelect = true)]
public IList<ButtonConfig> Buttons { get; set; } = new List<ButtonConfig>();
[TableView("Action Items", Reorderable = true)]
public IList<ActionItem> Actions { get; set; } = new List<ActionItem>();
Controlling column order: Use [ContentSection(N)] on sub-object properties to control which columns appear first (and thus which are visible when ColumnCount limits the display). IMPORTANT: Numbering is 1-based — start at ContentSection(1), not ContentSection(0). Using 0 causes the property to be treated as unpositioned, and the column won't appear where expected in the table.
Why 1-based? Internally, Sitefinity's sf-editable-table component uses the ContentSection ordinal to sort columns. An ordinal of 0 is treated as "no explicit position" (same as omitting the attribute), so those properties float to the end. Using 1, 2, 3... gives you explicit, deterministic column ordering.
public class FeatureItem
{
[ContentSection(1)]
[DisplayName("Title")]
public string Title { get; set; }
[ContentSection(2)]
[DisplayName("Description")]
public string Description { get; set; }
}
How the "Item details" Popup Editor Works
When ColumnCount hides properties behind "More details", clicking the pencil icon on a table row opens a full-screen "Item details" overlay. This is an internal AdminApp mechanism — the sf-editable-table component detects complex metadata (TypeChildProperties, Meta_TableView_Enabled) and renders a navigation to an edit view.
Key points:
- The popup is NOT a reusable public component — it's internal to
sf-editable-table in the AdminApp bundle
- The pencil button (
sf-pencil-button) triggers populateNestedComplexSettings(...) internally, which creates dialogData with Done/Cancel commands
- The edit view renders each sub-property using the standard Sitefinity field wrapper chain (see Field Wrapper DOM Structure below)
- Done saves the row data, Cancel discards — both return to the table view
To get this behavior automatically: Use IList<T> with [TableView] and let Sitefinity own the complex type rendering. This is the simplest way to get the native pencil-to-edit experience.
For custom field editors (e.g., a contact picker that manages its own JSON): The popup is not available. The public SDK alternative is SelectorService.openDialog() (from @progress/sitefinity-adminapp-sdk), which opens a modal dialog. For a full-screen edit experience, implement a view-swapping pattern with a CSS position: fixed overlay inside your custom component.
Field Wrapper DOM Structure (Native Fields)
Understanding how Sitefinity renders fields in the designer is critical for building custom field editors that look native. Each field follows this DOM hierarchy:
sf-form-field-wrapper ← Animated entry wrapper (internal, not available to extensions)
└─ sf-field-wrapper ← Label + content layout (PUBLIC — available via SfFieldWrapperModule)
└─ div.sf-field
├─ label.sf-field__label ← Bold label with proper spacing
└─ div.sf-field__content ← Content projection slot
└─ sf-input ← The actual input component
└─ div.sf-input
└─ input.sf-input__field.sf-field__input
Why this matters: sf-input has its own [label] prop that renders label.sf-input__label — this is a compact inline label with tighter spacing, intended for table cells and tight layouts. The proper designer label comes from sf-field-wrapper, which renders label.sf-field__label with correct font weight, font size, and vertical rhythm matching all other fields in the widget editor.
Rule for custom field editors:
The form container also matters. Native edit views use class="sf-form -medium -sf-centered-box" on the outer wrapper, which provides:
-medium — constrains the form to a readable max-width
-sf-centered-box — horizontally centers the form in the viewport
The table structure uses these native CSS classes:
table.sf-field__table -has-hover — the table wrapper (table-layout: fixed; width: 100%)
tr.sf-field__table-row -head — header row (height: auto)
tr.sf-field__table-row -middle — body rows (height: 55px)
th.-col-size-4xs — 30px column (drag handle)
th.-col-size-3xs — 50px column (action buttons)
sf-icon name="ellipsis-v" look="light size-m sf-drag-handle" — drag handle icon (cursor: move)
sf-button look="circle small" icon="pencil" — edit button per row
sf-button look="circle small" icon="plus" iconlook="size-xs" — add button below table
Docs: Autogenerated complex objects
Collections
public IList<string> Tags { get; set; }
public IList<ButtonConfig> ActionButtons { get; set; }
public IDictionary<string, ComplexObject> Settings { get; set; }
Choice Fields
Custom choice selectors for non-enum types.
Chip Choice (Int)
[DefaultValue(1)]
[DisplayName("Column count")]
[DataType(customDataType: KnownFieldTypes.ChipChoice)]
[Choice("[{\"Title\":\"1 column\",\"Name\":\"1\",\"Value\":1,\"Icon\":null},{\"Title\":\"2 columns\",\"Name\":\"2\",\"Value\":2,\"Icon\":null},{\"Title\":\"3 columns\",\"Name\":\"3\",\"Value\":3,\"Icon\":null}]")]
public int? ColumnCount { get; set; }
Dropdown Choice (Int)
[DefaultValue(1)]
[DisplayName("Items per row")]
[DataType(customDataType: KnownFieldTypes.Choices)]
[Choice("[{\"Title\":\"1 item\",\"Name\":\"1\",\"Value\":1,\"Icon\":null},{\"Title\":\"2 items\",\"Name\":\"2\",\"Value\":2,\"Icon\":null}]")]
public int? ItemsPerRow { get; set; }
Radio Choice (Enum)
[DisplayName("Text alignment")]
[DataType(customDataType: KnownFieldTypes.RadioChoice)]
public TextAlignment Alignment { get; set; }
Enum as Chip
[DataType(customDataType: KnownFieldTypes.ChipChoice)]
public LayoutStyle Layout { get; set; }
[Choice] Attribute — Full Properties
Namespace: Progress.Sitefinity.Renderer.Designers.Attributes
| Property | Type | Description |
|---|
Choices | string | JSON array of choice items (also available as constructor param) |
ServiceUrl | string | URL to fetch choices dynamically at runtime |
ServiceCallParameters | string | Parameters to pass to the service URL |
ServiceWarningMessage | string | Warning shown when service is unavailable |
ShowFriendlyName | bool | Show friendly display names |
ActionTitle | string | Title for the action button |
ButtonTitle | string | Title for the button |
NotResponsive | bool | Disable responsive layout |
SideLabel | string | Label shown beside the choice field |
ChipMaxThreshold | int | Maximum number of chips before collapsing |
External Data Choice (Dynamic Options)
Populate dropdown choices from an external data source at runtime using ServiceUrl on [Choice] or a custom attribute and property configurator.
[Choice(ServiceUrl = "/api/my-choices")]
[DataType(customDataType: KnownFieldTypes.Choices)]
public string DynamicChoice { get; set; }
[ExternalDataChoice]
[DataType(customDataType: KnownFieldTypes.Choices)]
public string DynamicChoiceSingle { get; set; }
The custom attribute approach (ExternalDataChoiceAttribute + ExternalChoicePropertyConfigurator) is an ASP.NET Core renderer only extension point — not available in MVC. In MVC, use [Choice(ServiceUrl = ...)] directly. See All Properties sample.
Hiding Enum Values
Use [Browsable(false)] on individual enum members to hide them from the selector.
[Flags]
public enum LayoutOptions
{
SingleColumn = 0x01,
TwoColumns = 0x02,
ThreeColumns = 0x04,
[Browsable(false)]
InternalLayout = 0x08,
}
Enum Descriptions
Use [Description] to customize how enum values appear in the selector.
public enum TextAlignment
{
[Description("Align left")]
Left,
[Description("Align center")]
Center,
[Description("Align right")]
Right,
}
Special Types
Namespace: Progress.Sitefinity.Renderer.Entities (for NumericRange, FileTypes) and Progress.Sitefinity.Renderer.Entities.Content (for MixedContentContext)
NumericRange
Range slider input with min/max values.
| Property | Type | Description |
|---|
Min | int? | Minimum value |
Max | int? | Maximum value |
[DataType(customDataType: KnownFieldTypes.Range)]
[Suffix("px")]
public NumericRange Padding { get; set; }
DecimalNumericRange
Same as NumericRange but for decimal values.
| Property | Type | Description |
|---|
Min | decimal? | Minimum value |
Max | decimal? | Maximum value |
FileTypes
File type picker for upload restrictions.
| Property | Type | Description |
|---|
Type | string | Predefined file type category |
Other | string | Custom file extensions |
[DataType(customDataType: KnownFieldTypes.FileTypes)]
[DisplayName("Allowed file types")]
public FileTypes AllowedFiles { get; set; }
MixedContentContext — Content Item Selector
Used with [Content] or [TaxonomyContent] attributes to select CMS content items.
| Property | Type | Description |
|---|
ItemIdsOrdered | string[] | Ordered array of selected item IDs |
Content | ContentContext[] | Content context for each selected item |
ManualSelectionItems | ManualSelectionItem[] | Manually selected items |
Declaring the Property
Always pair with [PropertyPersistence(PersistAsJson = true)] so Sitefinity stores the selection as JSON:
using Progress.Sitefinity.Renderer.Entities.Content;
using Progress.Sitefinity.Renderer.Designers.Attributes;
using Telerik.Sitefinity.Modules.Pages.PropertyPersisters;
[Content(Type = KnownContentTypes.Images, AllowMultipleItemsSelection = false)]
[PropertyPersistence(PersistAsJson = true)]
public MixedContentContext HeroImage { get; set; }
[Content(Type = KnownContentTypes.Documents)]
[PropertyPersistence(PersistAsJson = true)]
public MixedContentContext Attachments { get; set; }
[Content(Type = "Telerik.Sitefinity.DynamicTypes.Model.KnowledgeBase.Solution")]
[PropertyPersistence(PersistAsJson = true)]
public MixedContentContext FeaturedSolutions { get; set; }
Resolving Content — Extracting the Actual Items
Use ManagerBase.GetItems() to resolve the selected content. The pattern is always the same:
using Telerik.Sitefinity.Data;
using Telerik.Sitefinity.GenericContent.Model;
if (this.HeroImage == null) return;
var items = ManagerBase.GetItems(this.HeroImage, KnownContentTypes.Images)
.OfType<Telerik.Sitefinity.Libraries.Model.Image>()
.Where(i => i.Status == ContentLifecycleStatus.Live)
.ToList();
if (items.Any())
{
var image = items.First();
model.ImageUrl = image.MediaUrl;
model.AltText = image.AlternativeText;
}
Resolving Images
using Telerik.Sitefinity.Libraries.Model;
var images = ManagerBase.GetItems(this.HeroImage, KnownContentTypes.Images)
.OfType<Image>()
.Where(i => i.Status == ContentLifecycleStatus.Live)
.ToList();
if (images.Any())
{
var img = images.First();
model.ImageUrl = img.MediaUrl;
model.AltText = img.AlternativeText;
model.ThumbUrl = img.ResolveThumbnailUrl("profileName");
}
Image properties: MediaUrl, AlternativeText, Title, Width, Height, Extension, MimeType, TotalSize
Resolving Documents
using Telerik.Sitefinity.Libraries.Model;
var docs = ManagerBase.GetItems(this.Documents, KnownContentTypes.Documents)
.OfType<Document>()
.Where(d => d.Status == ContentLifecycleStatus.Live)
.ToList();
Document properties: MediaUrl, Title, Extension, TotalSize, MimeType
Resolving Dynamic Content
using Telerik.Sitefinity.DynamicModules.Model;
var items = ManagerBase.GetItems(this.FeaturedSolutions, "Telerik.Sitefinity.DynamicTypes.Model.KnowledgeBase.Solution")
.OfType<DynamicContent>()
.Where(dc => dc.Status == ContentLifecycleStatus.Live && dc.Visible)
.ToList();
Required Using Statements
using Progress.Sitefinity.Renderer.Entities.Content;
using Progress.Sitefinity.Renderer.Designers.Attributes;
using Telerik.Sitefinity.Data;
using Telerik.Sitefinity.GenericContent.Model;
using Telerik.Sitefinity.Libraries.Model;
using Telerik.Sitefinity.DynamicModules.Model;
using Telerik.Sitefinity.Modules.Pages.PropertyPersisters;
Legacy pattern: Older widgets used Guid? ImageId + App.WorkWith().Image(id).Get(). New code should always use MixedContentContext — it supports the content picker UI and multiple selections.
KnownContentTypes Constants
| Constant | Value |
|---|
KnownContentTypes.Pages | Telerik.Sitefinity.Pages.Model.PageNode |
KnownContentTypes.Images | Telerik.Sitefinity.Libraries.Model.Image |
KnownContentTypes.Videos | Telerik.Sitefinity.Libraries.Model.Video |
KnownContentTypes.Documents | Telerik.Sitefinity.Libraries.Model.Document |
KnownContentTypes.News | Telerik.Sitefinity.News.Model.NewsItem |
KnownContentTypes.Events | Telerik.Sitefinity.Events.Model.Event |
KnownContentTypes.BlogPost | Telerik.Sitefinity.Blogs.Model.BlogPost |
KnownContentTypes.Forms | Telerik.Sitefinity.Forms.Model.FormDescription |
KnownContentTypes.Albums | Telerik.Sitefinity.Libraries.Model.Album |
KnownContentTypes.Tags | Taxonomy_Tags |
KnownContentTypes.Categories | Taxonomy_Categories |
KnownContentTypes.GenericContent | Telerik.Sitefinity.GenericContent.Model.ContentItem |
KnownContentTypes.Lists | Telerik.Sitefinity.Lists.Model.List |
KnownContentTypes.ListItems | Telerik.Sitefinity.Lists.Model.ListItem |
KnownContentTypes.Blogs | Telerik.Sitefinity.Blogs.Model.Blog |
KnownContentTypes.Calendars | Telerik.Sitefinity.Events.Model.Calendar |
KnownContentTypes.DocumentLibraries | Telerik.Sitefinity.Libraries.Model.DocumentLibrary |
KnownContentTypes.VideoLibraries | Telerik.Sitefinity.Libraries.Model.VideoLibrary |
KnownContentTypes.Folders | Telerik.Sitefinity.Model.Folder |
KnownContentTypes.PageTemplates | Telerik.Sitefinity.Pages.Model.PageTemplate |
KnownContentTypes.Sites | Telerik.Sitefinity.Multisite.Model.Site |
KnownContentTypes.Taxonomies | Telerik.Sitefinity.Taxonomies.Model.Taxonomy |
Links (LinkModel)
Always use LinkModel for any button or link property. Do NOT use separate string ButtonText + string ButtonUrl properties — LinkModel gives editors a proper link picker UI with page selection, target, tooltip, and anchor support all in one field.
Confirmed available in MVC: LinkModel is at Progress.Sitefinity.Renderer.Models.LinkModel in Progress.Sitefinity.Renderer.dll (verified by reflection on Sitefinity 15.4).
LinkModel Properties (from DLL reflection)
| Type | Property | Description |
|---|
string | Href | The URL or page path |
string | Text | Link display text |
string | Target | Target attribute (_blank, _self, etc.) |
string | Tooltip | Tooltip text |
string | Sfref | Sitefinity internal reference (for CMS pages/content) |
Guid | Id | Content item ID (when linking to CMS content) |
string | Type | Link type |
string | QueryParams | Query string parameters |
string | Anchor | Anchor/hash fragment |
List<string> | ClassList | CSS classes |
IDictionary<string,string> | Attributes | Custom HTML attributes |
Declaring LinkModel Properties
using Progress.Sitefinity.Renderer.Models;
public LinkModel Link { get; set; }
[DataType(customDataType: "linkSelector")]
public LinkModel EnhancedLink { get; set; }
[DataType(customDataType: "linkSelector")]
public LinkModel[] Links { get; set; }
[Required]
[DataType(customDataType: "linkSelector")]
public LinkModel RequiredLink { get; set; }
Reading LinkModel in Controllers
LinkModel is a complex object persisted as JSON by Sitefinity. Access properties with null-safety:
var buttonText = this.PrimaryButton?.Text ?? "Default Text";
var buttonUrl = this.PrimaryButton?.Href ?? "#";
var openInNewTab = this.PrimaryButton?.Target == "_blank";
Rendering LinkModel in Razor Views
@if (Model.Link != null && !string.IsNullOrEmpty(Model.Link.Href))
{
<a href="@Model.Link.Href"
target="@Model.Link.Target"
title="@Model.Link.Tooltip">
@Model.Link.Text
</a>
}
Serializing LinkModel to JSON for a JS Frontend
When serializing link data to JSON for a JS frontend (see the companion skill sitefinity-vue3-vite8-guide for the config-island pattern), extract the properties you need:
link = this.PrimaryLink != null ? new
{
href = this.PrimaryLink.Href ?? "#",
text = this.PrimaryLink.Text ?? "",
target = this.PrimaryLink.Target ?? "_self"
} : null
Media Items
Namespace: Progress.Sitefinity.Renderer.Designers.Attributes
[MediaItem] — Image/Document/Video Selector
| Constructor Param | Type | Description |
|---|
itemType | string | Media type: "images", "documents", "videos" |
allowMultipleSelection | bool | Allow selecting multiple items |
standalone | bool | Standalone mode |
[MediaItem("images", false, false)]
public string HeroImage { get; set; }
[MediaItem("images", true, false)]
public string GalleryImages { get; set; }
[MediaItem("documents", false, false)]
public string DownloadFile { get; set; }
Renderer Attributes Reference
Complete list of all attributes in Progress.Sitefinity.Renderer.Designers.Attributes (from DLL reflection). Most commonly-used attributes are documented in their own sections above; this is the comprehensive reference for lesser-known ones.
[Dialog(data)]
Opens a dialog/modal for editing. The data string configures the dialog behavior.
[Dialog("{\"dialogKey\":\"customEditor\"}")]
public string AdvancedContent { get; set; }
[EnumDisplayName("Label")]
Custom display name for enum values (alternative to [Description]).
public enum Layout
{
[EnumDisplayName("Single Column Layout")]
Single,
[EnumDisplayName("Two Column Layout")]
Double
}
[Icon("name")]
Associates a Font Awesome icon with a property or enum value (name without fa- prefix).
public enum Layout
{
[Icon("columns")]
[Description("Two Columns")]
TwoCol,
[Icon("th-large")]
[Description("Grid")]
Grid
}
[InitialValue("propName", "value")]
Sets an initial value for a sub-property when a complex object is first created.
[InitialValue("Text", "Click me")]
[InitialValue("Url", "#")]
public ButtonConfig Button { get; set; }
[IsNullable(true)]
Marks a property as nullable in the designer, allowing it to be cleared.
[IsNullable(true)]
public int? OptionalCount { get; set; }
[LengthDependsOn("propertyName", "displayName", "displayTitle")]
Links a property's length/validation to another property. Used with Attributes field type.
| Property | Type | Description |
|---|
PropertyName | string | Source property name |
DisplayName | string | Display label |
DisplayTitle | string | Title text |
ExtraRecords | string | JSON array of additional records |
[MappedType(DataType = "typeName")]
Maps a property to a specific Sitefinity data type.
[MappedType(DataType = "sf-long-text")]
public string JsonData { get; set; }
[RangeLimitation(allowZeroes, initialRangeType)]
Configures range limitation behavior for numeric fields.
[SectionsOrder("Section1", "Section2", ...)]
Controls the display order of content sections in the designer. Apply to the widget class.
[SectionsOrder("Content", "Appearance", "Layout")]
public class MyWidgetEntity
{
[ContentSection("Content", 0)]
public string Heading { get; set; }
[ContentSection("Appearance", 0)]
public string Color { get; set; }
[ContentSection("Layout", 0)]
public int Columns { get; set; }
}
[TaxonomyContent(Type = "taxonomy-name")]
Content selector specifically for taxonomy items (tags, categories, custom taxonomies). Extends [Content].
[TaxonomyContent(Type = KnownContentTypes.Tags)]
public MixedContentContext Tags { get; set; }
[TaxonomyContent(Type = "geographical-regions")]
public MixedContentContext Regions { get; set; }
KnownFieldTypes Reference
IMPORTANT: The actual string values are lowercase/camelCase — confirmed by reflecting on Progress.Sitefinity.Renderer.dll. Using the wrong case (e.g., "TextArea" instead of "textArea") may cause the field to render as a plain text input.
| Constant | Actual String Value | UI Element |
|---|
KnownFieldTypes.Html | "html" | Rich text HTML editor |
KnownFieldTypes.TextArea | "textArea" | Multi-line text area |
KnownFieldTypes.Password | "password" | Password (masked) input |
KnownFieldTypes.CheckBox | "choiceYesNo" | Single checkbox (for bool) |
KnownFieldTypes.RadioChoice | "radioChoices" | Radio button group (for enums) |
KnownFieldTypes.ChipChoice | "chipchoice" | Chip/pill selector (for enums or ints) |
KnownFieldTypes.Choices | "choices" | Dropdown selector (for ints with [Choice]) |
KnownFieldTypes.ChoiceMultiple | "choiceMultiple" | Multi-select dropdown |
KnownFieldTypes.MultipleChoiceChip | "multipleChoiceChip" | Multi-select chip selector |
KnownFieldTypes.ChoiceList | "choiceList" | Choice list |
KnownFieldTypes.Color | "color" | Color picker |
KnownFieldTypes.Range | "range" | Range slider (uses NumericRange type) |
KnownFieldTypes.RangeLimitation | "rangeLimitation" | Range with limits |
KnownFieldTypes.Attributes | "attributes" | Key-value attribute editor |
KnownFieldTypes.FileTypes | "fileTypes" | File type picker (uses FileTypes type) |
KnownFieldTypes.PencilButton | "pencilButton" | Pencil/edit button |
KnownFieldTypes.DropdownWithText | "dropdownWithText" | Dropdown with text input |
Usage in MVC Controllers
With Progress.Sitefinity.Renderer.dll referenced by your widgets project, use the KnownFieldTypes constants directly:
using Progress.Sitefinity.Renderer.Designers;
[DataType(customDataType: KnownFieldTypes.TextArea)]
public string Description { get; set; }
[DataType(customDataType: KnownFieldTypes.Color)]
public string BackgroundColor { get; set; }
[DataType(customDataType: KnownFieldTypes.Html)]
public string RichContent { get; set; }
[DataType(customDataType: KnownFieldTypes.CheckBox)]
public bool ShowTitle { get; set; }
The raw string values are documented in the table above for reference, but prefer using the constants for compile-time safety.
PropertyCategory Reference
Constants for the [Category()] attribute. From Progress.Sitefinity.Renderer.Designers.PropertyCategory:
| Constant | Value | Description |
|---|
PropertyCategory.Basic | "Basic" | Default view (properties appear here by default) |
PropertyCategory.Advanced | "Advanced" | Advanced tab — for power-user settings |
PropertyCategory.QuickEdit | "QuickEdit" | Quick edit mode — inline editing on the page |
DataType Special Values
using Progress.Sitefinity.Renderer.Designers;
using Progress.Sitefinity.Renderer.Models;
[DataType(customDataType: KnownFieldTypes.Html)]
public string RichContent { get; set; }
[DataType(customDataType: KnownFieldTypes.TextArea)]
public string LongDescription { get; set; }
[DataType(customDataType: KnownFieldTypes.Color)]
public string BackgroundColor { get; set; }
[DataType(customDataType: KnownFieldTypes.Password)]
public string ApiKey { get; set; }
[DataType(customDataType: KnownFieldTypes.Range)]
[Suffix("px")]
public NumericRange Padding { get; set; }
[DataType(customDataType: "linkSelector")]
public LinkModel Link { get; set; }
Date Settings
[DateSettings(ShowTime = false)]
public DateTime PublishDate { get; set; }
public DateTime EventStart { get; set; }
Documentation Links