Wednesday, July 15, 2009

DotNetNuke - Implementing Multi-color skins

Introduction:
Here I’m going to present an approach to create a DotNetNuke skin which has multiple colors using a single ascx skin control and multiple css files.
  • Allow user to choose the color
  • When user selects the color, post an ajax request to server to store the setting in database and send response
  • read the response using javascript and change the css file.
    When user comes to the portal again, load right css from server side by reading database settings for the portal.
  • implement authorization so that only admin and host of the portal can change skins
Theory:
jQuery – jQuery comes into the picture when our page is loaded in client browser and it is ready. We will use jQuery to post ajax request to server using some parameters that can tell server side code what to do. That ajax call will wait for response and it expects response code (true or false) and response data (new css url).

Skin Object – The skin object will contain UI for changing the skin color as well as jQuery code that does the change in UI after interaction of the user. It handles the ajax request and update the database with the new skin file name.

Skin – While rendering the skin, we have to look into the database to check if current portal has any skin related setting available or not. If its not, we will render the default color skin. If it contains the setting, we will read it and apply.

Htmls and css - We will have a single ascx control called HomePage.ascx, with multiple css files blue.css and gray.css. Default is gray.css. Common attributes for the skin will be included in skin.css. common images are stored in images folder under skin root. Images for individual color css will be resided in a images/colorname/ folder. For instance, images for blue.css wll be in images/blue/ folder and same for gray.


Let’s Implement
Extend Skin – Create a new class that inherits from DotNetNuke.UI.Skins.Skin. Add a property for saving cssName. In get section of the property write a code to load css name from database by passing PortalSettings.portalid.

Use new Property – in ascx control where you have inherits section, change the DotNetNuke.UI.Skins.Skin to your class name. and add following after the register section at the top of the ascx control.



<link id="lnkMyCss" rel="stylesheet" href="<%=SkinPath+GridCss %>" type="text/css" media="screen, projection" />


Note: Make sure you have all the ascx, css and images arranged like mensioned in Htmls and css section.

Skin Object – Create a new skin object and add following code to its ascx.

<a href="javascript:void(0);" onclick="changeTheme(this.color);" color="Gray">Gray</a> |
<a href="javascript:void(0);" onclick="changeTheme(this.color);" color="Blue">Blue</a>
<script language="javascript" type="text/javascript">

function changeTheme(color)
{
jQuery.post(document.location.href,{action:'changeSkin',colorcode:color},response);
}

function response(data)
{
jQuery('#lnkMyCss')[0].href=data;
}
</script>

Add following code to Page_Init of the skin object.

protected void Page_Init(object sender, EventArgs e)
{
if (Request.Form["action"]!=null)
{
string action = Request.Form["action"].ToString();
string settingValue = string.Empty;
switch (action)
{
case "changeSkin":
if (Request.Form["colorcode"] != null)
{
string colorCode = Request.Form["colorcode"].ToString();
settingValue = colorCode == "Blue" ? "blue.css" : "gray.css";
BR.BRESS.Skins.DataProvider.Instance().setSettings(PortalSettings.PortalId, "CSS", settingValue);
settingValue = PortalSettings.ActiveTab.SkinSrc.Replace("HomePage.ascx", settingValue);
}

break;
default:
break;
}
Response.Clear();
Response.Write(settingValue);
Response.End();
}
}

Register Skin Object – Register this skin object in ascx control.

<%@ Register TagPrefix="BRESS" TagName="SKINMANAGER" Src="~/DesktopModules/SkinManager/SkinManager.ascx" %>

Note: The Src should contain a correct path of your skin object.
And wherever you like to add the UI you need to include this:

BRESS:SKINMANAGER ID="sm" runat="server" />

Conclusion:
• This article is only for those who knows basics about skin development and skin object development
• The methods and techniques used in this code are for demo purpose and can be improved
• It is a starting point to implement multi-skin multi-color functionality using DotNetNuke skinning technique.
• Simple alternative to this approach is to create multiple ascx controls and apply css to each control separately.
• Suggestions for enhancements and improvements are always welcome

3 comments:

  1. Do you have an example of this method? I am currently looking to do something just like this.

    Thanks.

    ReplyDelete
    Replies
    1. Hey i tried the same but unable to get the desired results.Dotnetnuke skins were not looking appropriate. Please upload one or two images of the same.

      Delete
  2. Hi Guys,

    Thanks for your comments, I implemented this before some time, I will try to get the source code and post it over here or quickly roll out on here.

    Thanks
    Prashant

    ReplyDelete

Please add your valuable comments about this post if it helped you. Thanks