内容介绍
本专题将带你使用 axum 实现一个简洁易用的博客系统应用骨架
本章我们将开始搭建本应用的骨架,包括:依赖、`Result` 和 `AppError` 以及通用数据库操作等。模板
我们的博客分为“前台”和“后台”两部分。前台用于展示博客内容,后台用于管理博客。本章我们将编写前台和后台的基础模板以及对应的路由。分类管理
本章开始,我们将对博客的具体业务进行实现。首先,我们实现博客分类的管理功能。文章管理
本章我们将实现博客的文章管理功能。鉴权与登录
本章实现后台管理的鉴权,以及管理员的登录、注销功能。涉及的知识点有:cookie及中间件等。后台管理菜单及首页模板
目前,后台管理功能基本完成,但还有两个工作没做:清理后台管理的导航菜单以及后台管理首页的模板。网站首页
后台管理完成后,我们开始进入前台功能的开发。本章我们将完成博客首页的开发。分类文章列表
本章将实现博客的分类文章列表功能。文章详情
本章将实现博客文章的详情显示功能。存档文章列表
本章将实现存档文章列表功能。注意,本章涉及较多PostgreSQL知识,如果你对相关知识不熟悉,可以先让代码跑起来,再去了解相关知识。总结与作业
恭喜你,已经完成了本专题的学习。下面我们对本专题进行简要的总结。
网站首页
- 545860
- 2022-03-26 15:51:46
后台管理完成后,我们开始进入前台功能的开发。本章我们将完成博客首页的开发。
templates/frontend/base.html
是时候对前台母模板进行数据填充和块的定义了:
其中:
<nav class="nav d-flex justify-content-between">
{% for cat in cats %}
<a class="p-2 link-secondary" href="/category/{{cat.id}}">{{cat.name}}</a>
{%endfor%}
</nav>
用于将分类列表填充为头部导航,而
<ol class="list-unstyled mb-0">
{% for arch in archives %}
<li><a href="/archive/{{arch.dateline}}">{{arch.dateline}}</a></li>
{%endfor%}
</ol>
用于填充按月份为单位的存档。
首页模板
templates/frontend/index.html
{%extends "./base.html"%}
{%block category_name%}最新博文{%endblock%}
{% block content %}
{% for item in list.data %}
<article class="blog-post">
<h2 class="blog-post-title">
<a href="/topic/{{item.id}}">{{item.title}}</a>
</h2>
<p class="blog-post-meta">
<a href="https://axum.rs" target="_blank">AXUM.RS</a> 发表于 {{item.dateline()}} [<a href="/category/{{item.category_id}}">{{item.category_name}}</a>]
</p>
{{ item.summary }}
</article>
{%endfor%}
{% endblock %}
{% block paginate %}
{%include "../pagination.html"%}
{%endblock%}
其中 {% for item in list.data %}...{%endfor%}用于填充文章列表。这个list是一个 Paginate分页对象。
视图类
// src/view/frontend/index.rs
#[derive(Template)]
#[template(path="frontend/index.html")]
pub struct Index {
pub list: Paginate<Vec<TopicList>>,
pub page : u32,
pub cats: Vec<Category>,
pub archives: Vec<TopicArchive>,
}
除了list和page是本身模板需要的数据之外,其它的都是母模板(base.html)所需要的
handler
Args:前台页面所需要的参数,请参见下文的“Args”部分。topic::archive_list():根据已发表的文章获取按月存档的日期列表。详情请见下文的“数据库操作”部分。
数据库操作
// src/db/topic.rs
pub async fn archive_list(client: &Client) -> Result<Vec<TopicArchive>> {
let sql = "SELECT
to_char(DATE_TRUNC('month',dateline), 'YYYY年MM月')
AS dateline
FROM topics
GROUP BY to_char(DATE_TRUNC('month',dateline), 'YYYY年MM月')";
super::query(client, sql, &[]).await
}
archive_list():调用Postgresql相关函数,根据已发表的文章获取按月存档的日期列表。单条记录的格式如2022年03月
// src/handler/frontend/mod.rs
#[derive(Deserialize)]
pub struct Args {
pub page : Option<u32>,
}
impl Args {
pub fn page(&self) -> u32 {
self.page.unwrap_or(0)
}
}
page:可选的分页页码。
本章代码位于07/网站首页分支。
