Open Closed

How can I customise the login page in ABP Commercial? #3286


0
[email protected] created

Hi,

I'm using abp commercial v 4.4.0.

There is help on replacing the login.cshtml template here: https://docs.abp.io/en/abp/2.8/How-To/Customize-Login-Page-MVC This does now work however for the commercial version.

How can I replace the the login and registration pages with my own layout while preserving the functionality?

I think maybe I just need the appropriate pro source file to copy as a basis for the changed version?

Thanks,

Pete


13 Answer(s)
  • 0
    EngincanV created
    Support Team

    Hi, you can override the Login and Register pages and simply specify the layout as your own layout as below:

    @page
    //...
    @model Volo.Abp.Account.Public.Web.Pages.Account.LoginModel
    @inject IHtmlLocalizer<AccountResource> L
    @inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout
    @inject ISettingProvider SettingProvider
    @{
        Layout = "your-own-layout-path";
    }
    
    @* ... *@
    

    Just install the source code of the Volo.Account.Pro module and copy-paste content of both login and register pages and specify your own layout for them.

  • 0
    [email protected] created

    I don't have access to the source code.

    So are you saying that if I have a team account I can't even modify the login page?

  • 0
    [email protected] created

    But with the free version I can modify the login page - that seems wrong.

  • 0
    EngincanV created
    Support Team

    Let me share the Login.cshtml and Register.cshtml files contents' with you so you can customize them. Just put the same file in the same directory (I've specified them for you between parentheses) and make your changes.

    • Login.cshtml (/Pages/Account/Login.cshtml)
    @page
    @using Microsoft.AspNetCore.Mvc.Localization
    @using Microsoft.Extensions.Options
    @using Owl.reCAPTCHA
    @using Volo.Abp.Account.Localization
    @using Volo.Abp.Account.Public.Web.Security.Recaptcha
    @using Volo.Abp.Account.Settings
    @using Volo.Abp.Settings
    @model Volo.Abp.Account.Public.Web.Pages.Account.LoginModel
    @inject IHtmlLocalizer<AccountResource> L
    @inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout
    @inject ISettingProvider SettingProvider
    @{
        PageLayout.Content.Title = L["Login"].Value;
        var reCaptchaVersion = await SettingProvider.GetAsync<int>(AccountSettingNames.Captcha.Version);
        if (Model.UseCaptcha)
        {
            await Model.ReCaptchaOptions.SetAsync(reCaptchaVersion == 3 ? reCAPTCHAConsts.V3 :reCAPTCHAConsts.V2);
        }
    
    }
    
    @section scripts
    {
        @if (Model.UseCaptcha)
        {
            if (reCaptchaVersion == 3)
            {
                <recaptcha-script-v3/>
                <recaptcha-script-v3-js action="login" callback="(function(){$('#@RecaptchaValidatorBase.RecaptchaResponseKey').val(token)})"/>
            }
            else
            {
                <recaptcha-script-v2/>
            }
        }
    }
    
    @if (Model.IsLinkLogin)
    {
        <abp-alert alert-type="Warning">
            @L["LinkAccountWarning", Url.PageLink()]
        </abp-alert>
    }
    
    <div class="account-module-form">
        @if (Model.EnableLocalLogin)
        {
            <form method="post">
                @if (Model.UseCaptcha)
                {
                    <input type="hidden" name="@RecaptchaValidatorBase.RecaptchaResponseKey" id="@RecaptchaValidatorBase.RecaptchaResponseKey"/>
                }
                <abp-input asp-for="LoginInput.UserNameOrEmailAddress" required-symbol="false"/>
                <abp-input asp-for="LoginInput.Password" required-symbol="false"/>
                <abp-row>
                    <abp-column>
                        <abp-input asp-for="LoginInput.RememberMe" class="mb-4"/>
                    </abp-column>
                    <abp-column class="text-end">
                        <a href="@Url.Page("./ForgotPassword", new { returnUrl = Model.ReturnUrl, returnUrlHash = Model.ReturnUrlHash })">@L["ForgotPassword"]</a>
                    </abp-column>
                </abp-row>
    
                @if (reCaptchaVersion == 2)
                {
                    <recaptcha-div-v2 callback="(function(){$('#@RecaptchaValidatorBase.RecaptchaResponseKey').val(token)})" />
                }
    
                <div class="d-grid gap-2">
                    <abp-button button-type="Primary"type="submit" class="mb-3" name="Action" value="Login">@L["Login"]</abp-button>
                </div>
    
                @if (Model.ShowCancelButton)
                {
                    <div class="d-grid gap-2">
                        <abp-button button-type="Secondary" type="submit" formnovalidate="formnovalidate" class="mb-3" name="Action" value="Cancel">@L["Cancel"]</abp-button>
                    </div>
                }
            </form>
            if (Model.IsSelfRegistrationEnabled)
            {
                @L["NotAMemberYet"]
                <a href="@Url.Page("./Register", new {returnUrl = Model.ReturnUrl, returnUrlHash = Model.ReturnUrlHash})">@L["Register"]</a>
            }
        }
    
        @if (Model.VisibleExternalProviders.Any())
        {
            <hr/>
            @L["OrSignInWith"]<br/>
            <form asp-page="./Login" asp-page-handler="ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" asp-route-returnUrlHash="@Model.ReturnUrlHash" method="post">
                @foreach (var provider in Model.VisibleExternalProviders)
                {
                    <button
                        type="submit"
                        class="mt-2 me-2 btn btn-outline-primary btn-sm"
                        name="provider"
                        value="@provider.AuthenticationScheme"
                        data-busy-text="@L["ProcessingWithThreeDot"]">
                        @if (provider.Icon != null)
                        {
                            <i class="@provider.Icon"></i>
                        }
                        <span>@provider.DisplayName</span>
                    </button>
                }
            </form>
        }
    </div>
    
    • Register.cshtml (/Pages/Account/Register.cshtml)
    @page
    @using Microsoft.AspNetCore.Mvc.Localization
    @using Volo.Abp.Account.Localization
    @using Volo.Abp.Account.Public.Web.Security.Recaptcha
    @using Volo.Abp.Account.Settings
    @using Volo.Abp.Settings
    @model Volo.Abp.Account.Public.Web.Pages.Account.RegisterModel
    @inject IHtmlLocalizer<AccountResource> L
    @inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout
    @inject ISettingProvider SettingProvider
    @{
        PageLayout.Content.Title = L["Register"].Value;
        var reCaptchaVersion = await SettingProvider.GetAsync<int>(AccountSettingNames.Captcha.Version);
    }
    
    @if (!Model.LocalLoginDisabled)
    {
        @section scripts
        {
            @if (Model.UseCaptcha)
            {
                if (reCaptchaVersion == 3)
                {
                    <recaptcha-script-v3/>
                    <recaptcha-script-v3-js action="register" callback="(function(){$('#@RecaptchaValidatorBase.RecaptchaResponseKey').val(token)})"/>
                }
                else
                {
                    <recaptcha-script-v2/>
                }
            }
        }
    
        <div class="account-module-form">
            <form method="post">
    
                @if (Model.UseCaptcha)
                {
                    <input type="hidden" name="@RecaptchaValidatorBase.RecaptchaResponseKey" id="@RecaptchaValidatorBase.RecaptchaResponseKey"/>
                }
    
                @if (!Model.IsExternalLogin)
                {
                    <abp-input asp-for="Input.UserName" auto-focus="true"/>
                }
    
                <abp-input asp-for="Input.EmailAddress"/>
    
                @if (!Model.IsExternalLogin)
                {
                    <abp-input asp-for="Input.Password"/>
                }
    
                @if (reCaptchaVersion == 2)
                {
                    <recaptcha-div-v2 callback="(function(){$('#@RecaptchaValidatorBase.RecaptchaResponseKey').val(token)})" />
                }
    
                <div class="d-grid gap-2">
                    <abp-button button-type="Primary" type="submit" class="mt-2 mb-3">@L["Register"]</abp-button>
                </div>
                @L["AlreadyRegistered"] <a href="@Url.Page("./Login", new {returnUrl = Model.ReturnUrl, returnUrlHash = Model.ReturnUrlHash})">@L["Login"]</a>
            </form>
        </div>
    }
    
  • 0
    [email protected] created

    Thank you for this - much appreciated.

  • 0
    [email protected] created

    Hi, if I add the login.cshtml page in the Host project I get this. It's not rendering the controls.

  • 0
    [email protected] created

    Note that I have to exclude the file from the project as I get build errors if it's included as it's not an MVC project.

  • 0
    [email protected] created

    I can see I should include the page in the product but I get these compilation errors due to the Recaptcha lines.

    I'm using Visual Studio 2019.

  • 0
    EngincanV created
    Support Team

    Can you add the following tag-helper namespaces to your _ViewImports.cshtml file (/Pages/Account/_ViewImports.cshtml):

    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    @addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI
    @addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
    @addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling
    @addTagHelper *, Owl.reCAPTCHA
    
  • 0
    [email protected] created

    I got it to compile by upgrading to Visual Studio 2022 but it still does not render the buttons etc.

    I don't have a /Pages/Account/_ViewImports.cshtml file currently but I'll create one and see if that works. If I should have one, please can you let me have the source for it.

    Thanks,

  • 0
    [email protected] created

    That seems better. The button alignment is still off though.

    If I want to override the page layout where can I find the source for the original layout file to base it on?

  • 0
    [email protected] created

    I think I need the source for Basic.cshtml and Account.cshtml that are used in my Pro version 4.4. Would you be able to let me have those?

  • 0
    EngincanV created
    Support Team

    I think I need the source for Basic.cshtml and Account.cshtml that are used in my Pro version 4.4. Would you be able to let me have those?

    You can get the source code of the Lepton Theme (it's available for team license) and override it to your needs. I close this question since it seems you've successfully overridden the login and register pages. Please create a new question for further questions/problems.