diff --git a/src/build.ts b/src/build.ts
index bf9d400..85eb588 100644
--- a/src/build.ts
+++ b/src/build.ts
@@ -1,10 +1,10 @@
import fs from 'node:fs';
-import { createAtomFeed } from './generator/feeds/create-atom-feed';
-import { createRssFeed } from './generator/feeds/create-rss-feed';
-import { createSitemap } from './generator/feeds/create-sitemap';
-import { optimize } from './generator/optimize/optimize';
-import { getPosts } from './generator/posts/get-posts';
-import { renderPages } from './generator/render-pages/render-pages';
+import { createAtomFeed } from './build/feeds/create-atom-feed';
+import { createRssFeed } from './build/feeds/create-rss-feed';
+import { createSitemap } from './build/feeds/create-sitemap';
+import { optimize } from './build/optimize';
+import { getPosts } from './build/posts/get-posts';
+import { renderPages } from './build/render-pages';
import { copySourceToTarget } from './utils/node';
import { DIR_DIST, DIR_SRC_STATIC } from './constants';
diff --git a/src/generator/feeds/create-atom-feed.ts b/src/build/feeds/create-atom-feed.ts
similarity index 100%
rename from src/generator/feeds/create-atom-feed.ts
rename to src/build/feeds/create-atom-feed.ts
diff --git a/src/generator/feeds/create-rss-feed.ts b/src/build/feeds/create-rss-feed.ts
similarity index 100%
rename from src/generator/feeds/create-rss-feed.ts
rename to src/build/feeds/create-rss-feed.ts
diff --git a/src/generator/feeds/create-sitemap.ts b/src/build/feeds/create-sitemap.ts
similarity index 66%
rename from src/generator/feeds/create-sitemap.ts
rename to src/build/feeds/create-sitemap.ts
index 676c646..906661e 100644
--- a/src/generator/feeds/create-sitemap.ts
+++ b/src/build/feeds/create-sitemap.ts
@@ -1,4 +1,4 @@
-import type { ImportedPageData, RenderedPages } from '@types';
+import type { PageData, RenderedPages } from '@types';
import path from 'node:path';
import { formatDateIso } from '../../utils/date';
import { html, map } from '../../utils/html';
@@ -6,16 +6,16 @@ import { createFile } from '../../utils/node';
import { BUILD } from '../../config';
import { DIR_DIST } from '../../constants';
-function pagesToSitemapEntries(pages: ImportedPageData[]): string {
- return map(pages, ({ url, config }) => {
- const date = config?.updated || config?.date || BUILD.date;
- return html`
+function pagesToSitemapEntries(pages: PageData[]): string {
+ return map(
+ pages,
+ ({ url, updated, date }) => html`
${url}
- ${formatDateIso(date)}
+ ${formatDateIso(updated || date || BUILD.date)}
- `;
- });
+ `,
+ );
}
export function createSitemap(pages: RenderedPages): void {
@@ -25,7 +25,7 @@ export function createSitemap(pages: RenderedPages): void {
const contents = html`
${pagesToSitemapEntries([
- ...content.filter((page) => !page.config.excludeFromSitemap),
+ ...content.filter((page) => !page.excludeFromSitemap),
...posts,
...tags,
])}
diff --git a/src/generator/optimize/optimize.ts b/src/build/optimize.ts
similarity index 97%
rename from src/generator/optimize/optimize.ts
rename to src/build/optimize.ts
index 6129224..36015b1 100644
--- a/src/generator/optimize/optimize.ts
+++ b/src/build/optimize.ts
@@ -2,10 +2,10 @@ import { transform } from 'lightningcss';
import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
-import { minify as minifyJs } from 'terser';
import { minify as minifyHtml } from 'html-minifier-terser';
-import { findFilesByExtension } from '../../utils/node';
-import { DIR_DIST } from '../../constants';
+import { minify as minifyJs } from 'terser';
+import { findFilesByExtension } from '../utils/node';
+import { DIR_DIST } from '../constants';
// A map of asset file paths to their hashed file names.
const fileHashMap: Record = {};
diff --git a/src/generator/posts/get-metadata.ts b/src/build/posts/get-metadata.ts
similarity index 100%
rename from src/generator/posts/get-metadata.ts
rename to src/build/posts/get-metadata.ts
diff --git a/src/generator/posts/get-posts.ts b/src/build/posts/get-posts.ts
similarity index 100%
rename from src/generator/posts/get-posts.ts
rename to src/build/posts/get-posts.ts
diff --git a/src/generator/posts/parse-markdown.ts b/src/build/posts/parse-markdown.ts
similarity index 100%
rename from src/generator/posts/parse-markdown.ts
rename to src/build/posts/parse-markdown.ts
diff --git a/src/generator/render-pages/render-pages.ts b/src/build/render-pages.ts
similarity index 57%
rename from src/generator/render-pages/render-pages.ts
rename to src/build/render-pages.ts
index 566c3f1..90dac27 100644
--- a/src/generator/render-pages/render-pages.ts
+++ b/src/build/render-pages.ts
@@ -1,17 +1,11 @@
-import type {
- BasePageData,
- ImportedPageData,
- LayoutPostData,
- LayoutTagData,
- Post,
- RenderedPages,
-} from '@types';
+import type { Layout, Page, PageData, Post, RenderedPages } from '@types';
import path from 'node:path';
-import { findFilesByExtension } from '../../utils/node';
-import { BUILD } from '../../config';
-import { DIR_DIST, DIR_SRC_STATIC } from '../../constants';
-import { createSocialImage } from '../social-image/create-social-image';
-import { getLayoutPath, renderPage } from './render-page';
+import postLayout from '../layouts/post';
+import tagLayout from '../layouts/tag';
+import { createFile, findFilesByExtension } from '../utils/node';
+import { BUILD } from '../config';
+import { DIR_DIST, DIR_SRC_STATIC } from '../constants';
+import { createSocialImage } from './social-image/create-social-image';
export async function renderPages(
posts: Post[],
@@ -30,20 +24,20 @@ export async function renderContentPage(
file: string,
posts: Post[],
tags: string[],
-): Promise {
+): Promise {
+ const layout = (await import(file)).default as Page;
const target = resolveSrcDirToDistDir(file).replace('.ts', '.html');
- const data: BasePageData = { url: resolveUrl(target), posts, tags };
- return renderPage(file, target, data);
+ const data: PageData = { url: resolveUrl(target), posts, tags };
+ return renderPage(target, layout, data);
}
async function renderPostPage(
post: Post,
posts: Post[],
tags: string[],
-): Promise {
- const layout = getLayoutPath('post');
+): Promise {
const target = resolveSrcDirToDistDir(post.file).replace('.md', '.html');
- const data: LayoutPostData = {
+ const data: PageData = {
url: resolveUrl(target),
posts,
tags,
@@ -52,7 +46,7 @@ async function renderPostPage(
};
const [page] = await Promise.all([
- renderPage(layout, target, data),
+ renderPage(target, postLayout, data),
createSocialImage(post, target),
]);
@@ -63,18 +57,30 @@ async function renderTagPage(
tag: string,
posts: Post[],
tags: string[],
-): Promise {
- const layout = getLayoutPath('tag');
+): Promise {
const target = path.join(DIR_DIST, `/tags/${tag}/index.html`);
- const data: LayoutTagData = { url: resolveUrl(target), posts, tags, tag };
- return renderPage(layout, target, data);
+ const data: PageData = { url: resolveUrl(target), posts, tags, tag };
+ return renderPage(target, tagLayout, data);
+}
+
+function renderPage(
+ target: string,
+ pageOrLayout: Page | Layout,
+ data: PageData,
+): PageData {
+ const result = pageOrLayout(data);
+ if (!result.content) {
+ throw new Error('No content');
+ }
+ createFile(target, result.content);
+ return result;
}
function resolveSrcDirToDistDir(file: string): string {
return path.join(DIR_DIST, path.relative(DIR_SRC_STATIC, file));
}
-export function resolveUrl(file: string): string {
+function resolveUrl(file: string): string {
const relativePath = path.relative(DIR_DIST, file);
const relativeUrl = path.normalize(path.dirname(relativePath) + '/');
return new URL(relativeUrl, BUILD.baseUrl).href;
diff --git a/src/generator/social-image/create-social-image.ts b/src/build/social-image/create-social-image.ts
similarity index 100%
rename from src/generator/social-image/create-social-image.ts
rename to src/build/social-image/create-social-image.ts
diff --git a/src/generator/social-image/resources/picture.png b/src/build/social-image/resources/picture.png
similarity index 100%
rename from src/generator/social-image/resources/picture.png
rename to src/build/social-image/resources/picture.png
diff --git a/src/generator/social-image/resources/source-sans-3-bold.ttf b/src/build/social-image/resources/source-sans-3-bold.ttf
similarity index 100%
rename from src/generator/social-image/resources/source-sans-3-bold.ttf
rename to src/build/social-image/resources/source-sans-3-bold.ttf
diff --git a/src/constants.ts b/src/constants.ts
index 9ad018c..1f69fd2 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -4,7 +4,6 @@ export const BASE_URL_DEV = 'http://localhost:3000/';
export const BASE_URL_PROD = 'https://tomherni.dev/';
export const DIR_DIST = path.resolve('dist/');
-export const DIR_SRC_LAYOUTS = path.resolve('src/layouts/');
export const DIR_SRC_STATIC = path.resolve('src/static/');
export const SOCIAL_FILE_NAME = 'social.jpg';
diff --git a/src/generator/render-pages/render-page.ts b/src/generator/render-pages/render-page.ts
deleted file mode 100644
index 48dfbd5..0000000
--- a/src/generator/render-pages/render-page.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import type { BasePageData, ImportedPageData, Page } from '@types';
-import fs from 'node:fs';
-import path from 'node:path';
-import { createFile } from '../../utils/node';
-import { DIR_SRC_LAYOUTS } from '../../constants';
-
-export async function renderPage(
- source: string,
- target: string,
- data: BasePageData | ImportedPageData,
-): Promise {
- const page: Page = (await import(source)).default;
- const content = page.content(data);
- const config = page.config?.(data);
-
- if (config?.layout) {
- const { layout, ..._config } = config;
- const layoutPath = getLayoutPath(layout);
-
- return renderPage(layoutPath, target, {
- ...data,
- config: { ...('config' in data ? data.config : {}), ..._config },
- content,
- });
- }
-
- createFile(target, content);
- return { ...data, content, config: (data as ImportedPageData).config };
-}
-
-export function getLayoutPath(layout: string): string {
- const layoutPath = path.join(DIR_SRC_LAYOUTS, `${layout}.ts`);
-
- if (!fs.existsSync(layoutPath)) {
- throw new Error('Layout does not exist');
- }
- return layoutPath;
-}
diff --git a/src/includes/site-header.ts b/src/includes/site-header.ts
index bffb903..e297c08 100644
--- a/src/includes/site-header.ts
+++ b/src/includes/site-header.ts
@@ -1,7 +1,7 @@
-import type { PageConfig } from '@types';
+import type { PageData } from '@types';
import { html } from '../utils/html';
-export const siteHeader = (config: PageConfig = {}) => html`
+export const siteHeader = (data: PageData) => html`