给静态博客实现rss

2023-09-30 12:31 | Rigos | #Rust# #Blog#

目录

    手痒了,想给博客添加 feed.xml 以实现 rss 功能。

    实现原理和 tera 的 html 模板渲染大差不差,大概思路就是遍历一边文章。

    模板文件:

    <?xml version="1.0" encoding="utf-8"?>
    <rss version="2.0">
        <channel>
            <title>Candlest's Blog</title>
            <link>http://candlest.github.io/</link>
            <description>Candlest 的博客</description>
            <language>zh-cn</language>
    
            {% for post in post_index | sort(attribute="datetime") |reverse%}
            <item>
                <title>{{post.title}}</title>
                <link>https://candlest.github.io/Post/{{post.url_name}}</link>
            </item>
            {% endfor %}
        </channel>
    </rss>
    

    代码:

    impl Builder
    {
        /* ... */
        pub fn build_feed(&self) {
            let tera = match Tera::new(
                format!(
                    "{}/{}/{}/*.html",
                    self.project_root_path, self.config.template_dir, self.config.theme
                )
                .as_str(),
            ) {
                Ok(t) => t,
                Err(e) => {
                    println!("Parsing error(s): {}", e);
                    ::std::process::exit(1);
                }
            };
            let mut context = tera::Context::new();
            context.insert("post_index", &self.posts_index);
            context.insert("tags", &self.tags);
            context.insert("categories", &self.categroies);
            //render
            let rendered = tera.render("feed.html", &context).unwrap();
            //let folder = std::path::Path::new(html_output_path.as_str());
            //let _ = std::fs::create_dir_all(folder);
            let html_output_path = format!("{}/feed.xml", self.config.public_dir);
            std::fs::write(html_output_path, rendered).unwrap();
        }
    }
    /* ... */
    pub fn build() {
        let pro_path = String::from("./");
        let builder = Builder::new(pro_path);
        let mut builder_o = builder.clone();
        utils::info(utils::Info::GENERATE, "now generate", utils::PUBLIC_DIR);
        let handle_static = std::thread::spawn(move || {
            builder.build_static_dir();
        });
        builder_o.pre_create_posts_index();
        builder_o.build_all();
        builder_o.build_feed();
        handle_static.join().unwrap();
    }