+1-888-365-2779
Try Now
More in this section

Forums / Sitefinity SDK / Login Status widget with external widget templates

Login Status widget with external widget templates

18 posts, 0 answered
  1. Nelson
    Nelson avatar
    14 posts
    Registered:
    29 Dec 2010
    01 Jul 2011
    Link to this post
    It seems that it is not possible to change the LoggedInLayoutTemplatePath and LoggedOutLayoutTemplatePath properties of the LoginStatus widget. Is this a bug?
  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    04 Jul 2011
    Link to this post
    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

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>

  3. Ian
    Ian avatar
    7 posts
    Registered:
    02 Mar 2009
    05 Oct 2011
    Link to this post
    Is there any progress on resolving this?  Thanks
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    06 Oct 2011
    Link to this post
    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

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  5. Ben
    Ben avatar
    44 posts
    Registered:
    27 Sep 2012
    17 Nov 2011
    Link to this post
    Can you go into a bit more depth explaining the work around?

    Thanks!

    -Ben
  6. SteveV
    SteveV avatar
    178 posts
    Registered:
    06 Nov 2011
    01 Dec 2011
    Link to this post
    @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
  7. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    06 Dec 2011
    Link to this post
    Hi Stevev,

    You have to inherit from LoginStatusControl and override the virtual LoggedInLayoutTemplatePath and LoggedOutLayoutTemplatePath public properties.



    Regards,
    Ivan Dimitrov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  8. Elsane
    Elsane avatar
    30 posts
    Registered:
    06 Jan 2012
    07 Feb 2012
    Link to this post
    I've tried to do this but my solution doesn't work. Can you give me an example ?

    Thanks
  9. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    08 Feb 2012
    Link to this post
    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
                }
     
            }
           
        }
    }


    http://www.sitefinity.com/blogs/slavoingilizov/posts/11-04-18/taking_advantage_of_the_virtual_path_provider_in_sitefinity_4_1.aspx

    Regards,
    Ivan Dimitrov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  10. denny
    denny avatar
    13 posts
    Registered:
    16 Oct 2007
    30 Nov 2012
    Link to this post
    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.

    http://www.telerik.com/support/pits.aspx#/public/sitefinity/13353
  11. Victor
    Victor avatar
    94 posts
    Registered:
    15 Jun 2011
    25 Jan 2013
    Link to this post
    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;
                }
            }
        }
  12. Veronica
    Veronica avatar
    125 posts
    Registered:
    30 Jan 2015
    28 Jan 2013
    Link to this post
    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
                }
            }

    Please accept my apologies for the caused inconvenience.

    Regards,
    Veronica Milcheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  13. Ivan
    Ivan avatar
    12 posts
    Registered:
    16 Sep 2012
    12 Apr 2013 in reply to Veronica
    Link to this post

    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";
                }
            }
        }
    }
  14. Boyan Barnev
    Boyan Barnev avatar
    1429 posts
    Registered:
    02 Dec 2016
    16 Apr 2013
    Link to this post
    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:
    Copy Code
    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));
                }
            }

    When OutputCache is used on the page, we substitute it with the CacheSubstitutionWrapper in DoPostCacheSubstitution() method by forming a Dictionary of parameters and passing it to a CacheSubstitutionWrapper.RenderMarkupDelegate which will later render the correct markup.

    So for example in LoginStatusControl we've implemented DoPostCacheSubstitution() like this:
    Copy Code
    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);
            }

    and the delegate implementation:

    Copy Code
    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();
            }

    As you can notice from the last code excerpt above, the dynamically generated markup that will be rendered in the 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.

    I hope you find the above information useful. please do not hesitate to let us know if you have any further questions, we'll be glad to help

    Greetings,
    Boyan Barnev
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  15. Ivan
    Ivan avatar
    12 posts
    Registered:
    16 Sep 2012
    16 Apr 2013 in reply to Boyan Barnev
    Link to this post
    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";

    ;-)
  16. Boyan Barnev
    Boyan Barnev avatar
    1429 posts
    Registered:
    02 Dec 2016
    19 Apr 2013
    Link to this post
    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

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  17. Ivan
    Ivan avatar
    12 posts
    Registered:
    16 Sep 2012
    19 Apr 2013 in reply to Boyan Barnev
    Link to this post
    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
  18. Boyan Barnev
    Boyan Barnev avatar
    1429 posts
    Registered:
    02 Dec 2016
    19 Apr 2013
    Link to this post
    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

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

18 posts, 0 answered