Exam Area: Area 4 – Framework Components (15%)
Reference: https://docs.developers.optimizely.com/content-management-system/docs/extending-the-cms-ui
// CMS UI has the following plug-in areas:
// - Edit view toolbar
// - Context menu
// - Navigation panel gadgets
// - Admin menu
// - On-page editing toolbar
// Register a component into the CMS UI (legacy approach)
[GuiPlugIn(
Area = PlugInArea.AdminMenu,
DisplayName = "My Tool",
Url = "~/my-tool")]
public class MyAdminPlugin : PlugInDescriptor { }
// Create an admin page with routing
[Route("/episerver/mycompany/my-tool")]
[Authorize(Roles = "WebAdmins")]
public class MyAdminController : Controller
{
public IActionResult Index()
{
return View();
}
}
[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
};
}
}
// 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>
[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;
}
}
// 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"
};
}
}
}
// 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);
}
}
IMenuProvider used for? (Adding custom menu items to CMS navigation)WebAdmins)ViewConfiguration used for? (Registering custom views for content editing)