diff options
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.ts | 117 |
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 +} |