rss feed and ryuji improvements
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@ build
|
||||
*.js
|
||||
!static/*.js
|
||||
/posts/_draft_*.md
|
||||
nohup.out
|
||||
|
||||
61
index.ts
61
index.ts
@@ -4,6 +4,7 @@ import { parse_md_to_html } from 'makoto';
|
||||
import { Renderer } from './ryuji.js';
|
||||
import { Builder } from './saki.js';
|
||||
import _posts_metadata from './posts/_metadata.json';
|
||||
import _site_info from './site_info.json';
|
||||
|
||||
export interface PostMetadata {
|
||||
title: string,
|
||||
@@ -20,6 +21,18 @@ export interface Post extends PostMetadata {
|
||||
tags_exist: boolean,
|
||||
}
|
||||
|
||||
export interface RSSPost extends PostMetadata {
|
||||
url: string,
|
||||
last_updated: string,
|
||||
html: string,
|
||||
}
|
||||
|
||||
export interface SiteInfo {
|
||||
title: string,
|
||||
url: string,
|
||||
icon: string,
|
||||
}
|
||||
|
||||
let renderer: Renderer = new Renderer("templates", "components");
|
||||
let builder: Builder = new Builder();
|
||||
|
||||
@@ -28,7 +41,7 @@ let posts_metadata: PostMetadata[] = Object.values(_posts_metadata);
|
||||
builder.serve_static_folder("static");
|
||||
|
||||
//home page
|
||||
builder.serve_template(renderer, "/", "index.html", {
|
||||
builder.serve_template(renderer, "/", "index", {
|
||||
posts: posts_metadata,
|
||||
});
|
||||
|
||||
@@ -75,7 +88,7 @@ for (let i=0; i < posts_metadata.length; i++) {
|
||||
);
|
||||
}
|
||||
|
||||
builder.serve_templates(renderer, posts_serve_paths, "post.html", posts_vars);
|
||||
builder.serve_templates(renderer, posts_serve_paths, "post", posts_vars);
|
||||
|
||||
//tags
|
||||
|
||||
@@ -91,4 +104,46 @@ for (let i=0; i < tags.length; i++) {
|
||||
});
|
||||
}
|
||||
|
||||
builder.serve_templates(renderer, tags_serve_paths, "tags.html", tags_vars);
|
||||
builder.serve_templates(renderer, tags_serve_paths, "tags", tags_vars);
|
||||
|
||||
//build rss feed
|
||||
let first_posts: PostMetadata[] = posts_metadata.slice(0, 5); //not truly the recents, actually the first 5 posts in the json file, which is decided by me and usually the most recent posts
|
||||
|
||||
const site_info: SiteInfo = _site_info;
|
||||
|
||||
let posts_rss: RSSPost[] = first_posts.map((post) => {
|
||||
//get url
|
||||
let url: string = `${site_info.url}/posts/${post.slug}`;
|
||||
//get last_updated
|
||||
let date_parts: number[] = post.date.split("/").map((p) => Number(p)); // dd/mm/yyyy
|
||||
let date: Date = new Date();
|
||||
date.setUTCFullYear(date_parts[2]);
|
||||
date.setUTCMonth(date_parts[1]-1, date_parts[0]);
|
||||
date.setUTCHours(0, 0, 0, 0);
|
||||
let iso_string: string = date.toISOString();
|
||||
let last_updated: string = iso_string.slice(0, iso_string.length-1)+"+00:00"; //remove the "Z" in iso string
|
||||
//get html
|
||||
let post_md_path: string = path.join(__dirname, `/posts/${post.filename}.md`);
|
||||
let md: string = readFileSync(post_md_path, "utf-8").replaceAll("\r", "");
|
||||
let html: string = parse_md_to_html(md);
|
||||
//turn into rsspost
|
||||
return {
|
||||
...post,
|
||||
url,
|
||||
last_updated,
|
||||
html,
|
||||
}
|
||||
});
|
||||
|
||||
//might leak what side of the planet youre on
|
||||
let now: Date = new Date();
|
||||
now.setUTCHours(0, 0, 0, 0);
|
||||
let global_iso_string: string = now.toISOString();
|
||||
let global_last_updated: string = global_iso_string.slice(0, global_iso_string.length-1)+"+00:00"; //remove the "Z" in iso string
|
||||
|
||||
builder.serve_template(renderer, "/atom.xml", "atom.xml", {
|
||||
site_info,
|
||||
recent_posts: posts_rss,
|
||||
last_updated: global_last_updated,
|
||||
});
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ createServer((req, res) => {
|
||||
case "js":
|
||||
content_type = "text/javascript";
|
||||
break;
|
||||
case "xml":
|
||||
content_type = "text/xml";
|
||||
break;
|
||||
case "png":
|
||||
case "ico":
|
||||
content_type = "image/png";
|
||||
|
||||
8
ryuji.ts
8
ryuji.ts
@@ -89,7 +89,10 @@ export class Renderer {
|
||||
if (recursion_layer > 5) throw Error("Components more than 5 layers deep, components may be referencing each other in infinite loop.");
|
||||
if (typeof exp_parts[1] !== "string") throw Error("`component:` statement missing component file name afterwards");
|
||||
let file_name: string = exp_parts[1];
|
||||
rendered += this.render_template(Renderer.concat_path(this.components_dir, `${file_name}${this.file_extension}`), vars, recursion_layer+1);
|
||||
if (!file_name.includes(".")) {
|
||||
file_name += this.file_extension;
|
||||
}
|
||||
rendered += this.render_template(Renderer.concat_path(this.components_dir, file_name), vars, recursion_layer+1);
|
||||
} else if (exp_parts[0] === "for") {
|
||||
if (for_loops[for_loops.length-1]?.index === index) {
|
||||
//for loop already exists, just continue and do nothing
|
||||
@@ -265,6 +268,9 @@ export class Renderer {
|
||||
}
|
||||
|
||||
render_template(template_name: string, vars?: any, recursion_layer: number=0): string {
|
||||
if (!template_name.includes(".")) {
|
||||
template_name += this.file_extension;
|
||||
}
|
||||
let path_to_template: string = Renderer.concat_path(this.templates_dir, template_name);
|
||||
const template_contents: string = readFileSync(path_to_template, "utf-8");
|
||||
return this.render(template_contents, vars, recursion_layer);
|
||||
|
||||
5
site_info.json
Normal file
5
site_info.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "prussiafan.club/hedgeblog",
|
||||
"url": "https://www.prussiafan.club/",
|
||||
"icon": "https://www.prussiafan.club/favicon.ico"
|
||||
}
|
||||
10
templates/atom.xml
Normal file
10
templates/atom.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
|
||||
<title>[[ site_info.title ]]</title>
|
||||
<link href="[[ site_info.url ]]"/>
|
||||
<id>[[ site_info.url ]]</id>
|
||||
<updated>[[ last_updated ]]</updated>
|
||||
<icon>[[ site_info.icon ]]</icon>
|
||||
[[ for:recent_posts:post ]]
|
||||
[[ component:post_entry.xml ]]
|
||||
[[ endfor ]]
|
||||
</feed>
|
||||
12
templates/components/post_entry.xml
Normal file
12
templates/components/post_entry.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<entry>
|
||||
<title>[[ post.title ]]</title>
|
||||
<link href="[[ post.url ]]"/>
|
||||
<id>[[ post.url ]]</id>
|
||||
<updated>[[ post.last_updated ]]</updated>
|
||||
<author>
|
||||
<name>[[ post.author ]]</name>
|
||||
</author>
|
||||
<content type="html">
|
||||
[[ post.html ]]
|
||||
</content>
|
||||
</entry>
|
||||
Reference in New Issue
Block a user