sitefinity-designer-attributes

star 2

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.

sitefinitysteve By sitefinitysteve schedule Updated 6/11/2026

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;  // 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.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(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 (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.

// ❌ 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; }

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.

// 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; }

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

// 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

Docs: Conditional fields


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: 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.

// 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; }

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; }
}

// 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-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:

  • ❌ Bad: <sf-input [label]="'Name'" [(ngModel)]="..."> — uses sf-input__label, looks cramped and non-native
  • ✅ Good: Wrap in sf-field-wrapper for 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 row
  • sf-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 ExternalDataChoiceAttribute and ExternalChoicePropertyConfigurator. 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 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;

// 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; }

Documentation Links

Topic URL
Overview https://www.progress.com/documentation/sitefinity-cms/autogenerated-widget-property-editors-for-asp.net-core
Field Types https://www.progress.com/documentation/sitefinity-cms/autogenerated-field-types
Customize Fields https://www.progress.com/documentation/sitefinity-cms/customize-autogenerated-fields
Complex Objects https://www.progress.com/documentation/sitefinity-cms/autogenerated-complex-objects
Validations https://www.progress.com/documentation/sitefinity-cms/field-validations
Conditional Fields https://www.progress.com/documentation/sitefinity-cms/conditional-fields
Sections & Views https://www.progress.com/documentation/sitefinity-cms/sections-and-views
Sample: All Properties https://www.progress.com/documentation/sitefinity-cms/sample--all-properties-widget-designer
Sample: Mega Menu https://www.progress.com/documentation/sitefinity-cms/sample--mega-menu
Sample: Tabs Section https://www.progress.com/documentation/sitefinity-cms/sample--tabs-section
Sample: Color Palettes https://www.progress.com/documentation/sitefinity-cms/sample--color-palettes-sample
GitHub Samples Repo https://github.com/Sitefinity/sitefinity-aspnetcore-mvc-samples
Install via CLI
npx skills add https://github.com/sitefinitysteve/SitefinityCommunity.Mcp --skill sitefinity-designer-attributes
Repository Details
star Stars 2
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
sitefinitysteve
sitefinitysteve Explore all skills →