You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
9.3 KiB
277 lines
9.3 KiB
---
|
|
sidebar_position: 2
|
|
title: Page creation
|
|
---
|
|
|
|
## Creation of a new page
|
|
|
|
In order to display your data, we will create a new page.
|
|
|
|
To do this, nothing could be simpler, select the `Pages` folder then right click and select `Add > Razor Component...`
|
|
|
|

|
|
|
|
We will name our page `List.razor` then click on `Add`
|
|
|
|

|
|
|
|
## Separation View & Model
|
|
|
|
In order to separate the View and Model part, we will therefore create a partial class for our view.
|
|
|
|
Select the `Pages` folder then right click and select `Add > Class...`
|
|
|
|

|
|
|
|
We will name our class `List.razor.cs` then click on `Add`
|
|
|
|

|
|
|
|
Remember to make your class partial with the `partial` keyword as follows:
|
|
|
|
```csharp title="Pages/List.razor.cs"
|
|
public partial class List
|
|
{
|
|
}
|
|
```
|
|
|
|
You can now remove the code from your view, for that remove the following part:
|
|
|
|
```cshtml title="Pages/List.razor"
|
|
<h3>List</h3>
|
|
|
|
// highlight-start
|
|
@code {
|
|
|
|
}
|
|
// highlight-end
|
|
```
|
|
|
|
## Declare the url of our new page
|
|
|
|
In order to make our page accessible, let's declare the url of our page as follows:
|
|
|
|
```cshtml title="Pages/List.razor"
|
|
// highlight-next-line
|
|
@page "/list"
|
|
|
|
<h3>List</h3>
|
|
```
|
|
|
|
From now on our page will be available from the `/list` address of our site.
|
|
|
|
## Add our new page to the menu
|
|
|
|
Open the `Shared/NavMenu.razor` file and add the highlighted lines:
|
|
|
|
```cshtml title="Shared/NavMenu.razor"
|
|
<div class="top-row ps-3 navbar navbar-dark">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand" href="">TO_DELETE_BlazorApp30000</a>
|
|
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
|
|
<nav class="flex-column">
|
|
// highlight-start
|
|
<div class="nav-item px-3">
|
|
<NavLink class="nav-link" href="list" Match="NavLinkMatch.All">
|
|
<span class="oi oi-list-rich" aria-hidden="true"></span> List
|
|
</NavLink>
|
|
</div>
|
|
// highlight-end
|
|
<div class="nav-item px-3">
|
|
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
|
<span class="oi oi-home" aria-hidden="true"></span> Home
|
|
</NavLink>
|
|
</div>
|
|
<div class="nav-item px-3">
|
|
<NavLink class="nav-link" href="counter">
|
|
<span class="oi oi-plus" aria-hidden="true"></span> Counter
|
|
</NavLink>
|
|
</div>
|
|
<div class="nav-item px-3">
|
|
<NavLink class="nav-link" href="fetchdata">
|
|
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
|
|
</NavLink>
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
|
|
@code {
|
|
private bool collapseNavMenu = true;
|
|
|
|
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
|
|
|
private void ToggleNavMenu()
|
|
{
|
|
collapseNavMenu = !collapseNavMenu;
|
|
}
|
|
}
|
|
```
|
|
|
|
You can now navigate to your new page.
|
|
|
|
## Concept: Layout
|
|
|
|
Some app elements, such as menus, copyright messages, and company logos, are usually part of the overall app layout.
|
|
Placing a copy of the markup for these elements in all components of an application is not efficient.
|
|
Whenever one of these elements is updated, every component that uses the element must be updated.
|
|
This approach is expensive to maintain and can lead to inconsistent content if an update is missed.
|
|
|
|
Layouts solve these problems.
|
|
|
|
### Create a layout
|
|
|
|
To create a layout:
|
|
|
|
* Create a new Razor component. Layouts use the `.razor` extension like regular Razor components. Since layouts are shared between components of an application, they are usually placed in the `Shared` application folder. However, layouts can be placed anywhere accessible to components that use it.
|
|
* Inherits the component from `LayoutComponentBase`, it defines a `Body` property (type `RenderFragment`) so that the content is rendered inside the layout.
|
|
* Use the Razor `@Body` syntax to specify the location in the layout tag where the content is displayed.
|
|
* The following `DoctorWhoLayout` layout shows a sample layout. The layout inherits from `LayoutComponentBase` and defines the `@Body` between the navbar ( <nav>...</nav> ) and the footer ( <footer>...</footer> ; ).
|
|
|
|
```cshtml title="Shared/DoctorWhoLayout.razor"
|
|
// highlight-next-line
|
|
@inherits LayoutComponentBase
|
|
|
|
<header>
|
|
<h1>Doctor Who™ Episode Database</h1>
|
|
</header>
|
|
|
|
<nav>
|
|
<a href="masterlist">Master Episode List</a>
|
|
<a href="search">Search</a>
|
|
<a href="new">Add Episode</a>
|
|
</nav>
|
|
|
|
// highlight-next-line
|
|
@Body
|
|
|
|
<footer>
|
|
@TrademarkMessage
|
|
</footer>
|
|
|
|
@code {
|
|
public string TrademarkMessage { get; set; } =
|
|
"Doctor Who is a registered trademark of the BBC. " +
|
|
"https://www.doctorwho.tv/";
|
|
}
|
|
```
|
|
|
|
### Apply a layout
|
|
|
|
Use the Razor `@layout` directive to apply a layout to a Razor routable component that has an `@page` directive.
|
|
The compiler converts `@layout` to a `LayoutAttribute` and applies the attribute to the component class.
|
|
|
|
The content of the next `Episodes` page is inserted into the `DoctorWhoLayout` at the position of `@Body`.
|
|
|
|
```cshtml title="Pages/Episodes.razor"
|
|
@page "/episodes"
|
|
// highlight-next-line
|
|
@layout DoctorWhoLayout
|
|
|
|
<h2>Episodes</h2>
|
|
|
|
<ul>
|
|
<li>
|
|
<a href="https://www.bbc.co.uk/programmes/p00vfknq">
|
|
<em>The Ribos Operation</em>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="https://www.bbc.co.uk/programmes/p00vfdsb">
|
|
<em>The Sun Makers</em>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="https://www.bbc.co.uk/programmes/p00vhc26">
|
|
<em>Nightmare of Eden</em>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
```
|
|
|
|
The following rendered HTML markup is produced by the `DoctorWhoLayout` layout and the `Episodes` page. Superfluous markup does not appear in order to focus on the content provided by the two components involved:
|
|
|
|
* The Doctor Who episode database ™ header ( <h1>...</h1> ) of the header ( <header>...</header> ), of the navigation bar ( <nav>...</nav> ) and the trademark information element ( <div>...</div> ) of the footer ( < footer>...</footer> ) comes from the `DoctorWhoLayout` component.
|
|
* The episodes header ( <h2>...</h2> ) and episode list ( <ul>...</ul> ) come from the `Episodes` page.
|
|
|
|
```cshtml
|
|
<body>
|
|
<div id="app">
|
|
<header>
|
|
<h1>Doctor Who™ Episode Database</h1>
|
|
</header>
|
|
|
|
<nav>
|
|
<a href="main-list">Main Episode List</a>
|
|
<a href="search">Search</a>
|
|
<a href="new">Add Episode</a>
|
|
</nav>
|
|
|
|
<h2>Episodes</h2>
|
|
|
|
<ul>
|
|
<li>...</li>
|
|
<li>...</li>
|
|
<li>...</li>
|
|
</ul>
|
|
|
|
<footer>
|
|
Doctor Who is a registered trademark of the BBC.
|
|
https://www.doctorwho.tv/
|
|
</footer>
|
|
</div>
|
|
</body>
|
|
```
|
|
|
|
### Apply a layout to a component folder
|
|
|
|
Each application folder can optionally contain a template file named `_Imports.razor`.
|
|
The compiler includes the directives specified in the `Imports` file in all Razor templates in the same folder and recursively in all its subfolders.
|
|
Therefore, a `_Imports.razor` file containing `@layout DoctorWhoLayout` ensures that all components in a folder use the `DoctorWhoLayout` layout.
|
|
There is no need to repeatedly add `@layout DoctorWhoLayout` to all Razor Components ( .razor ) in the folder and subfolders.
|
|
|
|
:::caution
|
|
Do not add a Razor `@layout` directive to the root `_Imports.razor` file, which results in an infinite layout loop.
|
|
To control the default application layout, specify the layout in the `Router` component.
|
|
:::
|
|
|
|
:::note
|
|
The Razor `@layout` directive only applies a layout to routable components with a `@page` directive.
|
|
:::
|
|
|
|
Example :
|
|
|
|
My application contains its pages in the `Pages` folder, I want to add an administration part to my application so I will create an `Admin` directory in the `Pages` folder:
|
|
|
|

|
|
|
|
I created a layout for my admin part located `Shared/AdminLayout.razor` and I want my admin pages to use it, two choices:
|
|
* Add at the top of each page `@layout AdminLayout`
|
|
* This choice is not the most relevant because in the event of a change of layout, you will have to go back to all the pages
|
|
* Create a `_Imports.razor` file and specify `@layout AdminLayout`, all pages in my `Admin` folder will now use this layout.
|
|
|
|
### Apply a default layout to an app
|
|
|
|
Specify the default application layout in the `App` component of the `Router` component.
|
|
The following example from an app based on a Blazor project template sets the default layout to the `MainLayout` layout.
|
|
|
|
```cshtml title="App.razor"
|
|
<Router AppAssembly="@typeof(Program).Assembly">
|
|
<Found Context="routeData">
|
|
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
|
</Found>
|
|
<NotFound>
|
|
<p>Sorry, there's nothing at this address.</p>
|
|
</NotFound>
|
|
</Router>
|
|
```
|
|
|
|
### Nested Layouts
|
|
|
|
A component can refer to a layout which, in turn, refers to another layout. For example, nested layouts are used to create multilevel menu structures.
|