Introduction
On one recent project the requirements were to have a rotating image placed
in the site, but the project required that the image didn't show up on the home
page. Granted DNN allows you to place a module in a page and then have that
module show up on every page, but what about exclusions? You could code the
module so it excluded the home page based on URL, but this seemed to more of a
kludge. Another thing you could do is to place the module individually on each
page you wanted to show up on, but on a site consisting of hundreds of pages
this didn't seem practical.
Enter the skin object, since in this specific project there were two skins
making up the site; one for the image (where the rotating image wasn't wanted),
and another skin for the sub pages, it made sense then to create a skin object
and place it into the skin for the subpages. This would fulfill the requirement
of having a rotating image on all pages except the home page.
In this article we'll discuss how easy it is to code your own skin object and
then use it.
Set Up the Project
We're not going to go into depth on setting up your Visual Studio project,
basically it's the same as any DNN project. I prefer to just set up a class
project and reference the DotNetNuke.dll in my project. This way I don't need to
load the DotNetNuke project, or the Build project. You're free to code the
object as you wish. In this example, I'm keeping it simple and using the
DotNetNuke namespace, in practice however you may want to use a custom namespace
and compile your DLL into some logical naming scheme.
Create an ASCX File for the Skin Object
In this example, I created an ascx page and called it ImageRotator.ascx, the
project is going to consist of this one file, and an XML file that will hold our
image definitions. The rotator object is going to be able to be placed into a
page multiple times and use different XML image definitions for each instance.
The ascx file is very simple an only contains an image control on the page:
<%@ Control Language="vb" AutoEventWireup="false"
Inherits="DotNetNuke.ImageRotator" CodeBehind="ImageRotator.ascx.vb" %>
<P><asp:Image id="imgMain" runat="server"></asp:Image></P
In
the code behind for the skin object we'll import a few namespaces for us to use:
Imports System.Web
Imports System.Xml
Imports System.Xml.XPath
Imports DotNetNuke
Then we'll inherit the DotNetNuke.UI.Skins.SkinObjectBase and declare our
object, and variables:
Public MustInherit Class ImageRotator
Inherits
DotNetNuke.UI.Skins.SkinObjectBase
Protected WithEvents imgMain As
System.Web.UI.WebControls.Image
Private mXMLFile As String = "default.xml"
A public property will be created to allow the object to accept an XML
document in case we want to display different images in the specific instance of
this control:
Public Property XMLFile() As String
Get
Return
mXMLFile
End Get
Set(ByVal Value As String)
mXMLFile =
Value
End Set
End Property
In
the main page onload event we're going to call our main method:
Private Sub Page_Load(ByVal sender As
System.Object, ByVal e _
As System.EventArgs) Handles MyBase.Load
Try
GetImageInfo()
Catch exc As Exception 'Module failed to load
DotNetNuke.Services.Exceptions.ProcessModuleLoadException(Me, exc)
End Try
End Sub
Then in the GetImageInfo method we do our reading of the XML file and pull a
random image from the file for display:
Private Sub GetImageInfo()
Dim xpathDoc As XPathDocument
Dim xmlNav As XPathNavigator
Dim xmlNI As XPathNodeIterator
xpathDoc = New
XPathDocument(Server.MapPath(DotNetNuke.Common.ApplicationPath) & _
"\SkinObjects\RotatingImage\" &
mXMLFile)
xmlNav = xpathDoc.CreateNavigator()
xmlNI = xmlNav.Select("/images/image")
Dim rndNode As Integer = RandomNumber(xmlNI.Count(), 0)
Dim xCnt As Integer = 0
While (xmlNI.MoveNext())
If xCnt = rndNode Then
imgMain.ImageUrl = xmlNI.Current.GetAttribute("src", "")
imgMain.AlternateText = xmlNI.Current.GetAttribute("alt", "")
End If
xCnt = xCnt + 1
End While
End Sub
The following function will provide a random number for our module to display
anyone of the elements within the XML file:
Private Function RandomNumber(ByVal MaxNumber
As Integer, _
Optional ByVal MinNumber As Integer = 0) As Integer
'initialize random number generator
Dim r As New Random(System.DateTime.Now.Millisecond)
'if passed incorrect arguments, swap them
'can also throw exception or return 0
If MinNumber > MaxNumber Then
Dim t As Integer = MinNumber
MinNumber = MaxNumber
MaxNumber = t
End If
Return r.Next(MinNumber, MaxNumber)
End Function
The XML Definition File
Now let's look at the XML file format that we're using to define our images
for the module. As you can see it is fairly simple:
<?xml version="1.0" encoding="utf-8" ?>
<images>
<image src="image1.gif" alt="First Image"></image>
<image src="image2.gif" alt="Second Image"></image>
<image src="image3.gif" alt="Third Image"></image>
</images>
Insert the Object Into Your Skin
Now that the code is done, all we need to do is compile, and place a
reference into our skin. At the top of the skin you place the following:
<%@ Register TagPrefix="lrd" TagName="ROTIMAGE"
Src="~/SkinObjects/RotatingImage/ImageRotator.ascx" %>
In the example above we placed our skin object development in a folder off of
the root of our DNN installation called "SkinObjects".
Then within the skin you place a directive to where you want the image to be:
<lrd:ROTIMAGE runat="server" id="lrdROTIMAGE"
XMLFile="default.xml" />
If you want to place multiple images with different image series you can do so,
just define an XML file with the images to rotate and give it a new id:
<lrd:ROTIMAGE runat="server"
id="lrdROTIMAGE2" XMLFile="anotherfile.xml" />
That's all there is to it.