Open Closed

How can I change the layout of the login page? #6571


User avatar
0
ageiter created
  • ABP Framework version: v8.0.2
  • UI Type: Blazor Server
  • Database System: EF Core (SQL Server)
  • Tiered (for MVC) or Auth Server Separated (for Angular): no

In the LeptonX demo you present 3 different account pages. I would like to use the "Login 3" layout for the login. How do I have to configure the application so that this is applied?

I know I read about this somewhere, but I can't find it anymore... I have searched the documentation, blogs, forum, Discord, etc. for a long time now... But it is in the demo, so it must work somehow. But how?

I'm not talking about how to create a custom layout, I know that and I can find plenty of explanations. It's about how I choose one of the 3 LeptonX layouts.

Thanks, Adrian


11 Answer(s)
  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Hi,

    LeptonX HTML demo shows you only possibilities with LeptonX theme. C# packages don't include all the variations inside them. If you need to customize a page, you should override it in your project and make changes by following Overriding a razor page documentation.

    In your case, you'll need to customize Account Layout in your project. And since Account layout is implemented inMVC, you'll need to override .cshtml file.

    • Create Themes/LeptonXLite/Layouts/Account.cshtml file in your project.
    • Fill the content of the file like below: (Original content from LeptonX 3.0, you can download the source-code of the theme from here)
    @using System.Globalization
    @using Microsoft.Extensions.Localization
    @using Microsoft.Extensions.Options
    @using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook
    @using Volo.Abp.AspNetCore.Mvc.UI.Layout
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Themes.LeptonXLite.Components.PageAlerts
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Bundling
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Themes.LeptonXLite.Components.Brand
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Themes.LeptonXLite.Components.BreadCrumbs
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Toolbars
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Themes.LeptonXLite.Components.MainToolbar
    @using Volo.Abp.AspNetCore.Mvc.UI.Theming
    @using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts
    @using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles
    @using Volo.Abp.Localization
    @using Volo.Abp.Ui.Branding
    @using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization
    @using Volo.Abp.AspNetCore.MultiTenancy
    @using Volo.Abp.MultiTenancy
    @using Volo.Abp.Ui.LayoutHooks
    @inject IBrandingProvider BrandingProvider
    @inject IPageLayout PageLayout
    @inject IStringLocalizer<AbpUiMultiTenancyResource> MultiTenancyStringLocalizer
    @inject ITenantResolveResultAccessor TenantResolveResultAccessor
    @inject IOptions<AbpMultiTenancyOptions> MultiTenancyOptions
    @inject ICurrentTenant CurrentTenant
    @{
    	Layout = null;
    	
    	var pageTitle = ViewBag.Title == null ? BrandingProvider.AppName : ViewBag.Title; //TODO: Discard to get from Title
    
    	if (PageLayout.Content.Title != null)
    	{
    		if (!string.IsNullOrWhiteSpace(pageTitle))
    		{
    			pageTitle = " | " + pageTitle;
    		}
    
    		pageTitle = PageLayout.Content.Title + pageTitle;
    	}
    
    	var rtl = CultureHelper.IsRtl ? "rtl" : string.Empty;
    }
    
    <!DOCTYPE html>
    
    <html lang="@CultureInfo.CurrentCulture.Name" dir="@rtl">
    
    <head>
    	@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.First, StandardLayouts.Account)
    
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    	<meta http-equiv="X-UA-Compatible" content="ie=edge">
    
    	<title>@pageTitle</title>
    
    	<link rel="icon" href="~/favicon.svg" type="image/svg+xml">
    	
    	<abp-style-bundle name="@LeptonXLiteThemeBundles.Styles.Global" />
    
    	@await Component.InvokeAsync(typeof(WidgetStylesViewComponent))
    
    	@await RenderSectionAsync("styles", false)
    
    	@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Account)
    </head>
    
    <body class="abp-account-layout @rtl">
    	@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.First, StandardLayouts.Account)
    
    	<div class="lpx-scroll-container">
    		<div id="lpx-wrapper">
    
    			<div class="lpx-mobile-navbar-container">
    				<header class="lpx-mobile-navbar">
    					<div class="lpx-logo-container">
    						@await Component.InvokeAsync(typeof(MainNavbarBrandViewComponent))
    					</div>
    					<div class="user-menu">
    						<i class="lpx-icon bi bi-person lpx-toggle" data-lpx-toggle="mobile-user-menu-group" aria-hidden="true"></i>
    					</div>
    				</header>
    
    				<div class="user-menu-groups d-none" id="mobile-user-menu-group">
    					@await Component.InvokeAsync(typeof(ToolbarItemsViewComponent), new { Name = LeptonXLiteToolbars.MainMobile })
    				</div>
    			</div>
    
    			<div class="lpx-content-container m-0">
    				<div class="lpx-topbar-container">
    					<div class="lpx-topbar rounded-0">
    						<nav aria-label="breadcrumb" class="lpx-breadcrumb-container">
    							@await Component.InvokeAsync(typeof(BreadCrumbsViewComponent))
    						</nav>
    
    						<div class="lpx-topbar-content">
    							@await Component.InvokeAsync(typeof(ToolbarItemsViewComponent), new { Name = LeptonXLiteToolbars.Main})
    						</div>
    					</div>
    				</div>
    
    				<div class="lpx-content">
    					@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Account)
    
    					<div class="container">
    						<div class="row"> 
    							<div class="col-md-8 col-lg-5 mx-auto">
    								
    								@await Component.InvokeAsync(typeof(PageAlertsViewComponent))
    
    								@if (MultiTenancyOptions.Value.IsEnabled &&
    									(TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(CookieTenantResolveContributor.ContributorName) == true ||
    									TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(QueryStringTenantResolveContributor.ContributorName) == true))
    								{
    									<abp-card>
    										<abp-card-body>
    											<div class="row">
    												<div class="col">
    													<span style="font-size: .8em;"
    														class="text-uppercase text-muted">@MultiTenancyStringLocalizer["Tenant"]</span><br />
    													<h6 class="m-0 d-inline-block">
    														@if (CurrentTenant.Id == null)
    														{
    															<span>
    																@MultiTenancyStringLocalizer["NotSelected"]
    															</span>
    														}
    														else
    														{
    															<strong>@(CurrentTenant.Name ??
    																	CurrentTenant.Id.Value.ToString())</strong>
    														}
    													</h6>
    												</div>
    												<div class="col-auto">
    													<a id="AbpTenantSwitchLink" href="#"
    													class="btn btn-sm btn-outline-primary">@MultiTenancyStringLocalizer["Switch"]</a>
    												</div>
    											</div>
    										</abp-card-body>
    									</abp-card>
    									<hr />
    								}
    
    
    								@RenderBody()
    
    								@*<UiMessageAlert />
    								<UiNotificationAlert />
    								<UiPageProgress />*@
    						
    								@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Account)
    							</div>
    						</div>
    					</div>
    				</div>
    
    			</div>
    
    		</div>
    	</div>
    
    	<abp-script-bundle name="@LeptonXLiteThemeBundles.Scripts.Global" />
            <abp-script src="~/Abp/ApplicationLocalizationScript?cultureName=@CultureInfo.CurrentUICulture.Name"/>
    	<abp-script type="text/javascript" src="~/Abp/ApplicationConfigurationScript"/>
    	<abp-script type="text/javascript" src="~/Abp/ServiceProxyScript"/>
    
    	@await Component.InvokeAsync(typeof(WidgetScriptsViewComponent))
    
    	@await RenderSectionAsync("scripts", false)
    
    	@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Account)
    </body>
    
    </html>
    
    

    When you do that, this file will be being used as account layout. You can make changes in this file according to your desired login page from https://x.leptontheme.com/side-menu/login-pages/login-2

  • User Avatar
    0
    ageiter created

    Thanks for the answer @enisn.

    I really thought I had seen that you can set the layout via configuration... I was so sure about that. But I was probably dreaming it ;-)

    You mentioned the path Themes/LeptonXLite/Layouts/Account.cshtml above. But I assume you are talking about LeptonX and not LeptonXLite.

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Sorry, my bad. You're right.

    In the LeptonX, it'll beThemes/LeptonX/Layouts/Account/Default.cshtml You can override this file for Account layout of LeptonX and existing content is below:

    @using Microsoft.Extensions.Localization
    @using Microsoft.Extensions.Options
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX
    @using Volo.Abp.LeptonX.Shared.Localization;
    @using Volo.Abp.Localization
    @using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling
    @using Volo.Abp.AspNetCore.Mvc.UI.Theming
    @using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts
    @using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles
    @using Volo.Abp.Ui.Branding
    @using Volo.Abp.AspNetCore.Mvc.AntiForgery
    @using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization
    @using Volo.Abp.AspNetCore.MultiTenancy
    @using Volo.Abp.MultiTenancy
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Themes.LeptonX.Components.Common.PageAlerts
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Themes.LeptonX.Components.SideMenu.Toolbar.LanguageSwitch
    @using Microsoft.AspNetCore.Http.Extensions
    @using Volo.Abp.Ui.LayoutHooks
    @inject IAbpAntiForgeryManager AbpAntiForgeryManager
    @inject IBrandingProvider BrandingProvider
    @inject LeptonXStyleProvider LeptonXStyleProvider
    @inject IStringLocalizer<AbpUiMultiTenancyResource> MultiTenancyStringLocalizer
    @inject IStringLocalizer<LeptonXResource> L
    @inject ITenantResolveResultAccessor TenantResolveResultAccessor
    @inject IOptions<AbpMultiTenancyOptions> MultiTenancyOptions
    @inject ICurrentTenant CurrentTenant
    @inject ThemeLanguageInfoProvider ThemeLanguageInfoProvider
    @inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout
    
    @{
        AbpAntiForgeryManager.SetCookie();
        var langDir = CultureHelper.IsRtl ? "rtl" : string.Empty;
        var title = $"{ViewBag.Title ?? PageLayout.Content.Title} | {BrandingProvider.AppName}".Trim('|', ' ');
    
    
        var languageInfo = await ThemeLanguageInfoProvider.GetLanguageSwitchViewComponentModel();
        var returnUrl = System.Net.WebUtility.UrlEncode(Context.Request.GetEncodedPathAndQuery());
    
        var logoUrl = BrandingProvider.LogoUrl == null ? null : "--lpx-logo: url(" + BrandingProvider.LogoUrl + ");";
        var logoReverseUrl = BrandingProvider.LogoReverseUrl == null ? null : "--lpx-logo: url(" + BrandingProvider.LogoReverseUrl + ");";
        var selectedStyle = await LeptonXStyleProvider.GetSelectedStyleAsync();
    
        var selectedStyleFileName = CultureHelper.IsRtl ? selectedStyle + ".rtl" : selectedStyle;
    }
    <!DOCTYPE html>
    <html lang="@CultureInfo.CurrentCulture.Name" dir="@langDir">
    
    <head>
    
        @await Component.InvokeLayoutHookAsync(LayoutHooks.Head.First, StandardLayouts.Account)
    
        <title>@title</title>
    
        <meta name="viewport" content="width=device-width,initial-scale=1.0" />
        <meta charset="UTF-8" />
        <meta name="description" content="@ViewBag.MetaDescription">
    
        <link rel="icon" href="~/favicon.svg" type="image/svg+xml">
    
        <abp-style-bundle name="@LeptonXThemeBundles.Styles.Global" />
    
        <link href="~/Themes/LeptonX/Global/side-menu/css/bootstrap-@(selectedStyleFileName).css" type="text/css"
              rel="stylesheet" id="lpx-theme-bootstrap-@selectedStyle" />
        <link href="~/Themes/LeptonX/Global/side-menu/css/@(selectedStyleFileName).css" type="text/css" rel="stylesheet"
              id="lpx-theme-color-@selectedStyle" />
    
        @await Component.InvokeAsync(typeof(WidgetStylesViewComponent))
        @await RenderSectionAsync("styles", false)
        @await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Account)
    
        <style>
            .lpx-login-bg {
                background-image: url('/LeptonX/images/login-pages/login-bg-img-@(selectedStyle).svg') !important;
            }
    
            :root .lpx-theme-light {
                @logoUrl
            }
            :root .lpx-theme-dark {
                @logoReverseUrl
            }
    
            :root .lpx-theme-dim {
                @logoReverseUrl
            }
        </style>
    </head>
    
    <body class="abp-account-layout lpx-theme-@selectedStyle">
    
        @await Component.InvokeLayoutHookAsync(LayoutHooks.Body.First, StandardLayouts.Account)
    
    
        <div class="container-fluid p-0 overflow-hidden">
            @await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Account)
            <div class="lpx-login-area">
                <div class="lpx-login-bg">
                    <div class="d-flex flex-column justify-content-center min-vh-100">
    
                        <div class="row">
                            <div class="col-xxl-5 col-lg-7 col-md-8 col-11 mx-auto position-relative py-4">
    
                                @if (BrandingProvider.LogoUrl.IsNullOrEmpty())
                                {
                                    <div class="lpx-logo-container lpx-login-brand-text">
                                        <div class="lpx-brand-logo lpx-login-logo mx-auto"></div> 
                                        <div class="lpx-brand-name lpx-login-name mx-auto">@BrandingProvider.AppName</div> 
                                    </div>
                                }
                                else
                                {
                                    <div class="lpx-brand-logo lpx-login-logo mb-3 mx-auto"></div>
                                }
    
    
                                <div class="card mx-auto" style="max-width: 30rem;">
                                    <div class="card-body p-3 p-sm-4">
                                        <div class="align-items-start d-flex justify-content-between mb-2">
                                            <h2 class="lpx-main-title lpx-login-title m-0 me-auto"> @PageLayout.Content.Title @* TODO: Find a better text here. *@</h2>
                                            <div class="dropdown btn-group ms-auto" aria-labelledby="languageDropdown">
    
                                                <button class="btn btn-sm btn-light dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                                                    <i class="bi bi-translate me-1"></i> @languageInfo.CurrentLanguage.DisplayName
                                                </button>
    
                                                <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenuButton1" style="">
                                                    @foreach (var language in languageInfo.Languages)
                                                    {
                                                        var twoLetterLanguageName = new CultureInfo(language.CultureName).TwoLetterISOLanguageName.ToUpperInvariant();
                                                        var url = Url.Content($"~/Abp/Languages/Switch?culture={language.CultureName}&uiCulture={language.UiCultureName}&returnUrl={returnUrl}");
                                                        <li>
                                                            <a href="@url" class="dropdown-item" data-lpx-language-option="@twoLetterLanguageName">@language.DisplayName / @twoLetterLanguageName</a>
                                                        </li>
                                                    }
                                                </ul>
                                            </div>
                                        </div>
    
                                        <hr />
    
                                        @await Component.InvokeAsync(typeof(PageAlertsViewComponent))
    
                                        @if (MultiTenancyOptions.Value.IsEnabled &&
                                        (TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(CookieTenantResolveContributor.ContributorName)
                                        == true ||
                                        TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(QueryStringTenantResolveContributor.ContributorName)
                                        == true))
                                        {
                                            <div>
                                                <div class="row">
                                                    <div class="col">
                                                        <span style="font-size: .8em;"
                                                              class="text-uppercase text-muted">@MultiTenancyStringLocalizer["Tenant"]</span><br />
                                                        <h6 class="m-0 d-inline-block">
                                                            @if (CurrentTenant.Id == null)
                                                            {
                                                                <span>
                                                                    @MultiTenancyStringLocalizer["NotSelected"]
                                                                </span>
                                                            }
                                                            else
                                                            {
                                                                <strong>
                                                                    @(CurrentTenant.Name ??
                                                                        CurrentTenant.Id.Value.ToString())
                                                                </strong>
                                                            }
                                                        </h6>
                                                    </div>
                                                    <div class="col-auto">
                                                        <a id="AbpTenantSwitchLink" href="#"
                                                           class="btn btn-sm btn-outline-primary">@MultiTenancyStringLocalizer["Switch"]</a>
                                                    </div>
                                                </div>
                                            </div>
                                            <hr />
    
                                        }
    
                                        @RenderBody()
    
                                    </div>
                                    @* @await Html.PartialAsync("~/Themes/LeptonX/Layouts/Account/_Footer.cshtml") *@
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
    
            @await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Account)
        </div>
    
        <abp-script-bundle name="@LeptonXThemeBundles.Scripts.Global" />
        <abp-script src="~/Abp/ApplicationLocalizationScript?cultureName=@CultureInfo.CurrentUICulture.Name"/>
        <abp-script src="~/Abp/ApplicationConfigurationScript"/>
        <abp-script src="~/Abp/ServiceProxyScript"/>
        @await Component.InvokeAsync(typeof(WidgetScriptsViewComponent))
        @await RenderSectionAsync("scripts", false)
        @await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Account)
    </body>
    
    </html>
    
  • User Avatar
    0
    ageiter created

    Thanks for the code. Is it possible to download the different layouts somewhere? We want layout 3 and not layout 2 and we are not sure yet whether TopMenu / SideMenu (although this does not matter on the login page).

    It seems that these layouts are not included in the module "Volo.Abp.LeptonXTheme.Pro", right?

  • User Avatar
    0
    ageiter created

    In general, it would of course be cool if we could get the source code of the demo page https://x.leptontheme.com/ (also for other pages that are nicely designed).

  • User Avatar
    0
    user5.abpio created

    Sorry, my bad. You're right.

    In the LeptonX, it'll beThemes/LeptonX/Layouts/Account/Default.cshtml You can override this file for Account layout of LeptonX and existing content is below:

    @using Microsoft.Extensions.Localization 
    @using Microsoft.Extensions.Options 
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX 
    @using Volo.Abp.LeptonX.Shared.Localization; 
    @using Volo.Abp.Localization 
    @using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook 
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling 
    @using Volo.Abp.AspNetCore.Mvc.UI.Theming 
    @using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts 
    @using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles 
    @using Volo.Abp.Ui.Branding 
    @using Volo.Abp.AspNetCore.Mvc.AntiForgery 
    @using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization 
    @using Volo.Abp.AspNetCore.MultiTenancy 
    @using Volo.Abp.MultiTenancy 
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Themes.LeptonX.Components.Common.PageAlerts 
    @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Themes.LeptonX.Components.SideMenu.Toolbar.LanguageSwitch 
    @using Microsoft.AspNetCore.Http.Extensions 
    @using Volo.Abp.Ui.LayoutHooks 
    @inject IAbpAntiForgeryManager AbpAntiForgeryManager 
    @inject IBrandingProvider BrandingProvider 
    @inject LeptonXStyleProvider LeptonXStyleProvider 
    @inject IStringLocalizer<AbpUiMultiTenancyResource> MultiTenancyStringLocalizer 
    @inject IStringLocalizer<LeptonXResource> L 
    @inject ITenantResolveResultAccessor TenantResolveResultAccessor 
    @inject IOptions<AbpMultiTenancyOptions> MultiTenancyOptions 
    @inject ICurrentTenant CurrentTenant 
    @inject ThemeLanguageInfoProvider ThemeLanguageInfoProvider 
    @inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout 
     
    @{ 
        AbpAntiForgeryManager.SetCookie(); 
        var langDir = CultureHelper.IsRtl ? "rtl" : string.Empty; 
        var title = $"{ViewBag.Title ?? PageLayout.Content.Title} | {BrandingProvider.AppName}".Trim('|', ' '); 
     
     
        var languageInfo = await ThemeLanguageInfoProvider.GetLanguageSwitchViewComponentModel(); 
        var returnUrl = System.Net.WebUtility.UrlEncode(Context.Request.GetEncodedPathAndQuery()); 
     
        var logoUrl = BrandingProvider.LogoUrl == null ? null : "--lpx-logo: url(" + BrandingProvider.LogoUrl + ");"; 
        var logoReverseUrl = BrandingProvider.LogoReverseUrl == null ? null : "--lpx-logo: url(" + BrandingProvider.LogoReverseUrl + ");"; 
        var selectedStyle = await LeptonXStyleProvider.GetSelectedStyleAsync(); 
     
        var selectedStyleFileName = CultureHelper.IsRtl ? selectedStyle + ".rtl" : selectedStyle; 
    } 
    <!DOCTYPE html> 
    <html lang="@CultureInfo.CurrentCulture.Name" dir="@langDir"> 
     
    <head> 
     
        @await Component.InvokeLayoutHookAsync(LayoutHooks.Head.First, StandardLayouts.Account) 
     
        <title>@title</title> 
     
        <meta name="viewport" content="width=device-width,initial-scale=1.0" /> 
        <meta charset="UTF-8" /> 
        <meta name="description" content="@ViewBag.MetaDescription"> 
     
        <link rel="icon" href="~/favicon.svg" type="image/svg+xml"> 
     
        <abp-style-bundle name="@LeptonXThemeBundles.Styles.Global" /> 
     
        <link href="~/Themes/LeptonX/Global/side-menu/css/bootstrap-@(selectedStyleFileName).css" type="text/css" 
              rel="stylesheet" id="lpx-theme-bootstrap-@selectedStyle" /> 
        <link href="~/Themes/LeptonX/Global/side-menu/css/@(selectedStyleFileName).css" type="text/css" rel="stylesheet" 
              id="lpx-theme-color-@selectedStyle" /> 
     
        @await Component.InvokeAsync(typeof(WidgetStylesViewComponent)) 
        @await RenderSectionAsync("styles", false) 
        @await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Account) 
     
        <style> 
            .lpx-login-bg { 
                background-image: url('/LeptonX/images/login-pages/login-bg-img-@(selectedStyle).svg') !important; 
            } 
     
            :root .lpx-theme-light { 
                @logoUrl 
            } 
            :root .lpx-theme-dark { 
                @logoReverseUrl 
            } 
     
            :root .lpx-theme-dim { 
                @logoReverseUrl 
            } 
        </style> 
    </head> 
     
    <body class="abp-account-layout lpx-theme-@selectedStyle"> 
     
        @await Component.InvokeLayoutHookAsync(LayoutHooks.Body.First, StandardLayouts.Account) 
     
     
        <div class="container-fluid p-0 overflow-hidden"> 
            @await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Account) 
            <div class="lpx-login-area"> 
                <div class="lpx-login-bg"> 
                    <div class="d-flex flex-column justify-content-center min-vh-100"> 
     
                        <div class="row"> 
                            <div class="col-xxl-5 col-lg-7 col-md-8 col-11 mx-auto position-relative py-4"> 
     
                                @if (BrandingProvider.LogoUrl.IsNullOrEmpty()) 
                                { 
                                    <div class="lpx-logo-container lpx-login-brand-text"> 
                                        <div class="lpx-brand-logo lpx-login-logo mx-auto"></div>  
                                        <div class="lpx-brand-name lpx-login-name mx-auto">@BrandingProvider.AppName</div>  
                                    </div> 
                                } 
                                else 
                                { 
                                    <div class="lpx-brand-logo lpx-login-logo mb-3 mx-auto"></div> 
                                } 
     
     
                                <div class="card mx-auto" style="max-width: 30rem;"> 
                                    <div class="card-body p-3 p-sm-4"> 
                                        <div class="align-items-start d-flex justify-content-between mb-2"> 
                                            <h2 class="lpx-main-title lpx-login-title m-0 me-auto"> @PageLayout.Content.Title @* TODO: Find a better text here. *@</h2> 
                                            <div class="dropdown btn-group ms-auto" aria-labelledby="languageDropdown"> 
     
                                                <button class="btn btn-sm btn-light dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> 
                                                    <i class="bi bi-translate me-1"></i> @languageInfo.CurrentLanguage.DisplayName 
                                                </button> 
     
                                                <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenuButton1" style=""> 
                                                    @foreach (var language in languageInfo.Languages) 
                                                    { 
                                                        var twoLetterLanguageName = new CultureInfo(language.CultureName).TwoLetterISOLanguageName.ToUpperInvariant(); 
                                                        var url = Url.Content($"~/Abp/Languages/Switch?culture={language.CultureName}&uiCulture={language.UiCultureName}&returnUrl={returnUrl}"); 
                                                        <li> 
                                                            <a href="@url" class="dropdown-item" data-lpx-language-option="@twoLetterLanguageName">@language.DisplayName / @twoLetterLanguageName</a> 
                                                        </li> 
                                                    } 
                                                </ul> 
                                            </div> 
                                        </div> 
     
                                        <hr /> 
     
                                        @await Component.InvokeAsync(typeof(PageAlertsViewComponent)) 
     
                                        @if (MultiTenancyOptions.Value.IsEnabled && 
                                        (TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(CookieTenantResolveContributor.ContributorName) 
                                        == true || 
                                        TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(QueryStringTenantResolveContributor.ContributorName) 
                                        == true)) 
                                        { 
                                            <div> 
                                                <div class="row"> 
                                                    <div class="col"> 
                                                        <span style="font-size: .8em;" 
                                                              class="text-uppercase text-muted">@MultiTenancyStringLocalizer["Tenant"]</span><br /> 
                                                        <h6 class="m-0 d-inline-block"> 
                                                            @if (CurrentTenant.Id == null) 
                                                            { 
                                                                <span> 
                                                                    @MultiTenancyStringLocalizer["NotSelected"] 
                                                                </span> 
                                                            } 
                                                            else 
                                                            { 
                                                                <strong> 
                                                                    @(CurrentTenant.Name ?? 
                                                                        CurrentTenant.Id.Value.ToString()) 
                                                                </strong> 
                                                            } 
                                                        </h6> 
                                                    </div> 
                                                    <div class="col-auto"> 
                                                        <a id="AbpTenantSwitchLink" href="#" 
                                                           class="btn btn-sm btn-outline-primary">@MultiTenancyStringLocalizer["Switch"]</a> 
                                                    </div> 
                                                </div> 
                                            </div> 
                                            <hr /> 
     
                                        } 
     
                                        @RenderBody() 
     
                                    </div> 
                                    @* @await Html.PartialAsync("~/Themes/LeptonX/Layouts/Account/_Footer.cshtml") *@ 
                                </div> 
                            </div> 
                        </div> 
                    </div> 
                </div> 
            </div> 
     
            @await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Account) 
        </div> 
     
        <abp-script-bundle name="@LeptonXThemeBundles.Scripts.Global" /> 
        <abp-script src="~/Abp/ApplicationLocalizationScript?cultureName=@CultureInfo.CurrentUICulture.Name"/> 
        <abp-script src="~/Abp/ApplicationConfigurationScript"/> 
        <abp-script src="~/Abp/ServiceProxyScript"/> 
        @await Component.InvokeAsync(typeof(WidgetScriptsViewComponent)) 
        @await RenderSectionAsync("scripts", false) 
        @await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Account) 
    </body> 
     
    </html> 
    

    When we try the existing code, language switch and tenant switch do not work Version:7.4.2

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Can you check if abp-script tags are colored (Tag helpers are imported)

    If not, you can crate a_ViewImports.cshtml file in the same folder with following imports:

    @using System.Globalization
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    @addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
    @addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling
    

    _(Or you can add them into the same file, but creating ViewImports is suggested.)

  • User Avatar
    0
    user5.abpio created

    HttpApi.Host Project current the image. "_ViewImports.cshtml" Does not exist

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Yes, you need to add view imports to work that cshtml file work properly. Then, you'll be overridden the default logic page, you can make any changes according to LeptonX HTML demo

  • User Avatar
    0
    ageiter created

    @enisn: I think because user5.abpio was also asking questions, you overlooked my questions and comments. Could you please answer them as well? Thanks!

    Thanks for the code. Is it possible to download the different layouts somewhere? We want layout 3 and not layout 2 and we are not sure yet whether TopMenu / SideMenu (although this does not matter on the login page).

    It seems that these layouts are not included in the module "Volo.Abp.LeptonXTheme.Pro", right?

    In general, it would of course be cool if we could get the source code of the demo page https://x.leptontheme.com/ (also for other pages that are nicely designed).

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Of course, you can download the source code.

    https://docs.abp.io/en/commercial/latest/themes/lepton-x/index#source-code

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11