Sau thanh điều hướng và phần hiển thị nội dung giới thiệu qua về trang web, thành phần tiếp theo mà chúng ta sẽ bổ sung vào trang chủ là phần hiển thị nội dung chính với các trích đoạn nội dung từ những bài viết mới nhất. Người dùng có thể đọc qua tiêu đề và những trích đoạn nội dung này để quyết định nhấn vào liên kết chuyển hướng tới trang đơn bài viết tương ứng.
Bổ sung component/main
Khu vực hiển thị nội dung chính dạng này còn được sử dụng trong các trang đơn danh mục để hiển thị tập trung chỉ các trích đoạn của những bài viết mới nhất thuộc danh mục đó. Vì vậy nên chúng ta sẽ tạo thêm một component
mới với tên là main.ejs
.
[view]
. |
. +-----[component]
. |
. +-----meta.ejs
. +-----topnav.ejs
. +-----header.ejs
. +-----script.ejs
. |
. +-----main.ejs
Nội dung của mỗi khối trích đoạn entry
sẽ chỉ đơn giản là bao gồm tiêu đề, văn bản nội dung ngắn, và liên kết dẫn tới bài viết tương ứng.
<main id="main">
<div class="container">
<section class="entry">
<h2> Bài Viết Thứ 1001 </h2>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's standard dummy text
ever since the 1500s, when an unknown printer took a galley of
type and scrambled it to make a type specimen book. It has survived
not only five centuries, but also the leap into electronic typesetting,
remaining essentially unchanged...
</p>
<a href="#"> Đọc tiếp </a>
</section>
<section class="entry">
<h2> Bài Viết Thứ 1000 </h2>
<p>
Contrary to popular belief, Lorem Ipsum is not simply random text.
It has roots in a piece of classical Latin literature from 45 BC,
making it over 2000 years old. Richard McClintock, a Latin professor
at Hampden-Sydney College in Virginia, looked up one of the more
obscure Latin words, consectetur, from a Lorem Ipsum passage, and
going through the cites of the word in classical literature, discovered
the undoubtable source...
</p>
<a href="#"> Đọc tiếp </a>
</section>
<!-- copy/paste thêm một số .entry nữa ở đây -->
</div><!-- .container -->
</main>
Bổ sung code CSS
Tiêu đề của các entry
được hiển thị nhỏ hơn so với nội dung chính và chỉ cần đủ tương phản để nổi bật so với đoạn văn bản ngắn đi kèm. Ở đây mình vẫn sẽ sử dụng line-height
với mật độ hiển thị khá kín kẽ so với đoạn văn bản thông thường. Liên kết điều hướng vẫn sẽ có một chút hiệu ứng hover
nhẹ.
[public]
. |
. +-----[css]
. |
. +-----[component]
. | |
. | +-----base.css
. | +-----topnav.css
. | +-----header.css
. | |
. | +-----main.css
. |
. +-----style.css
#main {
color: black;
background: white;
border-bottom: 1px solid lightgray;
}
#main {
padding: 45px 0;
}
.entry {
padding: 27px 0;
}
.entry:not(:first-child) {
border-top: 1px solid lightgray;
}
.entry h2 {
font-size: 1.618em;
line-height: 1.2;
}
.entry p {
margin: 18px 0;
}
.entry a {
color: black;
display: inline-block;
height: 42px;
line-height: 42px;
}
.entry a:hover {
text-decoration: none;
}
@import "./component/base.css";
@import "./component/topnav.css";
@import "./component/header.css";
@import "./component/main.css";
Chạy test để xem kết quả hiển thị mẫu.
npm test
Server Started
Cung cấp tham số data
Dữ liệu mà component
này cần sử dụng là một mảng các object
chứa thông tin về tiêu đề, trích đoạn văn bản ngắn, và liên kết tới bài viết. Do đó chúng ta có thể tạo một khóa duy nhất cho mảng dữ liệu là entry-list
và định nghĩa một type
riêng cho các object
trong mảng này là một class
có tên Entry
.
const Data = class extends Map {
constructor() {
super();
/* --- meta.ejs */
/* --- topnav.ejs */
/* --- header.ejs */
/* --- main.ejs */
this.set("entry-list", []);
return this;
}
}; // Data
module.exports = Data;
const Entry = class extends Map {
constructor() {
super();
this.set("title", "Tiêu đề bài viết")
.set("excerpt", "Đoạn văn bản nội dung ngắn...")
.set("url", "#");
return this;
}
}; // Entry
Thao tác lặp qua mảng dữ liệu được cung cấp và tạo ra các phần tử HTML thì chúng ta đã quá quen thuộc rồi.
<main id="main">
<div class="container">
<% for (var entry of data.get("entry-list")) { %>
<section class="entry">
<h2> <%= entry.get("title") %> </h2>
<p> <%= entry.get("excerpt") %> </p>
<a href="<%= entry.get("url") %>"> Đọc tiếp </a>
</section>
<% } %>
</div><!-- .container -->
</main>
Bây giờ thì chúng ta cần giả lập dữ liệu truy vấn được từ đâu đó và truyền vào view
và chạy test
để kiểm tra hoạt động của code template
mới viết.
const Data = require("./view/type/Data");
const Category = require("./view/type/Category");
const Entry = require("./view/type/Entry");
var data = new Data()
/* * * * * * * * * * * * * * * * * * * * * * * * * * *
TopNav ...
*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * *
Main
*/
var entry1 = new Entry()
.set("title", "Bài Viết Thứ 1001")
.set("excerpt", "Nội dung trích đoạn mở đầu bài viết thứ 1001 ...")
.set("url", "/article/view/1000");
var entry2 = new Entry()
.set("title", "Bài Viết Thứ 1000")
.set("excerpt", "Nội dung trích đoạn mở đầu bài viết thứ 1001 ...")
.set("url", "/article/view/999");
data.set("entry-list", [
entry1,
entry2
]);
module.exports = data;
npm test
Server Started
Như vậy là chúng ta đã thực hiện xong những thành phần chính trong trang chủ blog. Về phần chân trang web thì đây không hẳn là nội dung quá quan trọng và chúng ta sẽ để dành thời gian cho các layout
khác. Bây giờ thì chúng ta sẽ quay lại với Sub-Series ExpressJS một chút để viết một route
xử lý cho yêu cầu xem trang chủ và tản mạn về tổng quan kiến trúc của bộ code express-blog
mà chúng ta đang viết.
[ExpressJS] Bài 7 - Viết Code Điều Hành Blog Cá Nhân (Tiếp Theo)
Và trong bài viết tiếp theo của Sub-Series EJS, chúng ta sẽ bắt đầu thảo luận về nhóm layout
hiển thị nội dung các trang bài viết là article
.