Extending DNN UI for Custom Settings

extending dnn ui for customer settings

Extending DNN UI for Custom Settings

DNNCorp_logo_lrgOne of the great new features in DNN 7.0 is the ability to inject a module’s user control into specific places within the DNN administration sections. This allows you to extend areas of DNN that were previously unreachable or required custom changes to the core.

These areas currently include:

  • Page Scripts – Javascript injected on all pages
  • Page Settings  – Advanced Settings Sections
  • File Manager
    • Toolbar
    • Context Menu
    • Grid Columns
    • Folder Properties
  • Module Context Menu Items
  • Host Settings & Site Settings

Interestingly, Evoq Content (aka DotNetNuke Professional) uses these endpoints. This is in order to integrate the additional professional feature set into the community platform without any core modifications. But the potential is so much larger.

ModuleInjection-1 ModuleInjection-2

How does it work?

This system works by utilizing  the .NET Managed Extensibility Framework (System.ComponentModel.Composition) export/import model. This system works as a type of a dependency injection framework where an object decorated as [Import] will be populated with any other object that matches it’s type and is decorated with [Export]

First the [Import] in the core is implemented as a ImportMany in the ExtensionPointManager.cs class. Which just means it’ll populate it with an enumeration not a single instance.

[code lang=”csharp”]
private IEnumerable<Lazy<IEditPagePanelExtensionPoint, IExtensionPointData>> _editPagePanelExtensionPoints;

The Lazy generic as a side note for those not aware is just a delayed initialization of the variable until it is used. Handy for speeding up application and class loading. After that it is simply filling the _editPagePanelExtensionPoints variable with all the classes it can find with Exports that match the IEditPagePanelExtensionPoint interface.

Now lets take a look at that [Export]

[code lang=”csharp”]
[ExportMetadata("Module", "SiteSettings")]
[ExportMetadata("Name", "CacheSettingsExtensionPoint")]
[ExportMetadata("Group", "CacheSettings")]
[ExportMetadata("Priority", 1)]
public class CacheSettingsExtensionPoint : IEditPagePanelExtensionPoint {}

First you’ll notice the main export that matches the type in the previous section but then WHOA!!!!! How do I know what all those string values are suppose to be? Unfortunately this will require a bit of searching of DNN core to find the available values but if you implement your own it would be in the form of a user control with properties set that match the above exports.

[code lang=”csharp”]
<%@ Register TagPrefix="dnnext" Namespace="DotNetNuke.ExtensionPoints" Assembly="DotNetNuke" %>
<dnnext:EditPagePanelExtensionControl runat="server" ID="CacheSettingsExtensionControl" Module="SiteSettings" Group="CacheSettings"></dnnext:EditPagePanelExtensionControl>

There is a user control for each type of insertion point listed at the top of this post.

The Future If Fully Implemented

Currently this implementation is in it’s early stages as it’s mostly used for extending the file manager and url management integrations. However if this pattern is extended into more/all areas of the DNN platform you could see module developers being able to hook into anything anywhere without modifying the core.

When this pattern is embraced by the community we will see module developers allowing feature extensions into their products by other developers. This will be an amazing evolution in the DNN ecosystem as you could see developers focusing on specific features instead of reinventing the wheel with new implementations of common features.

Take for example the feature of ratings. Every module developer has created their own implementation of rating a blog post, image, or article. What if ratings were completely separated from the blog module? The blog module could focus on what it does well, blogging. The ratings feature could then be injected into the blog module wherever it was needed and that same ratings feature could also be injected into the image gallery module. Maybe you don’t like that initial ratings feature? Download a new one and replace it, in turn automatically replacing it in all modules.

Antonio Chagoury

Hi, I'm Antonio, Founder and CEO of Maxiom Technology (formerly Inspector IT).I'm a technology executive and entrepreneur who has achieved consistent success in driving growth, generating revenue, and enhancing value in domestic and international markets through technology product innovations.

1 Comment
  • Oem
    Posted at 4:39 pm, December 5, 2013


    I saw that you are using AngularJS. I myself want to use this framework in a DNN project. Do you have examples for me? How to use the custom headers [beforeSend: sf.setModuleHeaders]? Hope you blog on these issues or send me some examples.