Login Status widget with external widget templates
It seems that it is not possible to change the LoggedInLayoutTemplatePath and LoggedOutLayoutTemplatePath properties of the LoginStatus widget. Is this a bug?
Hello Nelson,
Yes, there is a know issue about the template paths of the control. I suggest that you should use the standard ASP.NET analogs in a custom or user controls as a workaround.
Greetings,
Ivan Dimitrov
the Telerik team
Is there any progress on resolving this? Thanks
Hi Ian,
The status of the issue is not fixed. There is a workaround that I see if you override
LoggedInLayoutTemplatePath and LoggedOutLayoutTemplatePath, but changing the properties though the control designer does not work.
Regards,
Ivan Dimitrov
the Telerik team
Can you go into a bit more depth explaining the work around?
Thanks!
-Ben
@Ivan:
Per your last post: "There is a workaround that I see if you override
LoggedInLayoutTemplatePath and LoggedOutLayoutTemplatePath, but changing the properties though the control designer does not work."
The "LoggedInLayoutTemplatePath" and "LoggedInLayoutTemplatePath" values aren't persisted when edited via the designer. Any info on the work around would be appreciated.
Thanks--Steve
Hi Stevev,
You have to inherit from LoginStatusControl and override the virtual LoggedInLayoutTemplatePath and LoggedOutLayoutTemplatePath public properties.
Regards,
Ivan Dimitrov
the Telerik team
I've tried to do this but my solution doesn't work. Can you give me an example ?
Thanks
Hi,
Here is a sample code
using System;using System.Collections.Generic;using System.Linq;using System.Web;using Telerik.Sitefinity.Web.UI.PublicControls;namespace SitefinityWebApp public class LoginStatusControlSample : LoginStatusControl protected override string LoggedInLayoutTemplateName get return null; protected override string LoggetOutLayoutTemplateName get return null; public override string LoggedInLayoutTemplatePath get return "~/MyPRefix/Telerik.Sitefinity.Samples.Resources.LoggedInLayoutTemplatePath.ascx";// here return your template using Virtual Path provider public override string LoggedOutLayoutTemplatePath get return "~/MyPRefix/Telerik.Sitefinity.Samples.Resources.LoggedOutLayoutTemplatePath.ascx";";//here return your template using Virtual Path provider Anyone else experiencing this issue... lets vote it up so they'll finally fix it. Still an issue in the latest version a year and a half later... only now the workaround doesn't even work it seems.
www.telerik.com/.../pits.aspx
I overrode all three functions below, the designer is working fine but I still can't get the right template to show. Any update on this?
public class LoginStatusControl : Telerik.Sitefinity.Web.UI.PublicControls.LoginStatusControl private string _LoggedInLayoutTemplatePath; private string _LoggedOutLayoutTemplatePath; [Browsable(false)] public override string LayoutTemplatePath get if (!this.IsLoggedIn) return this.LoggedOutLayoutTemplatePath; return this.LoggedInLayoutTemplatePath; set [WebDisplayName("DisplayName_LoggedInLayoutTemplatePath"), Telerik.Sitefinity.Web.UI.PublicControls.Attributes.WebCategory("ControLCategory_Templates")] public override string LoggedInLayoutTemplatePath get if (_LoggedInLayoutTemplatePath.IsNullOrEmpty()) return ControlUtilities.ToVppPath("Telerik.Sitefinity.Resources.Templates.PublicControls.LoginStatus_LoggedIn.ascx"); else return _LoggedInLayoutTemplatePath; set base.LayoutTemplatePath = value; _LoggedInLayoutTemplatePath = value; [WebDisplayName("DisplayName_LoggedOutLayoutTemplatePath"), Telerik.Sitefinity.Web.UI.PublicControls.Attributes.WebCategory("ControLCategory_Templates")] public override string LoggedOutLayoutTemplatePath get if (_LoggedOutLayoutTemplatePath.IsNullOrEmpty()) return ControlUtilities.ToVppPath("Telerik.Sitefinity.Resources.Templates.PublicControls.LoginStatus_LoggedOut.ascx"); else return _LoggedOutLayoutTemplatePath; set base.LayoutTemplatePath = value; _LoggedOutLayoutTemplatePath = value; Hi,
Unfortunately this is not fixed yet. I'll increase the priority of the PITS and we'll do out best to fix it in one of our next Releases.
As for your solution - you should better override the LayoutTemplateName property and use the same logic as in the LayoutTemplatePath:
protected override string LayoutTemplateName get return this.IsLoggedIn ? this.LoggedInLayoutTemplateName : this.LoggetOutLayoutTemplateName; public override string LayoutTemplatePath get return this.IsLoggedIn ? this.LoggedInLayoutTemplatePath : this.LoggedOutLayoutTemplatePath; set // does nothing Veronica your suggested code doesn't seem to work.
Here is what I use but my controls never get displayed....
using System;using System.Linq;using Telerik.Sitefinity.Web.UI.PublicControls;namespace SitefinityWebApp.CustomWidgets.Login public class CustomLoginStatus : LoginStatusControl protected override string LayoutTemplateName get return this.IsLoggedIn ? this.LoggedInLayoutTemplateName : this.LoggetOutLayoutTemplateName; public override string LayoutTemplatePath get return this.IsLoggedIn ? this.LoggedInLayoutTemplatePath : this.LoggedOutLayoutTemplatePath; set // does nothingv dsf protected override string LoggedInLayoutTemplateName get return "~/SfLocal/SitefinityWebApp.CustomWidgets.Login.LoginStatus_LoggedIn.ascx"; protected override string LoggetOutLayoutTemplateName get return "~/SfLocal/SitefinityWebApp.CustomWidgets.Login.LoginStatus_LoggedOut.ascx"; public override string LoggedInLayoutTemplatePath get return "~/SfLocal/SitefinityWebApp.CustomWidgets.Login.LoginStatus_LoggedIn.ascx"; public override string LoggedOutLayoutTemplatePath get return "~/SfLocal/SitefinityWebApp.CustomWidgets.Login.LoginStatus_LoggedOut.ascx"; Hello Ivan,
To address our client feedback where in some cases the LoginStatus control was displaying the cahced HTML and did not update its staus correclty we have implemented cache subsitution for that control. In other words, the LoginStatus control does not use the LayoutTemplatePath property to resolve the markup that should be rendered anymore.
Let me quickly elaborate a bit on the above statement:
For each control inheriting from System.Web.UI.WebControls.WebControl we can override the RenderContents(System.Web.UI.HtmlTextWriter writer) method and in it we call our own implementation for performing cache substitution.
In LoginStatusControl, for example we have:
protected override void RenderContents(System.Web.UI.HtmlTextWriter writer) if (!SystemManager.IsDesignMode) this.DoPostCacheSubstitution(); else writer.WriteEncodedText(Res.Get<PublicControlsResources>().ControlCannotBeRenderedInDesignMode.Arrange(Res.Get<PublicControlsResources>().LoginStatusControlTitle)); private void DoPostCacheSubstitution() Dictionary<string, string> parameters = new Dictionary<string, string>(); parameters.Add("ShowLoginName", this.ShowLoginName.ToString()); parameters.Add("LoginNameFormatString", this.LoginNameFormatString); parameters.Add("ClientId", ((LinkButton)this.StatusButton).UniqueID); Page.ClientScript.RegisterForEventValidation(((LinkButton)this.StatusButton).UniqueID); CacheSubstitutionWrapper cacheSubstitutionWrapper = new CacheSubstitutionWrapper(parameters, new CacheSubstitutionWrapper.RenderMarkupDelegate(LoginStatusControl.RenderCacheSubstitutionMarkup)); cacheSubstitutionWrapper.RegisterPostCacheCallBack(this.Context); internal static string RenderCacheSubstitutionMarkup(Dictionary<string, string> parameters) bool isUserLoggedIn = false; ClaimsIdentityProxy user = ClaimsManager.GetCurrentIdentity(); if (user != null) isUserLoggedIn = user.IsAuthenticated; StringBuilder resultMarkup = new StringBuilder(); if (isUserLoggedIn) bool showLoginName = bool.Parse(parameters["ShowLoginName"]); if (showLoginName) string formatedUserName = LoginNameControl.FormatLoginName(parameters["LoginNameFormatString"]); resultMarkup.Append(formatedUserName); resultMarkup.AppendFormat(@" <a href=""javascript:__doPostBack('0','')"" >1</a>", parameters["ClientId"].ToString(), Res.Get<PublicControlsResources>().LogOutText); else resultMarkup.AppendFormat(@" <a href=""javascript:__doPostBack('0','')"" >1</a>", parameters["ClientId"].ToString(), Res.Get<PublicControlsResources>().LogInText); return resultMarkup.ToString(); CacheSubstitutionWrapper is loaded from the LogInText and LogOutText localizable resources of the PublicControlsResources(you can edit these from Administration -> Interface labels and messages). You can either modify their values or inherit from the control, and override the above listed methods, so you can plug in your custom markup.Hi Boyan,
yes that's also what was posted by Patrick Dunn on his blog, it's not a very nice nor elegant solution, and I already brought other's attention to a potential problem with the beginning of that RenderCacheSubsitutionMarkup method:
ClaimsIdentityProxy user = ClaimsManager.GetCurrentIdentity();
will not be null even if its an unauthenticated user. ClaimsManager returns a user object anyway the only difference is that user.Name = "Anonymous";
;-)
Hello Ivan,
Thnak you for your feedback. Can you please elaborate a bit on the potential problem you've spotted with that call, so we can inspect it further if necessary?
Please note that the logical switch on the following line is actually targeted towards determining the user.IsAuthenticated value, so the check for null if just a standard defense programming - we do not expect the user to be null when the currently browsing user is not authenticated, but we need to ensure we've retrieved the ClaimsIdentityProxy object, before checking its IsAuthenticated property.
Regards,
Boyan Barnev
the Telerik team
Hi Boyan,
my wrong. I expected an unauthenticated visitor to be null, now I get it, you get back a user (of type ClaimsIdentityProxy ) for unauthenticated users to and then you check wether they are authenticated or not. I was surprised to see that no null user is returned for unauthenticated users. You can freely delete my former post as it might be misguiding others then.
Thanks Boyane,
Ivan
Hi Ivan,
No problems at all, we highly value your constructive feedback you've been providing us with, and just wanted to make sure where there wasn't an actual problem worth researching. I'm really glad to hear that everything has been sorted now.
Greetings,
Boyan Barnev
the Telerik team