Skip to main content

yggdrasil/components/post/
post_footer.rs

1//! 文章页脚组件。
2//! 展示文章标签与上一篇/下一篇导航。
3
4use dioxus::prelude::*;
5use dioxus::router::components::Link;
6
7use crate::components::post::post_nav_links::PostNavLinks;
8use crate::models::post::Post;
9use crate::router::Route;
10
11/// 文章页脚组件。
12///
13/// Props:
14/// - `post`:文章数据模型
15/// - `full_reload`:链接走整页加载而非客户端路由(默认 false)。仅当本组件
16///   渲染在 admin 布局内(`/admin/preview`)时传 true——跨 layout 分支的
17///   客户端导航会触发 dioxus 0.7.10 的 suspense 卸载双重回收 bug(详见
18///   `src/pages/admin/preview.rs` 模块文档),整页加载可完全规避。
19/// - `sample`:图鉴展示非跳转的样例链接;正式文章默认 false。
20///
21/// 展示内容包括:
22/// - 文章标签云,链接到对应标签详情页
23/// - 相邻文章导航(如有)
24#[component]
25pub fn PostFooter(
26    post: Post,
27    #[props(default = false)] full_reload: bool,
28    #[props(default = false)] sample: bool,
29) -> Element {
30    let tag_to = |tag: &str| {
31        super::nav_target(
32            Route::TagDetail {
33                tag: tag.to_string(),
34            },
35            full_reload,
36        )
37    };
38    rsx! {
39        footer { class: "post-footer",
40            if !post.tags.is_empty() {
41                ul { class: "post-tags", aria_label: "文章标签",
42                    for tag in &post.tags {
43                        li { key: "{tag}",
44                            if sample {
45                                a { href: "#", onclick: move |event| event.prevent_default(), "{tag}" }
46                            } else {
47                                Link { to: tag_to(tag), "{tag}" }
48                            }
49                        }
50                    }
51                }
52            }
53
54            if post.prev_post.is_some() || post.next_post.is_some() {
55                PostNavLinks { prev: post.prev_post, next: post.next_post, full_reload, sample }
56            }
57        }
58    }
59}