Wednesday, September 16, 2009

Writing smart DotNetNuke Schedulers that sends email

This post is for those who are using dotnetnuke scheduler for rapidly sending emails to the users. There are times when scheduler fails to complete the job and try running the job again base on retry setting applied to it. Bad news is that, the user who are expecting the email once receives the email twice. If you set retry frequency to an hour or so, and your code meets some bad data like null reference of so, users will get the email every hour.

This description at least clears the thing that we should at least not set retry frequency while sending emails through scheduler. Next thing comes to mind is, there should be a batter way to do it. I personally work on it and think about some way that adds some overhead to the scheduler activity but makes sure that no user will get the same email more than once.

Create a table called tracker that stores following things:
Id - Auto increment
Email - Email sent
Type - default 0, increment it in case if you are using more than one scheduler for sending emails
Date - Small date time that stores date and time the email sent to this user.

The next step is to modify your query to return email that are not in this table. For Example:

Select userid, email
from users u
where email not in (select email from tracker where = and convert(varchar(10),date,112) = convert(varchar(10),getdate(),112))

(Please be careful while comparing dates and times in t-sql. If you are using small date time to compare two dates, equality is base on date and time both.)

I think using this trick will never send email to the same user again.
Have fun with your development.

Thursday, September 10, 2009

DotNetNuke: Creating a new parent portal in localhost

As we all know, dotnetnuke provides a to build a multiportal environment using a single dotnetnuke installation and I was doing that exercise in order to get that running in localhost.

So let's start building a new parent portal in local environment:
  1. Login to host and go to Host > Portals
  2. Click Create New Portal
  3. Enter portalName Parent1 and username parent1admin, and add all other required data.
  4. go ahead an create new portal.
Creating a new portal in local environment will create a new portal Portal1. Now you need to do following after completing above 4 steps.
  1. Create a new virtual directory Parent1 and point it to dnn installation that you are using to create this portal
  2. Go to Host > Sql and execute this query :
    UPDATE PortalAlias
    Set HTTPAlias = 'localhost/Parent1'
    Where HTTPAlias='Parent1' or HTTPAlias='parent1'
  3. Try accessing localhost/parent1
We are done with installing a new parent portal.
Hope you enjoyed this trick.

Wednesday, September 9, 2009

Extending Skin class in DotNetNuke

Are you developing a new skin in DotNetNuke and need additional properties in Skin class? Let's look into how skinning works.

if you look at the top of the every skin, you will find following

<%@ Control Language="vb" Codebehind="~/admin/Skins/skin.vb" AutoEventWireup="false"
Explicit="True" Inherits="DotNetNuke.UI.Skins.Skin" %>

Please see the strong part of the above code. You will find that every skin that we develop in dnn is inherited from DotNetNuke.UI.Skins.Skin.

Ok so now is the time to introduce a new property to the class. Just create a new class like following:

public class MySkinBase : DotNetNuke.uI.Skins.Skin
private string _newOne;
public string NewOnw
get { return _newOne;}
set { _newOne = value; }

All you should do next is to use this class in place of DotNetNuke.UI.Skins.Skin in developing your skin like following.

<%@ Control Language="vb" Codebehind="~/admin/Skins/skin.vb" AutoEventWireup="false"
Explicit="True" Inherits="MySkinBase" %>

And you will now get a property NewOne into your skin object development. Enjoy!

What about user Types?

Every time you start developing new solution using DotNetNuke, you probably have a question about user types. If you are creating a job site, you will probably have user types like job seeker, employer etc. Is there any way to set multiple registration and login pages for a portal?

Well, This is tricky. As there is no direct way to multiple login page and registration page. So, I generally use query string parameter to determine the registration type. Once we know which is the right registration control to render (Employer signup or Job Seeker Signup), In addition to writing signup code, I add roles to the created user.

Once you register an employee with Role "Employee" and a job seeker with role "Job Seeker" it will be easier to modify login control and place a role check for logged in user and you can correctly redirect the user to its home without having separate login pages.

Does it make sense to you? Do you have another Idea? please tell me!

Tuesday, September 8, 2009

DotNetNuke - Access pages without tabId

I'm not sure which version of DotNetNuke included this magic, but if you create a page with tab name Sample Page, then you can simply access that page with portalAlias/SamplePage.aspx.

When I see this thing first time, I was impressed, and tried some more tab names with this. Next is to create a child tab of Sample Page called Child Page and tried and it doesn't work. I scratched my head for some time and tried /SamplePage/ChildPage.aspx and it worked.

I'm using dnn 5.x and it works nicely for almost all the pages.

Then I tried some more magic tabs and I come to know that there are some pages in dnn that are always available to all the portals and child portals regardless of they are created or not. For example, If you type portalAlias/login.aspx it will show a login window. If you try portalAlias/LogOff.aspx it will immediately logoff you!

It's nice to know this thing, because it will be useful when you are developing a new skin. If you forget to place login skin object and want to login or logoff, its easier to do that with this.

I assume this is a magic from dnn friendly url provider. I've come to know about this just before some time and thought it may be helpful to you also!

Sunday, September 6, 2009

DotNetNuke path helper methods

1. ModulePath
Useful in – Module Development
Member of – PortalModuleBase Class

Bad Practice:
<asp:image id="img" runat="server" imageurl="/DesktopModules/ModuleName/Images/ImageName.gif"/>
<img src="/DesktopModules/ModuleName/Images/ImageName.gif%E2%80%9D" alt="Alt" />

Good Practice:
<asp:image id="img" runat="server" ImageUrl="<%= ModulePath %>Images/ImageName.gif"/>
<img src="<%= ModulePath %>Images/ImageName.gif" alt="Alt Text"/>

Please note:
a. ModulePath will correctly resolve the path to module image regardless of in whatever the tab you are using.
b. If module name is changed, it will still remain correct.
c. This is also useful when you are linking a javascript file or adding additional css reference.

2. SkinPath
Userfull in – Skin Development
Member of – Skin Class

Similar to ModulePath, SkinPath variable will help you resolve the path to your skin folder. You can use it in similar way as ModulePath.

3. Getting SkinPath in Module Development
PortalSettings.ActiveTab.SkinSrc will return an full path to your ascx control in skin folder. You can simply use System.IO.Directory.GetParent().Name get folder name.

4. Getting Domain name anywhere in your development cycle

There many in the list, but that's it for now. Happy coding:)