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
- Field Types
- Display Attributes
- Validation Attributes
- Sections and Views
- Conditional Visibility
- Content Selectors
- Color Palettes
- Complex Objects and Table View
- Collections
- Choice Fields
- Links (LinkModel)
- Media Items
- Renderer Attributes Reference
- KnownFieldTypes Reference
- PropertyCategory Reference
- Documentation Links
Namespaces
For MVC (.NET Framework 4.8):
using Telerik.Sitefinity.Web.Services.PropertyEditor.Attributes; // ConditionalVisibility
using Telerik.Sitefinity.Frontend.Mvc.Infrastructure.Controllers.Attributes; // ViewSelector, EnhanceViewEnginesAttribute
using Telerik.Sitefinity.Web.Services.Contracts.Operations.Pages.PropertyEditor.AttributeConfigurator.Attributes; // IndexRenderMode
using Progress.Sitefinity.Renderer.Designers; // KnownFieldTypes, PropertyCategory
using Progress.Sitefinity.Renderer.Designers.Attributes; // TableView, ContentSection, Choice, MediaItem, etc.
using Progress.Sitefinity.Renderer.Models; // LinkModel (available in MVC via Progress.Sitefinity.Renderer.dll)
using System.ComponentModel; // DisplayName, Description, DefaultValue, Browsable, Category
using System.ComponentModel.DataAnnotations; // Required, Range, StringLength, DataType, etc.
Important:
Progress.Sitefinity.Renderer.dllships with Sitefinity 14.3+ — reference it from the project where your widget controllers live. The types inProgress.Sitefinity.Renderer.Designers.Attributeswork in MVC controllers (with the exceptions explicitly flagged below, e.g.[ColorPalette]which is ASP.NET Core renderer-only).
KnownFieldTypesandPropertyCategoryare classes with string constants — use them directly viausing 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(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")] // ISO 8601 format for dates
public DateTime StartDate { get; set; }
[DefaultValue(EnumSingle.Value2)] // Enum default
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; } // Auto-fills from Title
[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 (fromTelerik.Sitefinity.Frontend) only discovers views in the ResourcePackages theme folder (ResourcePackages/{Theme}/MVC/Views/{Widget}/), NOT in the standardMvc/Views/folder. If your custom widget views live inMvc/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.
// ❌ Doesn't work for custom MVC widgets (views not in ResourcePackages)
[ViewSelector]
public string TemplateName { get; set; }
// ✅ Recommended: Use an enum for template selection
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;
// Derive the view name from the enum (hidden from designer)
[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; }
Sections and Views
Basic vs. Advanced Views
Properties default to the Basic view. Use [Category(PropertyCategory.Advanced)] to move to the Advanced tab.
// This appears in the Basic (default) view
public string Heading { get; set; }
// This appears in the Advanced tab
[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)] // First property in Content section
public string Heading { get; set; }
[ContentSection(ContentSection, 1)] // Second property in Content section
public string Description { get; set; }
[ContentSection(AppearanceSection, 0)] // First property in Appearance section
public string BackgroundColor { get; set; }
[ContentSection(AppearanceSection, 1)] // Second property in Appearance section
public string TextAlignment { get; set; }
// Advanced section with its own groups
[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; }
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
// Show BackgroundImageUrl only when TemplateName equals "Split"
[ConditionalVisibility("{\"conditions\":[{\"fieldName\":\"TemplateName\",\"operator\":\"Equals\",\"value\":\"Split\"}]}")]
public string BackgroundImageUrl { get; set; }
Boolean Condition
[DefaultValue(false)]
public bool ShowSecondaryButton { get; set; }
// Show these only when ShowSecondaryButton is true
[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
Content Selectors
Select Sitefinity content items (pages, images, news, dynamic content, taxonomies).
// Single image selector
[Content(Type = KnownContentTypes.Images)]
public MixedContentContext HeroImage { get; set; }
// Multiple images
[Content(Type = KnownContentTypes.Images, AllowMultipleItemsSelection = true)]
public MixedContentContext GalleryImages { get; set; }
// Page selector (single, with site selector)
[Content(Type = KnownContentTypes.Pages, AllowMultipleItemsSelection = false, ShowSiteSelector = true)]
public MixedContentContext TargetPage { get; set; }
// Page selector with additional options
[Content(Type = KnownContentTypes.Pages, AllowMultipleItemsSelection = false, DisableInteraction = true, ShowSiteSelector = true)]
public MixedContentContext SinglePage { get; set; }
// Document library with specific provider, no create button
[Content(Type = KnownContentTypes.DocumentLibraries, AllowMultipleItemsSelection = false, AllowCreate = false, Provider = "secondlibraries")]
public MixedContentContext DocumentLibrary { get; set; }
// Live data (published items only)
[Content(Type = KnownContentTypes.News, LiveData = true)]
public MixedContentContext PublishedNews { get; set; }
// Dynamic content types
[Content(Type = "Telerik.Sitefinity.DynamicTypes.Model.Pressreleases.PressRelease")]
public MixedContentContext PressReleases { get; set; }
// Albums
[Content(Type = KnownContentTypes.Albums)]
public MixedContentContext Albums { get; set; }
// All content types (unfiltered)
[Content]
public MixedContentContext AnyContent { get; set; }
// Taxonomy selectors
[TaxonomyContent(Type = KnownContentTypes.Tags)]
public MixedContentContext Tags { get; set; }
[TaxonomyContent(Type = KnownContentTypes.Categories)]
public MixedContentContext Categories { get; set; }
// Custom taxonomy
[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:
ColorPaletteAttributedoes not exist inProgress.Sitefinity.Renderer.dll(15.4) or any other assembly in an MVC site'sbin\. 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.
// ASP.NET Core renderer ONLY:
[ColorPalette("Default")]
public string BackgroundColor { get; set; }
// Custom palette (appsettings.json under Widgets > Styling > Colorpalettes) — ASP.NET Core only
[ColorPalette("Company")]
public string BrandColor { get; set; }
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; }
}
// Usage in widget entity
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) |
// Show only Title column, hide Description and Icon behind "More details"
[TableView(Reorderable = true, ColumnCount = 1)]
public IList<FeatureItem> Features { get; set; } = new List<FeatureItem>();
// Full table with all columns, reorderable and selectable
[TableView(Reorderable = true, Selectable = true, MultipleSelect = true)]
public IList<ButtonConfig> Buttons { get; set; } = new List<ButtonConfig>();
// With column title header
[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)] // First column — visible when ColumnCount = 1
[DisplayName("Title")]
public string Title { get; set; }
[ContentSection(2)] // Second column — hidden when ColumnCount = 1
[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-tablein the AdminApp bundle - The pencil button (
sf-pencil-button) triggerspopulateNestedComplexSettings(...)internally, which createsdialogDatawith 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:
- ❌ Bad:
<sf-input [label]="'Name'" [(ngModel)]="...">— usessf-input__label, looks cramped and non-native - ✅ Good: Wrap in
sf-field-wrapperfor proper label styling:<sf-field-wrapper [label]="'Name'"> <sf-input [placeholder]="'Name'" [(ngModel)]="..."></sf-input> </sf-field-wrapper>
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 rowsf-button look="circle small" icon="plus" iconlook="size-xs"— add button below table
Docs: Autogenerated complex objects
Collections
// Simple list of strings
public IList<string> Tags { get; set; }
// List of complex objects
public IList<ButtonConfig> ActionButtons { get; set; }
// Dictionary
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.
// Dynamic choices from a service endpoint
[Choice(ServiceUrl = "/api/my-choices")]
[DataType(customDataType: KnownFieldTypes.Choices)]
public string DynamicChoice { get; set; }
// Custom attribute approach
[ExternalDataChoice]
[DataType(customDataType: KnownFieldTypes.Choices)]
public string DynamicChoiceSingle { get; set; }
Custom attribute approach requires implementing
ExternalDataChoiceAttributeandExternalChoicePropertyConfigurator. 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)] // Hidden from designer
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;
// Single image
[Content(Type = KnownContentTypes.Images, AllowMultipleItemsSelection = false)]
[PropertyPersistence(PersistAsJson = true)]
public MixedContentContext HeroImage { get; set; }
// Multiple documents
[Content(Type = KnownContentTypes.Documents)]
[PropertyPersistence(PersistAsJson = true)]
public MixedContentContext Attachments { get; set; }
// Dynamic content type
[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;
// 1. Null-check the context
if (this.HeroImage == null) return;
// 2. Resolve items via ManagerBase
var items = ManagerBase.GetItems(this.HeroImage, KnownContentTypes.Images)
.OfType<Telerik.Sitefinity.Libraries.Model.Image>()
.Where(i => i.Status == ContentLifecycleStatus.Live)
.ToList();
// 3. Extract what you need
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; // Full-size URL
model.AltText = img.AlternativeText; // Alt text
model.ThumbUrl = img.ResolveThumbnailUrl("profileName"); // Sized thumbnail
}
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; // MixedContentContext
using Progress.Sitefinity.Renderer.Designers.Attributes; // [Content], KnownContentTypes
using Telerik.Sitefinity.Data; // ManagerBase
using Telerik.Sitefinity.GenericContent.Model; // ContentLifecycleStatus
using Telerik.Sitefinity.Libraries.Model; // Image, Document, Video
using Telerik.Sitefinity.DynamicModules.Model; // DynamicContent
using Telerik.Sitefinity.Modules.Pages.PropertyPersisters; // [PropertyPersistence]
Legacy pattern: Older widgets used
Guid? ImageId+App.WorkWith().Image(id).Get(). New code should always useMixedContentContext— 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
LinkModelfor any button or link property. Do NOT use separatestring ButtonText+string ButtonUrlproperties —LinkModelgives editors a proper link picker UI with page selection, target, tooltip, and anchor support all in one field.Confirmed available in MVC:
LinkModelis atProgress.Sitefinity.Renderer.Models.LinkModelinProgress.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;
// Basic link model (pre-14.4 UI)
public LinkModel Link { get; set; }
// Enhanced link selector (14.4+ UI — recommended)
[DataType(customDataType: "linkSelector")]
public LinkModel EnhancedLink { get; set; }
// Multiple links
[DataType(customDataType: "linkSelector")]
public LinkModel[] Links { get; set; }
// Required link
[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 Vue
When passing to Vue via ConfigJson, 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 |
// Single image selector
[MediaItem("images", false, false)]
public string HeroImage { get; set; }
// Multiple images
[MediaItem("images", true, false)]
public string GalleryImages { get; set; }
// Document selector
[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;
// Multi-line text area
[DataType(customDataType: KnownFieldTypes.TextArea)]
public string Description { get; set; }
// Color picker
[DataType(customDataType: KnownFieldTypes.Color)]
public string BackgroundColor { get; set; }
// Rich text HTML editor
[DataType(customDataType: KnownFieldTypes.Html)]
public string RichContent { get; set; }
// Checkbox
[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;
// HTML rich text editor
[DataType(customDataType: KnownFieldTypes.Html)]
public string RichContent { get; set; }
// Multi-line text area
[DataType(customDataType: KnownFieldTypes.TextArea)]
public string LongDescription { get; set; }
// Color picker
[DataType(customDataType: KnownFieldTypes.Color)]
public string BackgroundColor { get; set; }
// Password field
[DataType(customDataType: KnownFieldTypes.Password)]
public string ApiKey { get; set; }
// Range slider with suffix
[DataType(customDataType: KnownFieldTypes.Range)]
[Suffix("px")]
public NumericRange Padding { get; set; }
// Link selector (recommended — enhanced UI)
[DataType(customDataType: "linkSelector")]
public LinkModel Link { get; set; }
Date Settings
// Date only (no time picker)
[DateSettings(ShowTime = false)]
public DateTime PublishDate { get; set; }
// Full date-time (default)
public DateTime EventStart { get; set; }