May 27, 2007 - DotNetNuke    Comments Off on Blog: How to improve a DotNetNuke module

Blog: How to improve a DotNetNuke module

Published: 17 Jan 2007
By: Oleg Zhukov

This article explains how to make changes to DotNetNuke [url=http://dotnetslackers.com/articles/dotnetnuke/Improve_a_DotNetNuke_module.aspx#:3jq2q1d8]modules[/url:3jq2q1d8] varying their look-and-feel as well as adding some fundamental behavior.

[size=130:3jq2q1d8]Introduction [/size:3jq2q1d8]
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. To understand the article easily I recommend that you download the article [url=http://dotnetslackers.com/articles/dotnetnuke/Improve_a_DotNetNuke_module.aspx#:3jq2q1d8]code[/url:3jq2q1d8].

As a case in point, we will make minor modifications to the Blog module step by step But first let us clarify DotNetNuke’s basic structure.

[size=130:3jq2q1d8]DotNetNuke module structure [/size:3jq2q1d8]
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. The assemblies files can be found in Bin\ folder.
[img:3jq2q1d8]http://dotnetslackers.com/images/articleimages/DotNetNuke_1.gif[/img:3jq2q1d8]

Due to the need of an entire recompilation, modifying a module’s *.dll file 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.

[size=130:3jq2q1d8]Step 1: Removing needless parts [/size:3jq2q1d8]
Some information displayed in a module may be redundant and should better be hidden. For example the calendar in a [url=http://dotnetslackers.com/articles/dotnetnuke/Improve_a_DotNetNuke_module.aspx#:3jq2q1d8]blog[/url:3jq2q1d8] archive view is needless if posts aren’t made often. The below code will remove the calendar from the Blog archive.
[img:3jq2q1d8]http://dotnetslackers.com/images/articleimages/DotNetNuke_2.jpg[/img:3jq2q1d8]

Take a look at the contents of Archive.ascx file (in the DesktopModules\Blog folder). It describes how the archive view looks. Several lines in the beginning of the file contain definitions for unwanted items:
[code:3jq2q1d8]<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>[/code:3jq2q1d8]
However we cannot simply remove label and calendar controls since they are referred to in the underlying [url=http://dotnetslackers.com/articles/dotnetnuke/Improve_a_DotNetNuke_module.aspx#:3jq2q1d8]dll’s[/url:3jq2q1d8]. Instead we should set their visible attribute to false:
[code:3jq2q1d8]<asp:label visible="false" …>Archive</asp:label>
<asp:calendar visible="false" …></asp:calendar>
<asp:label visible="false" …>Monthly</asp:label>[/code:3jq2q1d8]
This will make a module contain only what is desired and nothing more.

[size=130:3jq2q1d8]Step 2: Rearranging existing controls [/size:3jq2q1d8]
Let us now draw attention to the [url=http://dotnetslackers.com/articles/dotnetnuke/Improve_a_DotNetNuke_module.aspx#:3jq2q1d8]search box[/url:3jq2q1d8] of the Blog module. Say we want the dropdown at the top to be hidden and the radio buttons to be arranged vertically.

[img:3jq2q1d8]http://dotnetslackers.com/images/articleimages/DotNetNuke_3.jpg[/img:3jq2q1d8]

Here we need to modify the Search.ascx file. Hiding the dropdown is the same as in Step 1. Arranging the radio buttons vertically is not harder we just set repeatdirection property of the radiobuttonlist control to Vertical

[code:3jq2q1d8]
<asp:radiobuttonlist id="optSearchType" … repeatdirection="Vertical" … />[/code:3jq2q1d8]

Please note that changes to the visual style of a module (e.g. fonts, colors, etc.) are made through module.css style sheet.

[size=130:3jq2q1d8]Step 3: Adding logic to a module [/size:3jq2q1d8]
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? We will add the total number of posts in a given month to the Blog Module. While I would highly recommend that you do this through the code files, we’ll actually do it via the ascx control.
For example let us make blog archive show the number of posts for each month.

[img:3jq2q1d8]http://dotnetslackers.com/images/articleimages/DotNetNuke_4.jpg[/img:3jq2q1d8]

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 Storedprocedure which will return the desired count.

A stored procedure can be created by the means of the DotNetNuke SQL tool. Open it with Host > SQL menu item. Then paste the Storedprocedure creation query, select Run as Script and click Execute.
[img:3jq2q1d8]http://dotnetslackers.com/images/articleimages/DotNetNuke_5.jpg[/img:3jq2q1d8]

The storedprocedure to retrieve the number of posts for a specific month can be downloaded with the sources for the example.

Creating the storedprocedure is not the only thing we need do. In order to execute it we need to provide the 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 [url=http://dotnetslackers.com/articles/dotnetnuke/Improve_a_DotNetNuke_module.aspx#:3jq2q1d8]server[/url:3jq2q1d8] scripts with additional logic into *.ascx controls. Here is how it would look for our example:
[code:3jq2q1d8]
<%@ Import Namespace="DotNetNuke.Modules.Blog.Data" %>
<%@ Import Namespace="DotNetNuke.Modules.Blog.Business" %>
<%@ 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 Blog.Data.SqlDataProvider =
CType( Blog.Data.DataProvider.Instance(), Blog.Data.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))%>)
</asp:hyperlink>[/code:3jq2q1d8]

The storedprocedure used is Blog_GetEntriesCountForMonth and it is called with the SqlHelper.ExecuteReader static method. Here we use standard ASP.NET notation <%#expression%> to embed calculated values into the markup.

[size=130:3jq2q1d8]Conclusion [/size:3jq2q1d8]
DotNetNuke is an [url=http://dotnetslackers.com/articles/dotnetnuke/Improve_a_DotNetNuke_module.aspx#:3jq2q1d8]open-source[/url:3jq2q1d8] framework making it possible to modify the behavior of all of its parts including native and new modules. Throughout this 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 the 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.

Download
The example improvements to the Blog module can be found in the [url=http://www.olegzhukov.com/content/Downloads/tabid/73/Default.aspx:3jq2q1d8]downloads section[/url:3jq2q1d8] of my website. Or just click [url=http://www.olegzhukov.com/content/LinkClick.aspx?fileticket=s1qehJCovgo%3d&tabid=73&mid=402:3jq2q1d8]here[/url:3jq2q1d8] for direct access.