First time at my blog? Check out the table of contents! x
posted on Tuesday, November 20, 2007 6:27 PM | Filed Under [ DotNetNuke ]

Welcome Back! Last time I showed you how you can programmatically create pages from your module: Programmatically Creating DotNetNuke Pages. Today I want to show you how to programmatically add and remove module instances to and from pages in your DotNetNuke site.

The DotNetNuke.Entities.Modules Namespace

The DotNetNuke.Entities.Modules namespace brings to the party all the needed functionality required for adding and removing module instances to and from pages. When you explore this namespace you are going to find a whole lot more than you bargained for. For instance the DesktopModuleInfo, DesktopModuleController, and ModuleDefinitionInfo classes are all living in this namespace. Many of these classes are what DotNetNuke uses to represent and manage all the types of modules that are installed in your site.

The classes we are interested in today are the ModuleInfo and ModuleController classes. These two classes represent and manage instances of the module definitions.

DotNetNuke.Entities.Modules.ModuleInfo

The ModuleInfo class represents an instance of a module in DotNetNuke. You might recall that one module “instance” can exist on multiple pages, however these “instances” that live on multiple pages do not correspond one-to-one with unique instances of the ModuleInfo class. In the database there is a Modules table and a TabModules table. For every “instance” of a module on your site, there is an entry in the Modules table. For every page that a particular “instance” exists on, there is an entry in the TabModules table. Generally speaking, a ModuleInfo instance is associated with a particular TabModules table entry, meaning its key in the database consists of a combination of both the ModuleId and the TabId.

The information inside a ModuleInfo object actually contains a complex amalgamate of information that I don’t really care to explain in detail at this point. Suffice it to say that DotNetNuke pulls all the required information into the object for you using the vw_Modules view:

image

How fun is that!? One could probably write a small book about this relationship alone! I’m just not up for it today.

So anyway, there is no need to be intimidated by this view because the DotNetNuke Framework does all the heavy-lifting for you through the next class we are going to talk about.

DotNetNuke.Entities.Modules.ModuleController

The ModuleController class is basically a gift from the DotNetNuke Gods. This class will add, copy, delete, retrieve, and update module instances for you in no less than 10,000 ways. (Don’t hold me to that, I barely received a B in my 400-level stats course)

image

The ModuleController class’ methods are listed above. One of these methods will likely do what you need.

Adding a New Module Instance

The basic method for programmatically creating a new module instance in your site is as follows:

1. First create an instance of the ModuleController class

2. Then create an instance of the ModuleInfo class

3. Populate the properties of the ModuleInfo instance

4. Pass the ModuleInfo instance to the AddModule() method of the ModuleController object

This looks simple, but don’t fool yourself. Step 3, populating the properties, can be a lot of work! The best starting point for figuring out how to populate these properties is to dig into the DotNetNuke source code to take a look at the ControlPanelBase.vb file. The ControlPanelBase class has a protected method named AddNewModule() that goes through the painful work of populating all the properties of a ModuleInfo class. This is a ton of code, so I won’t be posting it here. You can download the source from here.

After you have the ModuleInfo object populated with information, you simply pass the object to the AddModule() method of the controller object.

Public Function AddModule(ByVal objModule As ModuleInfo) As Integer

AddModule() takes a ModuleInfo object that represents your new module instance, and it returns the id of the new module in the database.

Copying a Module Instance

Sometimes you want a modules instance to live on several different pages. In order to achieve this effect you must first acquire the id of the module that you wish to have on several pages. You must also build an ArrayList of TabInfo objects that represent each of the pages that you wish to have your module exist on. Once you have this information ready you call the CopyModule() method of the ModuleController class to copy the module to all the pages you specified in the ArrayList you created.

ModuleController.CopyModule() has the following signature:

Public Sub CopyModule(ByVal moduleId As Integer, _

   ByVal fromTabId As Integer, _

   ByVal toTabs As ArrayList, _

   ByVal includeSettings As Boolean)

The first parameter, moduleId, is the id of the module you want to copy to other pages. The second parameter, fromTabId, is the id of the page that the module currently lives on. The third parameter, toTabs, is an ArrayList of TabInfo objects that represent the different pages that you want to copy the module to. You can build your own list, or you can use the Globals.GetPortalTabs() method (from the DotNetNuke.Common namespace) to get a list of all the pages in your portal.

ArrayList allModulesAL =

   Globals.GetPortalTabs();

Finally, the last parameter to CopyModule() is a Boolean that specifies whether or not the settings associated with the module/page combination should be copied to the new module/page combination.

In this example, the current module gets copied to every page in the current portal:

// GET CURRENT MODULE'S DATA

ModuleController modController = new ModuleController();

ModuleInfo mod = modController.GetModule(ModuleId, TabId);

 

// MANUALLY ADD MODULE TO ALL TABS

ArrayList allTabsList =

   Globals.GetPortalTabs(

   PortalSettings.DesktopTabs, false, true);

modController.CopyModule(ModuleId,

   TabId, allTabsList, true);

Removing Modules from a Page

There are several different ways to delete modules using the ModuleController class. The method you use will depend on the behavior that you need.

The first method you might find in the ModuleController class is the DeleteModule() method. This method is not usually useful to the module developer. When you call this alone, it will delete the module info from the Modules table in the database. This is problematic because it could leave orphaned data that still is associated with the deleted module. Before you decide to use this method you should do some research and find out what steps you need to take to prevent this scenario.

A more useful method is the DeleteTabModule() method:

Public Sub DeleteTabModule(ByVal TabId As Integer,_

   ByVal ModuleId As Integer)

This method removes one module from one page. The TabId parameter is the id of the page you wish to remove the module from. The ModuleId parameter is the id of the module that you wish to remove from the page that you specified in the first parameter. The following example removes the current module from the current page:

ModuleController modController = new ModuleController();

modController.DeleteTabModule(TabId, ModuleId);

The final method for removing module instances is what I believe to be the most useful. The DeleteAllModules() method of the ModuleController class removes module instances from any number of pages. This method is very similar to the CopyModule() method in that it takes an ArrayList of TabInfo objects. The TabInfo objects in this ArrayList represent the pages that you need to remove the module from.

Public Sub DeleteAllModules(ByVal moduleId As Integer, _

   ByVal tabId As Integer, ByVal fromTabs As ArrayList, _

   ByVal includeCurrent As Boolean, _

   ByVal deleteBaseModule As Boolean)

The moduleId parameter is the id of the module you need to remove from the pages. The tabId parameter is the id of a page that the module exists on. Typically you would pass the id of the current page being rendered, if one exists. The fromTabs parameter is the ArrayList mentioned above. It contains TabInfo objects that represent all the pages that you wish to remove the module from. The third parameter, includeCurrent, is a Boolean value that specifies whether or not to remove the module from the page that you specified via the tabId parameter. If you set this parameter to false the module will be removed from all the pages listed in the fromTabs ArrayList, except for pages that have an id matching the second parameter of this method, tabId. Finally, the deleteBaseModule parameter is a Boolean value that specifies whether or not to delete the actual module record from the Modules table. Passing true here will call the DeleteModule() method that we talked about above.

Here is an example of how you can remove the current module from every page in the current portal, except the current page:

// GET CURRENT MODULE'S DATA

ModuleController modController = new ModuleController();

modController.DeleteTabModule(TabId, ModuleId);

 

// MANUALLY REMOVE MODULE FROM TABS

ArrayList allTabsList =

   Globals.GetPortalTabs(

        PortalSettings.DesktopTabs, false, true);

modController.DeleteAllModules(

   ModuleId, TabId, allTabsList, false, false);

Finally, I will leave you with a useful block of code. The ToggleAllTabs() method accepts a ModuleId, a PortalId, and a TabId. It first retrieves a ModuleInfo object for the current page+module combination. It then toggles the AllTabs property of the module. Depending on the state of AllTabs, the module is either added to all the tabs in the portal, or it is removed from all the tabs in the portal except for the current tab.

public void ToggleAllTabs(int ModuleId,

   int PortalId, int TabId)

{

   // GET CURRENT MODULE'S DATA

   ModuleController modController =

        new ModuleController();

   ModuleInfo mod =

        modController.GetModule(ModuleId, TabId);

 

   // TOGGLE AllTabs VALUE AND UPDATE

   mod.AllTabs = !mod.AllTabs;

   modController.UpdateModule(mod);

 

   if (mod.AllTabs)

   {

        // MANUALLY REMOVE MODULE FROM TABS

        ArrayList allTabsList =

            Globals.GetPortalTabs(

            PortalSettings.DesktopTabs, false, true);

        modController.DeleteAllModules(

            ModuleId, TabId, allTabsList, false, false);

   }

   else

   {

        // MANUALLY ADD MODULE TO ALL TABS

        ArrayList allTabsList =

            Globals.GetPortalTabs(

            PortalSettings.DesktopTabs, false, true);

        modController.CopyModule(

            ModuleId, TabId, allTabsList, true);

   }           

}

To Summarize

  1. Use the DotNetNuke.Entities.Modules namespace to access classes that will assist you in adding, removing, and all-around managing of modules.
  2. The ModuleInfo class houses all the information about a particular  module on a particular page.
  3. The ModuleController contains all the functionality you need to add, copy, update, and delete modules.
  4. You can create new instances of a module by calling the AddModule() method on an instance of the ModuleController class.
  5. You can copy an existing module instance to other pages by calling the CopyModule() method on an instance of the ModuleController class.
  6. You can remove one module from one page by calling the DeleteTabModule() method on an instance of the ModuleController class.
  7. You can remove one module from any number of pages by calling the DeleteAllModules() method on an instance of the ModuleController class.
Comments Leave Yours...
Ed DeGagne
11/30/2007 3:32 PM
# re: How to Programmatically Add and Remove Modules From DotNetNuke Pages

Rafe,

Excellent article. The DotNetNuke.Entities.Modules namespace can be quite daunting for the faint hearted. :-)

baldwin
6/6/2008 4:45 PM
# re: How to Programmatically Add and Remove Modules From DotNetNuke Pages

As you know, we can set the module permission to determine which role can view the module. but can we deal with the situation below:

Totally hidden the module in the related page, but the module had not been deleted( related record existed in the database,also). In the other word, I just do not want to load the module in the page since I had configured its visibility(maybe exist some property) as false. In the end, I also need had the capability to make the true and show the module in the same page.

Dexter
1/29/2009 1:14 AM
# how to retrive data on next tabID based upon button click in previous page.

look i am creating a website in which i am stuck-up at a place. there are 7-8 pics and text data related to it. On the selection of a pic i have to navigate to detaisl page where datahas to be fetched from database based upon the selection of pic on previous TabID. the no of pages has to be only two. One for just displaying pics and small text information and in the next page. full detail has to come up.

can u help.

Nick2k
2/18/2009 6:37 AM
# re: How to Programmatically Add and Remove Modules From DotNetNuke Pages

Thanks from this article...

Simplykid
3/12/2009 9:17 PM
# re: How to Programmatically Add and Remove Modules From DotNetNuke Pages

This article is interesting.
But how can i load/display the module?
In my case i want to make a print friendly module that load/display module from other page with given TabID.

Can you tell me how to do it, Kemmis? or is there anyone could help me?

Thanks in advance.

Mark
6/10/2009 12:35 PM
# re: How to Programmatically Add and Remove Modules From DotNetNuke Pages

Once again, thanks for your tutorial especially because this is the only one on this subject I could find.

I have a problem though and I am wondering if anyone else has seen this. I am using the AddNewModule method from ControlPanelBase.vb to create a new module. For example:
modInfo = modCtr.GetModuleByDefinition(PortalSettings.PortalId, "Text/HTML")
AddNewModule(objTab, sTitle, modInfo.DesktopModuleID, "ContentPane", 0, ViewPermissionType.View, "Left")

The module gets added to the page beautifully and I can edit it. However when I click "Settings" on the new module I get an exception (below). I have tested on "Text/HTML" and "effority.WF_HTML" and I get the same result. Looking at the DB using SQLProfiler I can't seem to find what is missing, but something must be missing in the DB, obviously related to settings.

Error: Module is currently unavailable.
DotNetNuke.Services.Exceptions.ModuleLoadException: Object reference not set to an instance of an object. ---> System.NullReferenceException: Object reference not set to an instance of an object. at DotNetNuke.Modules.Admin.Modules.ModuleSettingsPage.BindData() in D:\Websolutions\Vanguard2.0\dnnmoduledev\Admin\Modules\ModuleSettings.ascx.vb:line 144 at DotNetNuke.Modules.Admin.Modules.ModuleSettingsPage.Page_Load(Object sender, EventArgs e) in D:\Websolutions\Vanguard2.0\dnnmoduledev\Admin\Modules\ModuleSettings.ascx.vb:line 223 --- End of inner exception stack trace ---

I am using 4.9.3.

Post Your Comment

Title
Required
Name
Required
Email
Optional
Url
Optional
Comment  
Please add 8 and 2 and type the answer here:

Who Is Rafe

rafe

Rafe Kemmis

I am an audacious web developer with a double bachelor of science in Computer Science and Mathematics. I specialize in Microsoft ASP.Net, Silverlight, and Adobe ActionScript.

Questions?

Always a thoughtful response. You may post your question on an article, or contact me directly.

Hire Me.

I provide custom solutions to complex problems. I can help your business no matter how large or small.

Contact me now.

Subscribe