🧩 Framework Components
Plugins Extending Ui
📖 Docs

Plugins and Extending UI - Optimizely CMS 12

Exam Area: Area 4 – Framework Components (15%)
Reference: https://docs.developers.optimizely.com/content-management-system/docs/extending-the-cms-ui


1. Plug-in Areas

// CMS UI has the following plug-in areas:
// - Edit view toolbar
// - Context menu
// - Navigation panel gadgets
// - Admin menu
// - On-page editing toolbar

2. GuiPlugIn Attribute (Legacy)

// Register a component into the CMS UI (legacy approach)
[GuiPlugIn(
    Area = PlugInArea.AdminMenu,
    DisplayName = "My Tool",
    Url = "~/my-tool")]
public class MyAdminPlugin : PlugInDescriptor { }

3. Custom Admin Pages

// Create an admin page with routing
[Route("/episerver/mycompany/my-tool")]
[Authorize(Roles = "WebAdmins")]
public class MyAdminController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

4. IMenuProvider - Custom Menu Items

[ServiceConfiguration(typeof(IMenuProvider))]
public class CustomMenuProvider : IMenuProvider
{
    public IEnumerable<MenuItem> GetMenuItems()
    {
        yield return new UrlMenuItem(
            "My Custom Tool",
            MenuPaths.Global + "/cms/custom-tool",
            "/episerver/mycompany/custom-tool")
        {
            IsAvailable = request => 
                request.User.IsInRole("WebAdmins"),
            SortIndex = 200
        };
    }
}

5. Shell Module (Custom Application)

// Create a shell module — a standalone application within the CMS shell
// File: module.config
// <module>
//   <assemblies>
//     <add assembly="MyCompany.CmsModule" />
//   </assemblies>
//   <clientResources>
//     <add name="custom-editor" path="Scripts/custom-editor.js" resourceType="Script" />
//   </clientResources>
// </module>

6. ViewConfiguration - Edit Mode Views

[ServiceConfiguration(typeof(ViewConfiguration))]
public class MyCustomView : ViewConfiguration<IContent>
{
    public MyCustomView()
    {
        Key = "my-custom-view";
        Name = "My Custom View";
        Description = "Custom view for content";
        ControllerType = "my.customView.Main";
        IconClass = "epi-iconLayout";
        HideFromViewMenu = false;
    }
}

7. IContentContextMenu

// Add an item to the context menu in the content tree
[ServiceConfiguration(typeof(IContentContextMenu))]
public class CustomContextMenuProvider : IContentContextMenu
{
    public IEnumerable<IContentContextMenuCommand> GetCommands(
        IContent content, IContentRepository repository)
    {
        if (content is ArticlePage)
        {
            yield return new ContentContextMenuCommand
            {
                Text = "Custom Action",
                Command = "customAction",
                IconClass = "my-icon"
            };
        }
    }
}

8. Gadgets (Navigation Panel)

// Gadget in the left panel of the Edit View
[ServiceConfiguration(typeof(ComponentDefinition))]
public class MyGadgetDefinition : ComponentDefinition
{
    public MyGadgetDefinition()
    {
        ComponentType = typeof(MyGadgetController);
        Name = "My Gadget";
        PlugInAreas = new[] { PlugInArea.Navigation };
        Settings = new HashSet<Setting>
        {
            new Setting("numItems") { DefaultValue = "5" }
        };
    }
}

public class MyGadgetController : Controller
{
    public ActionResult Index(int numItems = 5)
    {
        // Gadget controller
        return PartialView(model);
    }
}

Review Questions

  1. What is IMenuProvider used for? (Adding custom menu items to CMS navigation)
  2. What role do custom admin pages typically require? (Usually WebAdmins)
  3. Where do gadgets appear in the Edit View? (Left navigation panel)
  4. What is ViewConfiguration used for? (Registering custom views for content editing)
  5. What is the module config file? (XML file declaring assemblies and resources for a CMS module)