-
Notifications
You must be signed in to change notification settings - Fork 3
Global Configurations
- Customizing the Endpoint
- Customizing the Title
- Configuring Authorization
- Search
- View Site URL
- Grouping
- Customizing the UI
- Exclude All Entities and Include Specific Only
By default, NetForge Admin is running on /admin but you can configure to use your custom endpoint like this:
appBuilder.Services.AddNetForge(optionsBuilder =>
{
optionsBuilder.UseEndpoint("/manage");
...
});You can customize the header title like this:
appBuilder.Services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetHeaderTitle("title");
...
});And customize the HTML title like this:
appBuilder.Services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetHtmlTitle("title");
...
});You can customize the access policy by requiring specific Identity roles:
appBuilder.Services.AddNetForge(optionsBuilder =>
{
optionsBuilder.AddAccessRoles("Role1", "Role2", "Role3");
...
});Alternatively, you can use a custom function to perform authorization checks. Example:
appBuilder.Services.AddNetForge(optionsBuilder =>
{
optionsBuilder.ConfigureAuth(serviceProvider =>
{
// Allow all authenticated users to see the Admin Panel.
var httpContext = serviceProvider.GetRequiredService<IHttpContextAccessor>().HttpContext;
return Task.FromResult(httpContext?.User.Identity?.IsAuthenticated ?? false);
});
});You can read about search here.
Located in the top right corner of the admin panel is a "View Site" link, configurable to direct users to the website URL. The default URL is "/". You can customize this value using the Fluent API:
services.AddNetForge(optionsBuilder =>
{
optionsBuilder.ConfigureUrl("https://www.example.com/");
});Group rows of entities into categories and make it easier for users to navigate and understand the data presented.
You can override the default layout of the admin panel. To do this, create a new layout in your host project and specify its type in the configuration.
services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetCustomLayout(typeof(CustomLayout));
});Your custom layout should inherit from the AdminBaseLayout class.
The example of the custom component with navigation bar and footer:
@using MudBlazor
@inherits Saritasa.NetForge.Blazor.Shared.AdminBaseLayout
<MudThemeProvider />
<MudDialogProvider />
<MudSnackbarProvider />
<MudAppBar Color="Color.Primary" Elevation="4">
<MudText Typo="Typo.h6">My Application</MudText>
<MudSpacer />
<MudNavMenu>
<MudNavLink Href="/about">About</MudNavLink>
<MudNavLink Href="/contact">Contact</MudNavLink>
</MudNavMenu>
</MudAppBar>
@Body
<footer>
<MudPaper Class="pa-4" Elevation="4">
<MudText Typo="Typo.body2">My Application</MudText>
<MudSpacer />
<MudNavMenu>
<MudNavLink Href="/privacy">Privacy Policy</MudNavLink>
<MudNavLink Href="/terms">Terms of Service</MudNavLink>
</MudNavMenu>
</MudPaper>
</footer>You can inject custom meta tags or page title into the head tag of the admin panel.
services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetCustomHeadType(typeof(CustomHead));
});Example of injecting custom meta tags or a page title into the head tag of the admin panel.
@using Microsoft.AspNetCore.Components.Web
<PageTitle>This is the custom page title.</PageTitle>
<meta name="custom-meta" content="content-meta">Note: If you are using a Custom Layout, you must add the dynamic component into the custom layout:
@using Saritasa.NetForge.Domain.Entities.Options
@inject AdminOptions AdminOptions;
<HeadContent>
@if (AdminOptions.CustomHeadType is not null)
{
<DynamicComponent Type="AdminOptions.CustomHeadType" />
}
</HeadContent>Example:
@using MudBlazor
@using Saritasa.NetForge.Domain.Entities.Options
@using Microsoft.AspNetCore.Components.Web
@inherits Saritasa.NetForge.Blazor.Shared.AdminBaseLayout
@inject AdminOptions AdminOptions;
<HeadContent>
@if (AdminOptions.CustomHeadType is not null)
{
<DynamicComponent Type="AdminOptions.CustomHeadType" />
}
</HeadContent>
<MudThemeProvider />
<MudDialogProvider />
...
...You can add some content to the end of the body section of admin site. Static and interactive content can be added separately.
Static content will be rendered by your custom component type.
services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetStaticBodyComponentType(typeof(AdminFooterStatic));
});Interactive content can be built using RenderTreeBuilder.
Note that JavaScript script tags should not be here. If you need JavaScript then put it to the static content section.
But you can import JavaScript file in your component to use it, in this case you will not need script tag.
Like in JsCollocation2 example here.
services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetInteractiveBodyContent(builder =>
{
builder.OpenComponent<AdminFooter>(0);
builder.AddAttribute(1, nameof(AdminFooter.VisitorsCount), 1234);
builder.CloseComponent();
})
});To use CSS in custom body sections you should add it to Custom Head Section. Also, you can use scoped CSS, in this case you should add bundled styles according to this. For example:
<link href="Saritasa.NetForge.Demo.styles.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">Before assigning entities to specific groups, users need to define the groups to which the entities will belong.
To create a new group, utilize the Fluent API through AdminOptionsBuilder. A name is required for each group, and a description is optional.
services.AddNetForge(optionsBuilder =>
{
optionsBuilder.UseEntityFramework(efOptionsBuilder =>
{
efOptionsBuilder.UseDbContext<ShopDbContext>();
}).AddGroups(new List<EntityGroup>
{
new EntityGroup{ Name = "Product", Description = "Contains all information related to products" },
new EntityGroup{ Name = "Shop"}
}).ConfigureEntity<Shop>(entityOptionsBuilder =>
{
entityOptionsBuilder.SetDescription("The base Shop entity.");
});
});By default, entities are assigned to the "empty" group. Grouping can be customized either through the Fluent API or by using attributes. When assigning entities to a group, users only need to specify the group's name. If user specifies a group that does not exists for an entity, that entity will belong to the default group.
Fluent API:
By utilizing EntityOptionsBuilder, user can set group for entity using group's name.
services.AddNetForge(optionsBuilder =>
{
optionsBuilder.UseEntityFramework(efOptionsBuilder =>
{
efOptionsBuilder.UseDbContext<ShopDbContext>();
}).AddGroups(new List<EntityGroup>
{
new EntityGroup{ Name = "Product", Description = "Contains all information related to products" },
new EntityGroup{ Name = "Shop"}
}).ConfigureEntity<Shop>(entityOptionsBuilder =>
{
entityOptionsBuilder.SetGroup("Shop");
entityOptionsBuilder.SetDescription("The base Shop entity.");
});
});Data Attribute:
[NetForgeEntity(GroupName = "Product")]
public class ProductTagYou can customize expanded header of all groups. By default, all groups are expanded.
services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetGroupHeadersExpanded(true);
});You can customize success messages on operations with entities. It can be customized on Global and Per-Model levels. Per-Model takes precedence on Global level.
services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetEntityCreateMessage("The entity was created.");
}); public void Configure(EntityOptionsBuilder<Address> entityOptionsBuilder)
{
entityOptionsBuilder.SetEntityCreateMessage("Address was created.");
}services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetEntitySaveMessage("Entity was saved.");
}); public void Configure(EntityOptionsBuilder<Address> entityOptionsBuilder)
{
entityOptionsBuilder.SetEntitySaveMessage("Address was saved.");
}services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetEntityDeleteMessage("The entity was deleted.");
}); public void Configure(EntityOptionsBuilder<Address> entityOptionsBuilder)
{
entityOptionsBuilder.SetEntityDeleteMessage("Address was deleted.");
}services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetEntityBulkDeleteMessage("The entities were deleted.");
}); public void Configure(EntityOptionsBuilder<Address> entityOptionsBuilder)
{
entityOptionsBuilder.SetEntityBulkDeleteMessage("Selected addresses were deleted.");
}You can exclude all entities and include only specific ones.
services.AddNetForge(optionsBuilder =>
{
optionsBuilder.SetIncludeAllEntities(false);
optionsBuilder.IncludeEntities(typeof(Shop), typeof(Product));
});Or you can include specific entities using the data attribute:
[NetForgeEntity]
public class Shop