网站首页

后台管理完成后,我们开始进入前台功能的开发。本章我们将完成博客首页的开发。

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>,
}

除了listpage是本身模板需要的数据之外,其它的都是母模板(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/网站首页分支。

要查看完整内容,请先登录