Dev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Create custom module settings

Describes how to create custom module settings in Optimizely Configured Commerce.

Optimizely Configured Commerce provides many standard settings that allow you to configure how the application behaves. These settings can be configured in the Admin Console. In addition to standard settings, you can create your own settings to provide configuration for new features or additional configuration for existing features.

The settings created for this user label will be displayed in the Admin Console in their own, new setting sub-group named "User Label Settings".

Settings can also be added to an existing sub-group, like Order Management > Cart. In that example, Cart is the sub-group and Order Management is the primary group.

📘

Prerequisite

  • Visual Studio installed
  • Configured Commerce SDK installed

Create the settings class

  1. In Visual Studio, open the < solution.

  2. In your Extensions project, add a new class and name it "UserLabelSettings".

  3. In the new class, inherit from the BaseSettingsGroup class and implement the IExtension interface. Inheriting from BaseSettingsGroup will make these settings available to manage in the Admin Console.

    namespace Extensions
    {
      using Insite.Core.Interfaces.Dependency;
      using Insite.Core.SystemSetting;
      using Insite.Core.SystemSetting.Groups;
      public class UserLabelSettings : BaseSettingsGroup, IExtension
      {
      }
    }
    
  4. Decorate the class with the [SettingsGroup] attribute. Within the attribute constructor, set the PrimaryGroupName equal to "AccountManagement" and the Label equal to "User Label Settings". The PrimaryGroupName maps to an existing primary settings group. This means these settings will display within that group in the Admin Console. The Label is the title displayed above the settings in the Admin Console. It is also a mapping to any existing sub-groups. Settings groups that share the same PrimaryGroupName will display within the same settings finger tab in the Admin Console.Settings groups that share the same PrimaryGroupName and Label will display within the same settings finger tab and under the same sub-group heading in the Admin Console.

    [SettingsGroup(PrimaryGroupName = "AccountManagement", Label = "User Label Settings")]
    public class UserLabelSettings : BaseSettingsGroup, IExtension
    {
    }
    
  5. In the body of the class, declare a property named "LabelFormat". The property is set to the return value of this.GetValue which is provided by the BaseSettingsGroup class. This method finds the value of this setting in the database. If the value does not exist, the default value is returned. The first argument to the method is the default value.

    [SettingsGroup(PrimaryGroupName = "AccountManagement", Label = "User Label Settings")]
    public class UserLabelSettings : BaseSettingsGroup, IExtension
    {
      public virtual string LabelFormat => this.GetValue("{userName} ({firstName} {lastName})");
    }
    
  6. Decorate the "LabelFormat" property with the [SettingsField] attribute. Within the attribute constructor, set the DisplayName equal to "Label Format". This attribute is used to configure how the setting is displayed in the Admin Console. In other words, what does the label and form element look like for this setting. The DisplayName text is used for the form element label. The Description text will cause a question mark (question) icon to display next to the label. The actual text is displayed in a tooltip when the icon is hovered. This can be used for help text so a user can understand the purpose of the setting.

    [SettingsField(DisplayName = "Label Format", Description = "The format used for displaying the user label.")]
    public virtual string LabelFormat => this.GetValue("{userName} ({firstName} {lastName})");
    

    For reference, the completed settings class is displayed below.

    namespace Extensions
    {
      using Insite.Core.Interfaces.Dependency;
      using Insite.Core.SystemSetting;
      using Insite.Core.SystemSetting.Groups;
         [SettingsGroup(PrimaryGroupName = "AccountManagement", Label = "User Label Settings")]
      public class UserLabelSettings : BaseSettingsGroup, IExtension
      {
        [SettingsField(DisplayName = "Label Format", Description = "The format used for displaying the user label.")]
        public virtual string LabelFormat => this.GetValue("{userName} ({firstName} {lastName})");
      }
    }
    
  7. Build your solution.

Now that the settings class is complete, you can use the setting in code. In this walk-through, the UserLabelSettings.LabelFormat setting will be used within a handler to format the user label returned to the Storefront.

Use the settings class in code

This section will create a new handler and insert it within an existing handler chain. The configuration of the handler will not be explained in detail. It is expected that you are already familiar with handlers and handler chains.

  1. In your Extensions project, add a new class and name it "FormatUserLabel".

  2. In the new class, inherit from the HandlerBase<GetSessionParameter, GetSessionResult> class and implement it. This will inject the handler into the "GetSessionHandler" handler chain.

    namespace Extensions.Handlers.GetSessionHandler
    {
      using Insite.Account.Services.Parameters;
      using Insite.Account.Services.Results;
      using Insite.Core.Interfaces.Data;
      using Insite.Core.Interfaces.Dependency;
      using Insite.Core.Services.Handlers;
         public class FormatUserLabel : HandlerBase<GetSessionParameter, GetSessionResult>
      {
        public override GetSessionResult Execute(IUnitOfWork unitOfWork, GetSessionParameter parameter, GetSessionResult result)
        {
          throw new System.NotImplementedException();
        }
        public override int Order { get; }
      }
    }
    
  3. Decorate the class with the [DependencyName] attribute, using nameof(FormatUserLabel) as the "name" argument.

    [DependencyName(nameof(FormatUserLabel))]
    public class FormatUserLabel : HandlerBase<GetSessionParameter, GetSessionResult>
    {
    }
    
  4. Set the Order property to 3000 to ensure the handler is executed last in the chain.

    public override int Order => 3000;
    
  5. Declare a constructor and specify the UserLabelSettings class you created earlier as the first parameter. Save the settings class in a property for later use.

    private readonly UserLabelSettings userLabelSettings;
       public FormatUserLabel(UserLabelSettings userLabelSettings)
    {
      this.userLabelSettings = userLabelSettings;
    }
    
  6. Within the Execute method, add the following code. The label format uses named tokens that are replaced with data from the user profile. This code is just an example and thus is not very robust. If the format included any static characters (not tokens), those would still appear even if the user did not specify a first or last name. Username is required so that token should always be replaced.

    public override GetSessionResult Execute(IUnitOfWork unitOfWork, GetSessionParameter parameter, GetSessionResult result)
    {
      var labelFormat = this.userLabelSettings.LabelFormat;
         if (!labelFormat.IsBlank() && result.UserProfile != null)
      {
        result.UserLabel = labelFormat
        .Replace("{userName}", result.UserProfile.UserName)
        .Replace("{firstName}", result.UserProfile.FirstName)
        .Replace("{lastName}", result.UserProfile.LastName)
        .Trim();
      }
    
      return result;
    }
    

    For reference, the completed handler is displayed below.

    namespace Extensions.Handlers.GetSessionHandler
    {
      using System;
         using Insite.Account.Services.Parameters;
      using Insite.Account.Services.Results;
      using Insite.Core.Interfaces.Data;
      using Insite.Core.Interfaces.Dependency;
      using Insite.Core.Services.Handlers;
         [DependencyName(nameof(FormatUserLabel))]
      public class FormatUserLabel : HandlerBase<GetSessionParameter, GetSessionResult>
      {
        private readonly UserLabelSettings userLabelSettings;
    
        public override int Order => 3000;
    
        public FormatUserLabel(UserLabelSettings userLabelSettings)
        {
          this.userLabelSettings = userLabelSettings;
        }
           public override GetSessionResult Execute(IUnitOfWork unitOfWork, GetSessionParameter parameter, GetSessionResult result)
        {
          var labelFormat = this.userLabelSettings.LabelFormat;
          if (!labelFormat.IsBlank() && result.UserProfile != null)
          {
            result.UserLabel = labelFormat
            .Replace("{userName}", result.UserProfile.UserName)
            .Replace("{firstName}", result.UserProfile.FirstName)
            .Replace("{lastName}", result.UserProfile.LastName)
            .Trim();
          }
    
          return result;
        }
      }
    }
    
  7. Build your solution.

Now that the user label settings are being used in code, you can see them in action. However, first you need to specify a label format for your new setting in the Admin Console.

Configure the settings in the admin console

  1. Open a browser and go to the Admin Console for your application. You can do this by going to http://{your_website_domain}/admin.

  2. Sign in and go to Administration > System > Settings.

  3. Once you are there, select the Account Management finger tab. This is where you added your new setting. The Account Management finger tab is considered the settings primary group.

  4. Scroll down until you see your new setting. It will be located under the "User Label Settings" heading you specified. The "User Label Settings" is considered the settings sub-group.

  5. In the Label Format textbox, type "{userName} ({firstName} {lastName})".

    This explanation dives a bit deeper into settings, so feel free to skip if you want.

    If you leave the Label Format value blank, the user label will still be formatted correctly on the storefront. This is due to the default value specified for the UserLabelSettings.LabelFormat property. All settings are eventually stored in the database. Eventually meaning that when a new setting is first created, a value for it is not stored in the database. If the application attempts to access the setting, it attempts to find the value in the database. If a value does not exist in the database, the default value will be saved to the database and returned as the value.

    Once a value for the setting is saved in the Admin Console, the application will use that value. However, if you don't like the current setting value and want to revert to the default value specified in the settings class, you can click the "Restore default" link adjacent to the field, as shown above.

  6. Click Save in the top right corner.

Now that the setting has been configured in the Admin Console, you can see the setting in action on the Storefront.

See setting in action on storefront

Before you start, make sure you have a website user that is activated and has specified a first and last name. This way you can see the label format in full effect.

Go to the storefront and sign in. After that, you should see the user label formatted using your new format. The user label that is affected is in the bar at the top of the page.

Conclusion

Configured Commerce relies on configuration for a good portion of its functionality. This configuration is provided using settings. Settings allow you to configure the application rather than provide custom code extensions. Configured Commerce provides a large amount of standard settings to configure the application. However, if the standard settings do not provide enough configuration or you need to configure a new feature specific to your instance that does not have settings, you can create your own settings. Your own settings can be used just like standard settings and configured in the Admin Console.