Was mir bei DotNetNuke schon lange nicht schmeckt ist der ganze Login und Registrierungsbereich.
Zum einen habe ich andere Anforderungen - okay dafür kann das Core-Team nichts - zum anderen ist aber die Anpassung des Layout nur für alle Portal gleichzeitig möglich.
Deswegen habe ich mich hingesetzt und ein ein weiters Modul dafür geschrieben. Ja, es gibt zwar schon ein paar aber die unterstützen halt alle nicht ein Templatesystem.
Das Konzept dafür ist relativ einfach: Zur Laufzeit wird die ASCX Datei dynamisch geladen. Entweder wird dabei ein Standardlayout geladen oder aber wenn vorhanden aus dem jeweiligen Portalverzeichnis.
Dafür habe ich eine Klasse SkinnedWebControl geschrieben, die von PortalModuleBase abgeleitet wird.
Die Methode InitSkin() lädt das entsprechende Skin und sorgt dafür das es initialisiert wird.
protected Control LoadSkin()
{
Control skin;
skinpath = this.PortalSettings.HomeDirectory + "GaliNeo/UserAccount/" ;
// Do we have a skin?
if (SkinFilename == null)
throw new Exception("You must specify a skin.");
try
{
skin = this.LoadControl(skinpath + this.skinFilename) ;
}
catch (FileNotFoundException)
{
try
{
skinpath = this.ModulePath + "UITemplates/" ;
skin = this.LoadControl(skinpath + this.skinFilename);
}
catch (FileNotFoundException)
{
throw new Exception("Critical error: The skinfile '" + skinpath + "' could not be found. The skin must exist for this control to render.");
}
}
// Initialize the skin
InitializeSkin(skin);
Controls.Add(skin) ;
return skin;
}
Die Mehtode InitializeSkin() wird dann in der entsprechenden Klasse überschrieben um z.B die Steuerelemente mit entsprechenden Werten zu versehen oder aber auch Events an die Steuerelemente zu binden.
protected abstract void InitializeSkin(Control skin);
Das entsprechende DotNetNuke Modul UserControl wird dann von der Klasse SkinnedWebControl abgeleiet.
Eine Besonderheit ist der Zugriff auf Steuerelemente. Diese sind nicht direkt ansprechbar sonder müssen zunächst über die Methode FindControl gesucht werden. So könnte das dann aussehen:
protected override void InitializeSkin(Control skin)
{
LabelControl dnnlbl = null ;
LinkButton lnkbtn = null ;
dnnlbl = (LabelControl) skin.FindControl("lblUserName") ;
if (dnnlbl != null)
{
dnnlbl.Text = GetLocalization("lblUserName") ;
}
lnkbtn = (LinkButton) skin.FindControl("lnkBtnLogIn") ;
if (lnkbtn != null)
{
lnkbtn.Text = GetLocalization("lnkBtnLogIn") ;
lnkbtn.Click += new System.EventHandler(btnLogIn_Click) ;
}
}
Die ASCX Datei des Modules sieht ganz normal aus, nur sind dort die Controls nicht definiert. Dafür gibt es die Templatedatei wobei es sich auch um ene ASCX Datei handelt, die aber nicht die Attribute CodeBehind und Namespace benötigt.
Die beiden Controls Label und LinkButton werden in der Template-ASCX wie gewohnt definiert.