Create an admin page

Updated at 1709786834000
Create an admin page

Ezyplatform admin utilizes bootstrap 4, but you can use any CSS framework as long as it doesn't conflict with bootstrap 4. Additionally, ezyplatform admin has already integrated Font awesome version 5 and Ionicons v2.

To create an admin page, you'll need to follow these steps:

  1. Create a Thymeleaf template.
  2. Create a controller.

Create a Thymeleaf template

A template will be decorated by the ezyadmin template. You can find the detailed content of the ezyadmin template at ezyplatform/admin/resources/templates/ezyadmin.html. Suppose we need to create an admin screen to display a list of books. We can create the template file book-store-admin-plugin/resources/templates/book-store/book/list as follows:

<!DOCTYPE html>
<html
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:th="http://www.thymeleaf.org"
  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
  layout:decorate="~{ezyadmin}">
<head>
	<script>
		const bookStore = {};
	</script>
</head>
<body>
<div layout:fragment="content" class="row">
  <-- content -->
</div>
<th:block layout:fragment="modals">
  <th:block th:replace="~{fragments/prompt :: content(id='delete-book-modal', title=confirm, confirmButton=delete, closeButton=close)}" ></th:block>
</th:block>
<script layout:fragment="scripts" th:inline="javascript">
/*<![CDATA[*/
ezyadmin.messages.book_deleted = /*[[#{book_deleted}]]*/;
bookStore.bookSearchKeyword = /*[[${bookSearchKeyword}]]*/;
/*]]>*/


// javascript source code here

</script>
<script layout:fragment="final-scripts">

// javascript source code here

</script>
</body>
</html>

There is some important information in this template:

  1. This template is decorated by ezyadmin with the declaration layout:decorate="~{ezyadmin}".
  2. We need to declare a JavaScript variable bookStore to later assign properties and functions to it to avoid duplication with other plugins, such as bookStore.propertyA, bookStore.functionA = function() {}.
  3. The content inside the <div layout:fragment="content" class="row"> tag will be replaced for the <div layout:fragment="content"></div> tag of ezyadmin.html.
  4. <th:block th:replace="~{fragments/prompt :: content(id='delete-book-modal', title=confirm, confirmButton=delete, closeButton=close)}" ></th:block> will create HTML code for a delete confirmation popup.
  5. The content inside the <th:block layout:fragment="modals"> tag will be replaced for the <th:block th:replace="~{media/modal :: content}" ></th:block> tag of ezyadmin.html.
  6. The content inside the <script layout:fragment="scripts" tag will be replaced for the <script layout:fragment="scripts" type="text/javascript"></script>.
  7. th:inline="javascript" tells Thymeleaf to assign values to variables during HTML rendering.
  8. ezyadmin.messages.book_deleted = /*[[#{book_deleted}]]*/; will assign the value of the book_deleted message to the variable ezyadmin.messages.book_deleted.
  9. bookStore.bookSearchKeyword = /*[[${bookSearchKeyword}]]*/; will assign the value of the bookSearchKeyword variable to the bookStore.bookSearchKeyword variable.
  10. The content of the <script layout:fragment="final-scripts"> tag will be replaced for the <script layout:fragment="final-scripts" type="text/javascript"></script> tag of ezyadmin.html.

Create a controller

You can create a controller named AdminBookController in book-store-admin-plugin/src/main/java under the package org.youngmonkeys.bookstore.admin.controller.view.

@Authenticated
@Controller
public class AdminBookController {

    @DoGet("/books")
    public View booksGet(
        @RequestParam("keyword") String keyword
    ) {
        return View.builder()
            .addVariable("bookSearchKeyword", keyword)
            .template("book-store/book/list")
            .build();
    }
}

There is some important information in this controller:

  1. Annotation @Authenticated: Indicates that the administrator must log in before accessing screens created by the controller.
  2. Although we declare the URI as @DoGet("/books"), the URI will actually be supplemented with the name of the plugin, for example, in this case, it will be book-store, and the full URI

Example source code

You can take a look here