Business Solution: Changing skin dynamically

From Sense/Net Wiki
Jump to: navigation, search
  •  
  •  
  •  
  •  
  • 100%
  • 6.0
  • Enterprise
  • Community
  • Planned

Overview

Problem description: I want to enable the users to pick their own skin after registration so that when they log in, the portal outlook is customized according to their choice.
Solution: We will expand the user's CTD so that the skin the user picked is persisted as a property of the user, and we will create a custom user control that will set the current page's skin to the current user's skin dynamically. We will place this custom control in a pagetemplate so that every page using that pagetemplate will use the skin picked by the user.

Steps

1. Expand the user's CTD so that users can pick a skin

Add the following definition to the User Content Type's CTD.

    <Field name="UserSkin" type="Reference">
      <DisplayName>Selected skin</DisplayName>
      <Configuration>
        <AllowMultiple>false</AllowMultiple>
        <AllowedTypes>
          <Type>Skin</Type>
        </AllowedTypes>
        <SelectionRoot>
          <Path>/Root/Skins</Path>
        </SelectionRoot>
      </Configuration>
    </Field>

Now when editing a user a skin can be picked for it.

It is strongly advised to use a custom User Content Type derived from the User and define extra fields there instead of extending the built-in User Content Type as future patches / modifications to this CTD will make it more difficult to upgrade your portal!

2. Customize the EditProfile Content View so that users can change their own skins

The Content View that displays the user content for the account by default only contains a couple of fields. The newly defined UserSkin field is not yet displayed. To display this field, edit the /Root/Global/contentviews/EditProfile.ascx file, according to the following:

<%@ Control Language="C#" AutoEventWireup="true" Inherits="SenseNet.Portal.UI.SingleContentView" %>
 
<div class="sn-content sn-content-inlineview">
 
    ...
 
    <sn:ReferenceGrid ID="ReferenceGrid1" runat="server" FieldName="UserSkin" />
</div>
 
...

Do not modify anything in the default layout, just add the extra line handling the UserSkin field. After that you will see the UserSkin field appear on the Edit Profile page (log in and click on the Edit Profile link in the login box):

Picking a custom skin for the current user

3. Create a custom user control that will apply the selected skin dynamically

We will now create a custom control that checks for the skin selected by the current user and sets the current page's skin accordingly. All portal logic afterwards will use the newly set skin. Create a class library in your solution and create a new class with the following code:

using System;
using System.Web.UI;
using SenseNet.Portal.Virtualization;
using SenseNet.ContentRepository.Storage;
using SenseNet.ContentRepository;
using System.Collections.Generic;
using System.Linq;
 
namespace MyNameSpace.Controls
{
    public class SkinSetter : UserControl
    {
        /* ========================================================================= Methods */
        protected override void OnInit(EventArgs e)
        {
            var currentUser = User.Current as User;
            if (currentUser != null && currentUser.HasProperty("UserSkin"))
            {
                var userSkin = currentUser["UserSkin"] as IEnumerable<Node>;
                if (userSkin != null)
                    PortalContext.Current.Page.PageSkin = userSkin.FirstOrDefault();
            }
            base.OnInit(e);
        }
    }
}

The above SkinSetter control does the following:

  • in the OnInit phase it checks if the current user has a UserSkin property
  • the UserSkin field is a reference field whose value is a List of Nodes via the IEnumerable interface
  • it overrides the current page's pageskin to use the value of the user's UserSkin property

We have defined the control in the MyNameSpace.Controls namespace, customize it to your solution's namespaces. The control is now ready to be used in a PageTemplate.

4. Use the control in a PageTemplate

First, don't forget to reference the created control in the Web.config so that you can use it in an ASP.Net control or page:

   <add tagPrefix="my" namespace="MyNameSpace.Controls" assembly="MyDll"/>

Give the namespace and the dll of the control. Now you can use it in a PageTemplate - we will reference the control in the /Root/Global/pagetemplates/sn-layout-dialog.html pagetemplate:

...
<body class="sn-body sn-layout1 sn-layout-dialog sn-intra-<%=snLang%>">
  <my:SkinSetter id="skinSetter1" runat="server" />
  ...
</body>
</html>

Put the SkinSetter control right after the body tag. Note the my tagprefix that was previously defined in the Web.config. Now the pages that use this PageTemplate will appear with the skin picked by the user.

Video

Related links

References