M .gitignore => .gitignore +1 -0
                    
                    
@@ 5,3 5,4 @@
 /blogs
 /pages
 /template.html.hbs
+/config.toml
                     
                    M Cargo.lock => Cargo.lock +145 -0
                    
                    
@@ 21,6 21,19 @@ dependencies = [
 ]
 
 [[package]]
+name = "atom_syndication"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91a85f2ee28cbd1ecf91288460f6dc74661fd99b4e9a559836a667ccf63aa38c"
+dependencies = [
+ "chrono",
+ "derive_builder",
+ "diligent-date-parser",
+ "never",
+ "quick-xml",
+]
+
+[[package]]
 name = "autocfg"
 version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 172,6 185,72 @@ dependencies = [
 ]
 
 [[package]]
+name = "darling"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "derive_builder"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
+dependencies = [
+ "derive_builder_macro",
+]
+
+[[package]]
+name = "derive_builder_core"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "derive_builder_macro"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
+dependencies = [
+ "derive_builder_core",
+ "syn 1.0.109",
+]
+
+[[package]]
 name = "digest"
 version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 182,6 261,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "diligent-date-parser"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6cf7fe294274a222363f84bcb63cdea762979a0443b4cf1f4f8fd17c86b1182"
+dependencies = [
+ "chrono",
+]
+
+[[package]]
 name = "emojicons"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 193,6 281,21 @@ dependencies = [
 ]
 
 [[package]]
+name = "encoding_rs"
+version = "0.8.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
 name = "fuchsia-cprng"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 262,6 365,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
 name = "indexmap"
 version = "1.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 336,6 445,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
 
 [[package]]
+name = "never"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91"
+
+[[package]]
 name = "num-integer"
 version = "0.1.45"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 464,6 579,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "quick-xml"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffc053f057dd768a56f62cd7e434c42c831d296968997e9ac1f76ea7c2d14c41"
+dependencies = [
+ "encoding_rs",
+ "memchr 2.5.0",
+]
+
+[[package]]
 name = "quote"
 version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 607,6 732,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
 
 [[package]]
+name = "rss"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14816ec8b4e58b34a36adba66dcadd3e1e221dcb0fb2fd83e7c5129ea1a72458"
+dependencies = [
+ "atom_syndication",
+ "derive_builder",
+ "never",
+ "quick-xml",
+]
+
+[[package]]
 name = "ryu"
 version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 682,6 819,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
 
 [[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
 name = "syn"
 version = "1.0.109"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 919,8 1062,10 @@ dependencies = [
  "emojicons",
  "handlebars",
  "pulldown-cmark",
+ "rss",
  "serde",
  "serde_derive",
+ "serde_json",
  "toml",
  "walkdir",
 ]
                     
                    M Cargo.toml => Cargo.toml +2 -0
                    
                    
@@ 10,7 10,9 @@ chrono = "0.4.24"
 emojicons = "1.0.1"
 handlebars = "4.3.6"
 pulldown-cmark = "0.9.2"
+rss = "2.0.2"
 serde = "1.0.157"
 serde_derive = "1.0.157"
+serde_json = "1.0.94"
 toml = "0.7.3"
 walkdir = "2.3.3"
                     
                    M src/main.rs => src/main.rs +69 -3
                    
                    
@@ 1,11 1,12 @@
 use chrono::NaiveDate;
 use handlebars::Handlebars;
-use serde_derive::Serialize;
+use serde_derive::{Serialize, Deserialize};
 use std::fs::{self, File};
 use std::io::Write;
 use std::path::{Path, PathBuf};
 use toml::{Table, Value};
 use walkdir::WalkDir;
+use rss::{Item, Guid, ChannelBuilder};
 
 #[derive(Clone, Serialize)]
 struct Blog {
@@ 21,11 22,39 @@ struct BlogPage {
     after: Option<usize>,
 }
 
+#[derive(Serialize)]
+struct Jsonfeed {
+    version: String,
+    title: String,
+    items: Vec<JsonfeedItems>,
+    icon: String,
+    home_page_url: String,
+    feed_url: String
+}
+
+#[derive(Serialize)]
+struct JsonfeedItems {
+    id: String,
+    url: String,
+    title: String,
+    content_html: String,
+    date_published: String,
+}
+
+#[derive(Deserialize)]
+struct Config {
+    name: String,
+    home_page: String,
+    icon: String,
+}
+
 fn main() {
     // make public folder
     let _ = fs::remove_dir_all("public");
     fs::create_dir("public").expect("could not make the folder \"public\"");
 
+    let config: Config = toml::from_str(&fs::read_to_string("config.toml").expect("could not read file config.toml")).expect("Cant convert your config to toml");
+
     //copy all static
     for e in WalkDir::new("static").into_iter().filter_map(|e| e.ok()) {
         if e.metadata().unwrap().is_file() {
@@ 163,8 192,45 @@ fn main() {
                 before,
                 after,
             }
-        });
-        for (x, i) in blog_pages.enumerate() {
+        }).collect::<Vec<_>>();
+        let json_blogs = serde_json::to_string(&Jsonfeed {
+            version: "https://jsonfeed.org/version/1".to_string(),
+            title: format!("{}'s Blog", config.name),
+            icon: config.icon,
+            home_page_url: config.home_page.clone(),
+            feed_url: format!("{}/blogs.json", config.home_page),
+            items: blog_pages.first().expect("cant get the first blog page").blogs.iter().map(|x| JsonfeedItems {
+                id: format!("{}/blogs/{}", config.home_page.clone(), x.path.display()),
+                url: format!("{}/blogs/{}", config.home_page, x.path.display()),
+                title: x.config["title"].as_str().expect("cant get the title of the blog").to_string(),
+                content_html: x.config["content"].as_str().expect("cant get the content of a blog (should never happen)").to_string(),
+                date_published: format!("{}T00:00:00+00:00", x.config["date"].as_str().expect("no date on blog"))
+            }).collect()
+        }).expect("Cant write the json blogs");
+        let rss_blogs = ChannelBuilder::default()
+            .title(format!("{}'s Blog", config.name))
+            .link(format!("{}/blogs", config.home_page))
+            .items(blog_pages.first().expect("cant get the first blog page").blogs.iter().map(|x| {
+                let mut item = Item::default();
+                item.set_guid({
+                    let mut guid = Guid::default();
+                    guid.set_permalink(true);
+                    guid.set_value(format!("{}/blogs/{}", config.home_page.clone(), x.path.display()));
+                    guid
+                });
+                item.set_title(x.config["title"].as_str().expect("Cant get the title of a blog").to_string());
+                item.set_link(format!("{}/blogs/{}", config.home_page.clone(), x.path.display()));
+                item.set_description(x.config["content"].as_str().expect("cant get the content of a blog (should never happen)").to_string());
+                item.set_pub_date(NaiveDate::parse_from_str(x.config["date"].as_str().expect("no date on blog"), "%Y-%m-%d").expect("Cant read date").format("%a, %d %b %Y 00:00:00 +0000").to_string());
+                item
+            }).collect::<Vec<_>>()).build();
+
+        let mut file = File::create("public/blogs.json").expect("Cant make blogs.json");
+        file.write_all(json_blogs.as_bytes()).expect("Cant write to blogs.json");
+        let mut file = File::create("public/blogs.rss").expect("Cant make blogs.rss");
+        file.write_all(rss_blogs.to_string().as_bytes()).expect("Cant write to blogs.rss");
+
+        for (x, i) in blog_pages.iter().enumerate() {
             let path_name = format!("public/blogs-{x}.html");
             let path = Path::new(&path_name);
             let mut file =