diff --git a/common/rss.hbs b/common/rss.hbs
new file mode 100644
index 0000000..cfb9abf
--- /dev/null
+++ b/common/rss.hbs
@@ -0,0 +1,26 @@
+
+
+
+ {{ blog.title }}
+ {{ blog.description }}
+ {{ page.base_url }}
+
+
+ {{ #if next }}
+
+ {{ /if }}
+ {{ #if prev }}
+
+ {{ /if }}
+
+ {{ #each posts }}
+ -
+ {{ this.title }}
+
+ {{ format_date this.timestamp "%a, %d %b %Y %T GMT" }}
+ {{ ../page.base_url }}/{{ this.url }}
+ {{ ../page.base_url }}/{{ this.url }}
+
+ {{ /each }}
+
+
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index f534e79..fc610f2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -148,7 +148,7 @@ async fn default_route(_req: Request, url: Url) -> MyResult {
} else {
// TODO: Actually render the page...
return Response::new_with_opt_str_and_init(
- Some(&render::render_post(post).await?),
+ Some(&render::render_post(url, post).await?),
ResponseInit::new()
.status(200)
.headers(headers!{
diff --git a/src/render.rs b/src/render.rs
index 2e40696..0b703b0 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -17,6 +17,7 @@ include!(concat!(env!("OUT_DIR"), "/load_theme.rs"));
pub fn build_routes(router: &mut Router) {
router.add_route("/static/", &serve_static);
+ router.add_route("/feed.xml", &serve_rss);
}
async fn serve_static(_req: Request, url: Url) -> MyResult {
@@ -37,6 +38,17 @@ async fn serve_static(_req: Request, url: Url) -> MyResult {
}
}
+async fn serve_rss(_req: Request, url: Url) -> MyResult {
+ Response::new_with_opt_str_and_init(
+ Some(&_render_homepage(url, "rss.hbs").await?),
+ ResponseInit::new()
+ .status(200)
+ .headers(headers!{
+ "Content-Type" => "application/rss+xml"
+ }.as_ref())
+ ).internal_err()
+}
+
// Context objects used when rendering pages
#[derive(Serialize)]
struct BlogRootContext {
@@ -45,6 +57,17 @@ struct BlogRootContext {
description: &'static str,
}
+#[derive(Serialize)]
+struct PageContext {
+ // The current base URL that the client is visiting
+ // This may be different from the blog's preferred URL
+ // (e.g. the workers.dev domain, which is differnent
+ // from where you actually deploy the worker)
+ base_url: String,
+ // The current query string
+ query: String
+}
+
#[derive(Serialize)]
struct HomePagePost {
title: String,
@@ -56,6 +79,7 @@ struct HomePagePost {
#[derive(Serialize)]
struct HomePageContext {
blog: &'static BlogRootContext,
+ page: PageContext,
posts: Vec,
prev: Option,
next: Option
@@ -64,6 +88,7 @@ struct HomePageContext {
#[derive(Serialize)]
struct PostContext {
blog: &'static BlogRootContext,
+ page: PageContext,
title: String,
url: String,
timestamp: u64,
@@ -88,6 +113,9 @@ handlebars_helper!(build_num: | | BuildTag{}.get_build_timestamp());
handlebars_helper!(format_date: |date: u64, format: str| {
NaiveDateTime::from_timestamp(date as i64, 0).format(format).to_string()
});
+// Convert "/?offset=X" to "/feed.xml?offset=X"
+// for use in RSS feed (feed.xml)
+handlebars_helper!(feed_pagination: |s: str| s.replace("/", "/feed.xml"));
fn build_handlebars() -> Handlebars<'static> {
let mut hbs = Handlebars::new();
@@ -96,6 +124,7 @@ fn build_handlebars() -> Handlebars<'static> {
hbs.register_helper("cur_year", Box::new(cur_year));
hbs.register_helper("build_num", Box::new(build_num));
hbs.register_helper("format_date", Box::new(format_date));
+ hbs.register_helper("feed_pagination", Box::new(feed_pagination));
// Templates
for file in THEME_DIR.files() {
@@ -106,15 +135,35 @@ fn build_handlebars() -> Handlebars<'static> {
path, file.contents_utf8().unwrap()).unwrap();
}
}
+
+ // The common RSS template
+ hbs.register_template_string("rss.hbs",
+ include_str!("../common/rss.hbs")).unwrap();
+
return hbs;
}
-pub async fn render_homepage(url: Url) -> MyResult {
+fn build_page_context(url: &Url) -> PageContext {
+ PageContext {
+ base_url: url.origin(),
+ query: url.search()
+ }
+}
+
+pub fn render_homepage(url: Url) -> impl std::future::Future