---
title: Customize widget attributes
slug: configured-commerce/docs/custom-widget-attributes-in-classic
docTags: 
createdAt: 2026-08-13T10:46:23.000Z
---

:::hint{type="warning"}
**Important**

Classic CMS reached end-of-life in January 2025 and is no longer receiving feature updates or bug fixes. You should \[migrate to Spire CMS]\(../../End user docs/spire-cms/get-started-with-spire-cms/migrate-from-classic-cms-to-spire-cms.mdx).
:::

After creating a custom widget, it is likely that you'll also want to include custom attributes that the end user can access and alter as needed based on the widget.

`ContentFieldAttributes` can be used to customize the display/editing of a property on a widget. An example of this is adding a Country Selection ability to a widget.

First create a new class with the following content. In this example we are inheriting from an existing attribute. An important thing to note is that we override `GenericType` to return `typeof(DropDownContentFieldAttribute)`. This is required to make use of the existing html template, without it a new html template would be required

```csharp
public class CountrySelector : DropDownContentFieldAttribute
{
    public override Type GenericType => typeof(DropDownContentFieldAttribute);
 
    public CountrySelector() : base(new string[0])
    {
        var countries = DependencyLocator.Current.GetInstance<IUnitOfWorkFactory>().GetUnitOfWork().GetRepository<Country>().GetTable().OrderBy(o => o.Name).ToList();
        this.Options = countries.Select(o => new KeyValuePair<string, string>(o.Id.ToString(), o.Name)).ToArray();
    }
}
```

If a custom HTML template is needed for our new attribute, then the Template property can be set in our new class. In order to make sure of a razor view from the extensions project, this value needs to start with "\~/Extensions/" followed by the path to the view inside of the project.

```csharp
public class CountrySelector : DropDownContentFieldAttribute
{
    public CountrySelector() : base(new string[0])
    {
        this.Template = "~/Extensions/Views/ContentItemFields/CountrySelector.cshtml";
 
        var countries = DependencyLocator.Current.GetInstance<IUnitOfWorkFactory>().GetUnitOfWork().GetRepository<Country>().GetTable().OrderBy(o => o.Name).ToList();
        this.Options = countries.Select(o => new KeyValuePair<string, string>(o.Id.ToString(), o.Name)).ToArray();
    }
}
```

Then in the extensions project a razor view needs to exist at *Views/ContentItemFields/CountrySelector.cshtml*. By default, the extensions project will embed all razor views, which is required for the view to be available to Configured Commerce.

This example is a copy of the *DropDown.cshtml* view, with the `@model` declaration modified to use `Extensions.CountrySelector`.

```xml
@using Insite.ContentLibrary.ContentFields
@using Insite.WebFramework.ContentAdmin.Models.ContentItems
 
@model EditContentFieldModel<Extensions.CountrySelector>
 
<label for="@Model.FieldName">
    @Model.DisplayName
    @if (Model.ContentFieldAttribute.IsRequired)
    {
        <span class="required">(required)</span>
    }
 
    @Html.Partial("ContentItemFields/_ContextDisplay", Model.ContentItemFieldModel)
</label>
<span data-valmsg-replace="true" data-valmsg-for="@(Model.FieldName)"></span>
<select id="@Model.FieldName" name="@Model.FieldName" @if (Model.ContentFieldAttribute.IsRequired) { <text> data-val="true" data-val-required="Value is required" </text> }>
    <option value="">Select Value</option>
    @foreach (var value in Model.ContentFieldAttribute.Options)
    {
        <option value="@value.Key" @(Model.GetValue().ToString() == value.Key ? "selected" : "")>@value.Value</option>
    }
</select>
```

To make use of the new `ContentFieldAttribute`, add a new property to a custom widget. Then include your new attribute on the property. When editing this widget, the `CountrySelector` will be used.

```csharp
[CountrySelector]
public string SelectedCountry
{
    get { return this.GetValue("SelectedCountry", string.Empty, FieldType.General); }
    set { this.SetValue("SelectedCountry", value, FieldType.General); }
```
