How to improve a DotNetNuke module
Abstract: This article explains how to make changes to DotNetNuke modules varying their look-and-feel as well as adding some fundamental behavior.
Introduction
DotNetNuke module structure
Step 1: removing needless parts
Step 2: rearranging existing controls
Step 3: adding logic to a module
Conclusion
Download
DotNetNuke is shipped with a number of feature-rich modules suitable for various tasks. However a necessity to modify a module’s behavior may arise. This article covers how to easily modify DNN modules and extend their behavior.
As a case in point, we will modify Blog module making it better step by step. But firstly let us clarify the basics of a DotNetNuke module’s structure.
In DNN 4.x a module is usually comprised of front-end controls (in *.ascx files) and module’s logic (*.dll assemblies). A module’s front-end is located under DesktopModules\<Module_Name>\ folder. Module’s assemblies can be found in Bin\ folder.

Due to the need of entire recompilation modifying module’s *.dll files is a complicated task. So we will insert all additional behavior into *.ascx files and will deal with them through the rest of the article.
Some information displayed in a module may be redundant and should better be hidden. For example the calendar in a blog archive view is needless if posts aren’t made often. Let us show how to remove the calendar from the Blog archive.

Take a look at the contents of Archive.ascx file (under DesktopModules\Blog folder). It describes how the archive view looks. Several lines in the beginning of the file contain definitions for unwanted items:
<tr>
<td>
<asp:label id="lblArchive" …>Archive</asp:label>
</td>
</tr>
<tr>
<td>
<asp:calendar id="calMonth" …></asp:calendar>
</td>
</tr>
<tr>
<td>
<asp:label id="lblMonthly" …>Monthly</asp:label>
</td>
</tr>
However we cannot simply remove label and calendar controls since they are referred to in the underlying dll’s. Instead we should attribute them as invisible:
<asp:label visible="false" id="lblArchive" …>Archive</asp:label>
<asp:calendar visible="false" id="calMonth" …></asp:calendar>
<asp:label visible="false" id="lblMonthly" …>Monthly</asp:label>
This will make a module contain only what is desired and nothing more.
Let us now draw attention to the search box of the Blog module. Say we want combo box at the top to be hidden and radio buttons to be arranged vertically.

Here we need to modify Search.ascx file. The former task is done as in Step 1. The latter one is no harder – we just set repeatdirection="Vertical" on <asp:radiobuttonlist> control.
<asp:radiobuttonlist id="optSearchType" … repeatdirection="Vertical" …
Note that changes to the visual style of a module (e.g. fonts, colors, etc.) are made through module.css style sheet.
So far we have dealt only with visual modifications to modules. But what if it’s necessary to add some new functionality to a module? It can be fulfilled the same way – via modifying module’s front-end *.ascx files.
For example let us make blog archive show the number of posts for each month.

In order to get the number of posts made in a particular month a SQL query should be executed. Since inline querying is forbidden in DotNetNuke we need to create an appropriate stored procedure which will return the desired number.
A stored procedure can be created by the means of DotNetNuke SQL tool. Open it with Host > SQL menu item. Then paste there the stored procedure creation query, select “Run as Script” and click “Execute”.

The stored procedure to retrieve the number of posts in a month can be downloaded with the sources for the example.
Such stored procedure is not the only thing to do. In order to execute it we need to provide a proper connection settings and procedure parameters. Connection settings can be retrieved by static methods of the corresponding DataProvider subclass. Other parameters depend on the specific case, for example portal ID can be obtained via “PortalId” property of a module’s front-end control.
Anyway we will need to embed server scripts with additional logic into *.ascx controls. Here is how it would look for our example:
<%@ Import Namespace="Microsoft.ApplicationBlocks.Data" %>
<script runat="server">
Function GetEntryCount(ByVal Month As DateTime) As Integer
Dim BlogID As Integer = -1
If Not Request.Params("BlogID") Is Nothing Then
BlogID = CType(Request.Params("BlogID"), Integer)
End If
Dim sqlDataProvider As SqlDataProvider = CType(
DataProvider.Instance(), SqlDataProvider)
Dim connectStr As String = sqlDataProvider.ConnectionString
Dim dbo As String = sqlDataProvider.DatabaseOwner
Dim oq As String = sqlDataProvider.ObjectQualifier
Dim dr As IDataReader = CType(SqlHelper.ExecuteReader(connectStr, dbo & oq &
"Blog_GetEntriesCountForMonth", Me.PortalId, BlogID, Month), IDataReader)
dr.Read()
Dim Result As Integer = dr.GetInt32(0)
dr.Close()
Return Result
End Function
</script>
…
…<asp:hyperlink … /> (<%#GetEntryCount(CType(Eval("AddedDate"), DateTime))%>)
The stored procedure used is "Blog_GetEntriesCountForMonth" and it is called with SqlHelper.ExecuteReader static method. Here we use standard ASP.NET notation <%#expression%> to embed calculated values into the markup.
DotNetNuke is an open-source framework and this makes possible to modify the behavior of all of its parts including native modules. Through the article we have addressed questions of making changes to modules by modifying their *.ascx front-end files. Such changes do not require recompilation of underlying dll’s though they may contradict standard DotNetNuke programming model. Anyway if a minor change to a module should be made then modifying module’s *.ascx files is the easiest way to.
The example improvements to the Blog module can be found in the downloads section of my website. Or just click here for fast access.
|