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.

9.3 KiB

sidebar_position title
2 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...

Creation of a new page

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

Creation of a new page

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...

Separation View & Model

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

Separation View & Model

Remember to make your class partial with the partial keyword as follows:

public partial class List
{
}

You can now remove the code from your view, for that remove the following part:

<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:

// 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:

<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> ; ).
// highlight-next-line
@inherits LayoutComponentBase

<header>
    <h1>Doctor Who&trade; 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.

@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.
<body>
    <div id="app">
        <header>
            <h1>Doctor Who&trade; 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:

Apply a layout to a component 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.

<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.