aboutsummaryrefslogtreecommitdiffstats
path: root/src/server/template/Base.ts
diff options
context:
space:
mode:
author2023-02-16 22:57:52 +0530
committer2023-02-16 22:57:52 +0530
commit93e75949e9a2861f651e2a3602e08e9b25cf47c4 (patch)
tree9da44bdc8885c94355ee3dc7a1ae029bc2627356 /src/server/template/Base.ts
parent0.4.3 (diff)
downloadsudomsg-93e75949e9a2861f651e2a3602e08e9b25cf47c4.tar
sudomsg-93e75949e9a2861f651e2a3602e08e9b25cf47c4.tar.gz
sudomsg-93e75949e9a2861f651e2a3602e08e9b25cf47c4.tar.bz2
sudomsg-93e75949e9a2861f651e2a3602e08e9b25cf47c4.tar.lz
sudomsg-93e75949e9a2861f651e2a3602e08e9b25cf47c4.tar.xz
sudomsg-93e75949e9a2861f651e2a3602e08e9b25cf47c4.tar.zst
sudomsg-93e75949e9a2861f651e2a3602e08e9b25cf47c4.zip
Move to Server Side Render with expressjs
Backend Rewritten in typescript Signed-off-by: Marc Pervaz Boocha <mboocha@sudomsg.xyz> On branch main Your branch is up to date with 'origin/main'. Changes to be committed: new file: .editorconfig modified: .gitignore new file: Containerfile renamed: favicon/icon.svg -> assets/favicon.svg modified: assets/index.css deleted: assets/index.js deleted: assets/mandle.png deleted: assets/sw.js new file: assets/syntax.css modified: deploy deleted: eleventy.config.js deleted: favicon/192.png deleted: favicon/512.png deleted: favicon/icon.ico deleted: license modified: package-lock.json modified: package.json deleted: src/_data/env.js deleted: src/_data/metadata.js deleted: src/_includes/base.njk deleted: src/_includes/page.njk deleted: src/_includes/post.njk deleted: src/about.njk deleted: src/blog.njk new file: src/client/index.ts deleted: src/gen/atom.njk deleted: src/gen/error.njk deleted: src/gen/feedjson.11ty.js deleted: src/gen/gen.11tydata.js deleted: src/gen/manifest.11ty.js deleted: src/gen/metadata.11ty.js deleted: src/gen/robot.njk deleted: src/gen/sitemap.njk deleted: src/index.njk deleted: src/post/post.11tydata.js new file: src/server/app.ts new file: src/server/build.ts new file: src/server/content/about.ts new file: src/server/content/blog.ts new file: src/server/content/feed.ts new file: src/server/content/index.ts new file: src/server/content/robots.ts new file: src/server/content/sitemap.ts new file: src/server/content/webmanifest.ts new file: src/server/errHanadler.ts new file: src/server/img.ts new file: src/server/metadata.ts new file: src/server/router.ts new file: src/server/server.ts new file: src/server/template/Base.ts new file: src/server/template/Page.ts new file: src/server/template/Post.ts new file: src/server/template/atom.ts new file: src/server/template/header.ts new file: src/server/template/html.ts new file: src/server/template/sitemap.ts new file: src/server/template/syntax.ts new file: src/server/template/table.ts new file: src/server/template/vdom.ts new file: src/server/template/xml.ts new file: src/server/utils/createUrl.ts new file: src/server/utils/curl.ts new file: src/server/utils/isDefined.ts new file: src/server/utils/isDevel.ts new file: src/server/utils/relDir.ts new file: src/server/utils/relUrl.ts new file: src/server/utils/schema.ts new file: src/server/utils/setStingRoute.ts new file: src/server/utils/strHandler.ts new file: src/worker/sw.ts new file: src/worker/tsconfig.json new file: tsconfig.json
Diffstat (limited to 'src/server/template/Base.ts')
-rw-r--r--src/server/template/Base.ts117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/server/template/Base.ts b/src/server/template/Base.ts
new file mode 100644
index 0000000..e5128ee
--- /dev/null
+++ b/src/server/template/Base.ts
@@ -0,0 +1,117 @@
+import metadata from "../metadata.js"
+import curl from "../utils/curl.js"
+import setStingRoute from "../utils/setStingRoute.js"
+import isDefined from "../utils/isDefined.js"
+import { Attribute, doctype, html as html_1, head, meta, title as title_1, link, script, body, header, nav, a, main, footer } from "./html.js"
+import { c, node } from "./vdom.js"
+import type { URL } from "url"
+
+export var pages: (ReturnType<typeof Base>)[] = []
+
+type content<T extends node = node> = T | (() => T)
+
+interface BasePageI<T extends node = node> {
+ url?: string | URL | undefined,
+ content: content<T>,
+ date_mod?: Date | undefined,
+ date_pub?: Date
+}
+
+export interface BaseI<T extends node = node> extends BasePageI<T> {
+ title?: string,
+ description?: string,
+ keywords?: string[],
+ isHighlight?: boolean
+}
+
+export function content<Type extends BasePageI>({ data }: Attribute & { data: Type }): node {
+ return data.content instanceof Function ? data.content() : data.content
+}
+
+function BasePage<Type extends BasePageI>(data: Type): Type & {
+ setupRoute(url?: URL): void;
+ render(): Promise<string>;
+ date_mod: Type["date_pub"];
+ url: URL | undefined
+} {
+ return {
+ ...data,
+ setupRoute(url?: URL): void {
+ url ??= this.url
+ if (isDefined(url)) {
+ setStingRoute(url.pathname, "html", this.render.bind(this))
+ } else {
+ throw new Error();
+
+ }
+ },
+ async render(): Promise<string> {
+ console.profile()
+ const a = doctype(c(content, { data: this }))
+ console.profileEnd()
+ return a
+ },
+ date_mod: data.date_mod ?? data.date_pub,
+ url: isDefined(data.url) ? curl(data.url) : undefined,
+ }
+}
+
+export default function Base<Type extends BaseI>(data: Type): ReturnType<typeof BasePage<Type>> {
+ const arg = {
+ ...data,
+ content() {
+ var { title, description, keywords, url, isHighlight = true } = this
+ if (!url) {
+ isHighlight = false
+ }
+ return c(html_1, { lang: metadata.language },
+ c(head, {},
+ ...(url ? [c(meta, { property: "og:locale", content: metadata.language })] : []),
+ c(title_1, { property: "og:title" }, title || metadata.title),
+ c(meta, { name: "theme-color", content: metadata.theme }),
+ ...(url ? [
+ c(meta, { name: "description", property: "og:description", content: description || metadata.description }),
+ ...(Array.isArray(keywords) ? [c(meta, { name: "keywords", contents: keywords })] : []),
+ c(meta, { property: "og:url", content: url }),
+ c(link, { rel: "canonical", href: url }),
+ c(meta, { property: "og:site_name", content: metadata.title }),
+ c(meta, { name: "author", content: metadata.author.name }),
+ c(meta, { property: "og:type", content: "website" }),
+ c(meta, { name: "viewport", content: "width=device-width, initial-scale=1" }),
+ c(meta, { name: "twitter:card", content: "summary" }),
+ c(link, { rel: "alternate", href: metadata.feed.atom, type: "application/atom+xml", title: metadata.title }),
+ c(meta, { property: "og:image", content: "/favicon.svg?format=png&width=1024" })
+ ] : []),
+ c(link, { rel: "icon", href: "/favicon.ico", sizes: "any" }),
+ c(link, { rel: "icon", href: "/favicon.svg", type: "image/svg+xml" }),
+ c(link, { rel: "apple-touch-icon", href: "/favicon.svg?format:png&width=192" }),
+ c(link, { rel: "manifest", href: "/app.webmanifest" }),
+ c(link, { rel: "stylesheet", href: "/index.css" }),
+ c(script, { type: "module", src: "/index.js" }),
+ ...(isHighlight ? [c(link, { rel: "stylesheet", href: "/syntax.css" })] : [])
+ ),
+ c(body, {},
+ c(header, {}, c(nav, {},
+ c(a, { href: "#", id: "nav-toogle" }, "Sudomsg"),
+ ...Object.entries({
+ Home: "/",
+ Blog: "/blog",
+ About: "/about",
+ Git: "/cgit",
+ }).map(([name, href]) => c(a, { href, class: "navlinks" }, name))
+ )),
+ c(main, {}, c(content, { data })),
+ c(footer, {},
+ "Subscribe: ",
+ c(a, { href: metadata.feed.atom, type: "application/atom+xml" }, "Atom")
+ )
+ )
+ )
+ }
+ }
+ const base = BasePage(arg)
+ if (isDefined(base.url)) {
+ pages.push(base)
+ }
+ return base
+}