feat: created basic blog layout

This commit is contained in:
Leyla Becker 2026-02-10 11:02:43 -06:00
parent 42fd071301
commit 0d41db36ef
13 changed files with 935 additions and 3 deletions

122
posts/posts.11tydata.js Normal file
View file

@ -0,0 +1,122 @@
const path = require("path");
const fs = require("fs");
const { execSync } = require("child_process");
const getGitCreatedTime = (filePath) => {
try {
const result = execSync(
`git log --diff-filter=A --follow --format=%aI -- "${filePath}" | tail -1`,
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
).trim();
if (result) {
return new Date(result);
}
} catch (e) {
// Git command failed, return null
}
return null;
};
const getGitModifiedTime = (filePath) => {
try {
const result = execSync(
`git log -1 --format=%aI -- "${filePath}"`,
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
).trim();
if (result) {
return new Date(result);
}
} catch (e) {
// Git command failed, return null
}
return null;
};
const getTitleFromFilename = (filePath) => {
const basename = path.basename(filePath, '.md');
return basename
.split('-')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
}
const getFileCreatedTime = (filePath) => {
try {
const stats = fs.statSync(filePath);
return stats.birthtime || stats.mtime;
} catch (e) {
return null;
}
}
const getFileModifiedTime = (filePath) => {
try {
const stats = fs.statSync(filePath);
return stats.mtime;
} catch (e) {
return null;
}
}
const parseDate = (value) => {
if (!value) return null;
if (value instanceof Date) return value;
const parsed = new Date(value);
return isNaN(parsed.getTime()) ? null : parsed;
}
const getPostCreatedAt = (data) => {
const frontmatterDate = parseDate(data.createdAt);
if (frontmatterDate) {
return frontmatterDate;
}
const gitDate = getGitCreatedTime(data.page.inputPath);
if (gitDate) {
return gitDate;
}
const fileDate = getFileCreatedTime(data.page.inputPath);
if (fileDate) {
return fileDate;
}
return data.page.date;
}
module.exports = {
layout: "post.njk",
tags: ["posts"],
unreleased: false,
eleventyComputed: {
title: (data) => {
if (data.title && data.title !== data.page.fileSlug) {
return data.title;
}
return getTitleFromFilename(data.page.inputPath);
},
createdAt: getPostCreatedAt,
updatedAt: (data) => {
const modifiedDate = parseDate(data.updatedAt) ??
getGitModifiedTime(data.page.inputPath) ??
getFileModifiedTime(data.page.inputPath);
const createdDate = getPostCreatedAt(data);
if (modifiedDate) {
// Only return updatedAt if it's AFTER created date (by more than a day)
const dayInMs = 24 * 60 * 60 * 1000;
if (modifiedDate > createdDate && (modifiedDate - createdDate) > dayInMs) {
return modifiedDate;
}
}
return createdDate;
},
permalink: (data) => {
const title = data.title || getTitleFromFilename(data.page.inputPath);
const slug = title.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, '');
const createdDate = getPostCreatedAt(data);
const isoDate = createdDate.toISOString().split('T')[0];
return `/post/${slug}/${isoDate}/`;
}
}
};