Tiếp nối bài trước: “Tạo giao diện cho theme EzyPlatform blog đơn giản”.

Mục tiêu

Hoàn thành các mục sau:

  • Trang Home đang hiển thị html tĩnh → chuyển sang lấy dữ liệu động từ CSDL (bài viết đã xuất bản, loại blog).
  • Có phân trang, có đa ngôn ngữ theo request hoặc mặc định.
  • Hiển thị ngày tháng từ timestamp.

1. Liên kết plugin EzyArticle vào dự án theme Personal

Để có thể lấy dữ liệu đông của các bài viết, chúng ta sẽ cần liên kết theme Personal với plugin EzyArticle. Chúng ta sẽ cần chạy câu lệnh sau:

ezy.sh link ezyarticle

Về bản chất nó sẽ cập nhật tập tin pom.xml của các module để bổ sung phụ thuộc, ví dụ:

<dependency>
    <groupId>org.youngmonkeys</groupId>
    <artifactId>ezyarticle-sdk</artifactId>
    <version>${ezyarticle.version}</version>
    <scope>system</scope>
    <systemPath>
        ${ezyplatform.home}/web/plugins/ezyarticle/lib/ezyarticle-sdk-${ezyarticle.version}.jar
    </systemPath>
</dependency>

Ngoài ra nó bổ sung thêm package để scan vào các tập tin startup test, ví dụ:

@ComponentsScan({
    "org.youngmonkeys.ezyplatform",
    "org.youngmonkeys.personal",
    "org.youngmonkeys.ecommerce"
})
public class PersonalThemeStartupTest {
---

2. Tạo môt bài blog từ admin

  1. Mở Admin (sau khi restart).
  2. Vào Bài viếtTạo mới:
  • Tiêu đề: Ví dụ “Platform là gì?”
  • Ảnh đại diện (featured image): chọn một ảnh.
  • Nội dung: Bạn có thể nhập bất ký.
  • Loại bài viết: chọn blog.
  • Trạng thái: Xuất bản.
Lưu/Xuất bản.

3. Chuyển Home sang lấy dữ liệu động

3.1 Cập nhật HomeController

Bạn có thể bổ sung các phụ thuộc và cài đặt chi tiết cho lớp này như sau:

@Setter
@Controller
public class HomeController {

    @EzyAutoBind
    private WebLanguageControllerService languageControllerService;

    @EzyAutoBind
    private WebPostControllerService postControllerService;

    @EzyAutoBind
    private WebCommonValidator commonValidator;

    @DoGet("/")
    public View home(
        HttpServletRequest request,
        @RequestParam(value = "sortOrder") String sortOrder,
        @RequestParam(value = "nextPageToken") String nextPageToken,
        @RequestParam(value = "prevPageToken") String prevPageToken,
        @RequestParam(value = "lastPage") boolean lastPage,
        @RequestParam(value = "limit", defaultValue = "12") int limit
    ) {
        commonValidator.validatePageSize(limit);
        DefaultPostFilter filter = DefaultPostFilter
            .builder()
            .postType(PostType.BLOG.toString())
            .postStatus(PostStatus.PUBLISHED.toString())
            .build();
        String language = languageControllerService
            .getLanguageCodeOrDefault(request);
        PaginationModel<WebPostItemResponse> pagination = postControllerService
            .getPostItemPagination(
                filter,
                language,
                sortOrder,
                nextPageToken,
                prevPageToken,
                lastPage,
                limit
            );
        return View.builder()
            .template("home")
            .addVariable("pagination", pagination)
            .build();
}

Ở đây chúng ta sẽ lấy ra một trang dữ liệu blog và truyền cho template. Điều này sẽ khiến dữ liệu blog sẽ được gen ra html và trả về trình duyệt, điều này sẽ tốt cho SEO.


3.2 Sửa home.html

Chúng ta sẽ dùng thuộc tính th:each để lặp qua danh sách các bài blog để gen ra html, đây là một trong những thuộc tính quan trọng và hay được dùng với thymeleaf:

<div class="blog">
    <h2 class="h2">Latest Blog Post</h2>
    <div class="blog-card-group">
        <th:block th:each="blog : ${pagination.items}">
            <th:block th:replace="~{fragments/blog-item :: content(blog=${blog})}"></th:block>
        </th:block>
    </div>
    <button class="btn load-more">Load More</button>
</div>

Khi bạn chạy PersonalThemeStartupTest và truy cập vào localhost:8080 bạn có thể thấy kết quả:

Screenshot 2025-10-11 at 15.35.54.png

4. Hiển thị ngày tháng từ timestamp

Hiện tại ngày tháng của bài blog được hiển thị dạng số, ví dụ 1717232273000 điều này không tốt với người dùng, chúng ta sẽ cần chuyển nó về dạng ngày tháng nhìn được.

Bạn chỉ cần bổ sung thêm thư viện moment.js là được:

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Và refresh lại trình duyệt, kết quả bạn nhận được sẽ là:

Screenshot 2025-10-11 at 15.36.07.png

Tài liệu liên quan