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.
@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>
@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>
}
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.
It should be fixed, can you try it again?
Hi @berly, thanks for reporting. I'll check and write you back asap.
Hi, you can define the icon when defining a new menu item like below:
context.Menu.AddItem(
new ApplicationMenuItem("MyProject.Crm", l["Menu:CRM"])
.AddItem(new ApplicationMenuItem(
name: "Name",
displayName: "Display",
url: "/crm/my-url",
icon: "fa fa-tag" //define your Font Awesome icon here.
)
));
Hi @shijo, thanks for reporting the problem. We are aware of this problem and will fix it asap. I'll inform you when it's resolved. Btw, your credit is refunded.
what if I wanted to do my changes at server side not JavaScript?
The same is also valid for razor pages and etc.. You only need to create a new razor page/class on the same path and change by your needs.
Please check the https://docs.abp.io/en/abp/5.3/UI/AspNetCore/Customization-User-Interface?_ga=2.135766769.1926299507.1654164050-344190752.1654164050#overriding-a-page .
Hi, it seems there are some problems with debugging in Visual Studio for Blazor applications. (as you've faced, "children could not be evaluated" etc.)
This problem is related to Visual Studio rather than ABP Framework. I found a thread that you can follow and apply suggestions that have been made. So please check this thread.
To use the Buttons extension from DataTable, you need to add some additional js files to your application.
Alternatively, you can use the download builder of Datatables (https://datatables.net/download/) to ensure install all related packages.
Then you can use it like you mentioned:
$(document).ready(function() {
$('#example').DataTable( {
dom: 'Bfrtip',
buttons: [
'copyHtml5',
'excelHtml5',
'csvHtml5',
'pdfHtml5'
]
} );
} );
It's not fully related with ABP Framework, you can follow the documentation of Datatables (Buttons Extension) and make the necessary configurations (you need to add the above js files to your project) to make it work.
Hi, you can override it by creating an Index.js file in the same directory of the module file (/Pages/Identity/Users/index.js) and copy the module content to that newly created file and make your changes.
(function ($) {
var l = abp.localization.getResource('AbpIdentity');
//...
abp.ui.extensions.tableColumns.get("identity.user").addContributor(
function (columnList) {
columnList.addManyTail(
[
{
title: l('Actions'),
rowAction: {
items: abp.ui.extensions.entityActions.get("identity.user").actions.toArray()
}
},
//other fields
{
title: l('CreationTime'),
data: "creationTime",
dataFormat: "datetime" //change data format by your needs
},
]
);
},
0 //adds as the first contributor
);
//...
})(jQuery);
Please see the following resources for more: