Skip to content

Instantly share code, notes, and snippets.

@ebicoglu
Last active July 20, 2021 01:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ebicoglu/bb28666a892646b245b2a525d5760bb7 to your computer and use it in GitHub Desktop.
Save ebicoglu/bb28666a892646b245b2a525d5760bb7 to your computer and use it in GitHub Desktop.
Customizing ABP Commercial register page (MVC)
@using Microsoft.Extensions.Localization
@using Microsoft.Extensions.Options
@using Volo.Abp.AspNetCore.MultiTenancy
@using Volo.Abp.AspNetCore.Mvc.AntiForgery
@using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton.Bundling
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton.Themes.Lepton.Components.Content.Alerts
@using Volo.Abp.Ui.Branding
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton.Themes.Lepton.Components.Header.Brand
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton.Themes.Lepton.Components.Toolbar.LanguageSwitch
@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.MultiTenancy
@inject IAbpAntiForgeryManager AbpAntiForgeryManager
@inject IBrandingProvider BrandingProvider
@inject IPageLayout PageLayout
@inject IOptions<AbpMultiTenancyOptions> MultiTenancyOptions
@inject IOptions<AbpLocalizationOptions> LocalizationOptions
@inject ICurrentTenant CurrentTenant
@inject IStringLocalizer<AbpUiMultiTenancyResource> MultiTenancyStringLocalizer
@inject ITenantResolveResultAccessor TenantResolveResultAccessor
@{ Layout = null;
AbpAntiForgeryManager.SetCookie();
var containerClass = ViewBag.FluidLayout == true ? "container-fluid" : "container"; //TODO: Better and type-safe options
var logoUrl = BrandingProvider.LogoUrl == null ? null : "--logo: url(" + BrandingProvider.LogoUrl + ") !important;";
var logoReverseUrl = BrandingProvider.LogoReverseUrl == null ? null : "--logo-reverse: url(" + BrandingProvider.LogoReverseUrl + ") !important;";
var langDir = CultureHelper.IsRtl ? "rtl" : string.Empty; }
<!DOCTYPE html>
<html lang="@CultureInfo.CurrentCulture.Name" dir="@langDir">
<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">
<meta name="description" content="@ViewBag.MetaDescription">
<link rel="apple-touch-icon" sizes="180x180" href="~/images/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="~/images/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="~/images/favicon/favicon-16x16.png">
<link rel="manifest" href="~/images/favicon/site.webmanifest">
<link rel="mask-icon" href="~/images/favicon/safari-pinned-tab.svg" color="#5bbad5">
<title>@(ViewBag.Title == null ? BrandingProvider.AppName : ViewBag.Title)</title>
<abp-style-bundle name="@LeptonThemeBundles.Styles.Global" />
@* TODO: We can continue with this until find a better way *@
@if (logoUrl != null || logoReverseUrl != null)
{
<style>
:root {
@logoUrl
@logoReverseUrl
}
.card {
background: #55535f;
color: #ffffff;
border-radius: 250px;
padding: 50px;
min-width: 500px;
text-align: center;
}
body {
background-color: #9B9B9B;
text-align: center;
background-image: url('https://placeimg.com/640/480/tech/grayscale');
}
</style>
}
@await Component.InvokeAsync(typeof(WidgetStylesViewComponent))
@await RenderSectionAsync("styles", false)
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Account)
</head>
<body class="abp-account-layout @langDir">
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.First, StandardLayouts.Account)
<div class="account-header fixed-top p-3">
</div>
<div class="d-flex align-items-center" style="min-height: 100vh;">
<div style="margin-left: 35%;">
<abp-row>
<abp-column class="col mx-auto">
<div class="account-brand p-4 text-center mb-1">
@(await Component.InvokeAsync<HeaderBrandViewComponent>())
</div>
<div class="card">
<div class="card-header">
<h2 class="card-title d-inline-block">@PageLayout.Content.Title</h2>
@if (LocalizationOptions.Value.Languages.Count > 1)
{
<nav class="navbar navbar-expand p-0 pt-1 float-right">
<ul class="navbar-nav ml-auto toolbar-nav">
<li class="nav-item">
@(await Component.InvokeAsync<LanguageSwitchViewComponent>())
</li>
</ul>
</nav>}
</div>
@if (MultiTenancyOptions.Value.IsEnabled &&
(TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(CookieTenantResolveContributor.ContributorName) == true))
{
<div class="card-header bg-light">
<div class="tenant-switch-box">
<div class="row">
<div class="col pr-1">
<h6 class="m-0">
@MultiTenancyStringLocalizer["Tenant"]
</h6>
@if (CurrentTenant.Id == null)
{
<i class="text-muted">@MultiTenancyStringLocalizer["NotSelected"]</i> }
else
{
<span> Your tenant name <strong>@(CurrentTenant.Name ?? CurrentTenant.Id.Value.ToString())</strong></span>}
</div>
<div class="col-auto pl-1">
<a id="AbpTenantSwitchLink" style="cursor: pointer" href="javascript:;" class="btn btn-sm btn-outline-primary float-right">@MultiTenancyStringLocalizer["Switch"]</a>
</div>
</div>
</div>
</div>}
<div class="card-body">
@(await Component.InvokeAsync<ContentAlertsViewComponent>())
@RenderBody()
</div>
</div>
<div class="p-1 text-center text-muted">
@await Html.PartialAsync("~/Themes/Lepton/Layouts/Account/_Footer.cshtml")
</div>
</abp-column>
</abp-row>
</div>
</div>
<abp-script-bundle name="@LeptonThemeBundles.Scripts.Global" />
<script type="text/javascript" src="~/Abp/ApplicationConfigurationScript"></script>
<script type="text/javascript" src="~/Abp/ServiceProxyScript"></script>
@await Component.InvokeAsync(typeof(WidgetScriptsViewComponent))
@await RenderSectionAsync("scripts", false)
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Account)
</body>
</html>
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.Account.Localization
@using Volo.Abp.Account.Public.Web.Security.Recaptcha
@using Volo.Abp.Account.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);
}
@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)})" />
}
<abp-button button-type="Primary" size="Block" type="submit" class="mt-2 mb-3">@L["Register"]</abp-button>
@L["AlreadyRegistered"] <a href="@Url.Page("./Login", new {returnUrl = Model.ReturnUrl, returnUrlHash = Model.ReturnUrlHash})">@L["Login"]</a>
</form>
<div class="mt-3">
<hr />
<p class="font-weight-light">
<small>By clicking Register button, you agree to our <a href="/Account/TermsConditions">Terms & Conditions</a> and <a href="#">Privacy Policy</a>.</small>
</p>
</div>
</div>
@ebicoglu
Copy link
Author

image

@ebicoglu
Copy link
Author

ebicoglu commented May 25, 2021

1- Copy the Register.cshtml to Pages > Account folder of your web project.
2- Copy the Default.cshtml to Themes > Lepton > Layouts > Account folder of your web project.

image

@sturlath
Copy link

sturlath commented Jul 16, 2021

I got here from this support ticket but following this code I´m getting the following errors and un-styled UI.

I have been unable to find the cause of this and have nothing to go on with... the only other similar issue I found was this one with no resolution.

Btw I'm using the source code for Volo.Account.Pro module (I haven´t changed it yet so its 100% the same)

Any ideas?

image

Uncaught ReferenceError: $ is not defined in ApplicationConfigurationScript
and
Uncaught ReferenceError: abp is not defined in ServiceProxyScript

image
and
image

For the record I have successfully customised the login page by following this guide and reading the docs

My setup:
Version 4.3.2
Blazor
EFCore
Separate Identity Server (so this code is in there)

p.s
My goal is removing the "tenant-switch-box" from both the register and login window (but for now no change in your code)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment