volpe/posts/posts.11tydata.js

121 lines
No EOL
3 KiB
JavaScript

const path = require("path");
const fs = require("fs");
const { execSync } = require("child_process");
const { DateTime } = require("luxon");
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 DateTime.fromISO(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 DateTime.fromISO(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);
const time = stats.birthtime ?? stats.mtime;
return DateTime.fromJSDate(time);
} catch (e) {
return null;
}
}
const getFileModifiedTime = (filePath) => {
try {
const stats = fs.statSync(filePath);
return DateTime.fromJSDate(stats.mtime);
} catch (e) {
return null;
}
}
const parseDate = (value) => {
if (!value) return null;
if (DateTime.isDateTime(value)) return value;
if (value instanceof Date) return DateTime.fromJSDate(value);
const parsed = DateTime.fromISO(value);
return parsed.isValid ? parsed : null;
}
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 DateTime.fromJSDate(data.page.date);
}
module.exports = {
layout: "post.njk",
tags: ["posts"],
eleventyComputed: {
released: (data) => {
if(data.page.inputPath.startsWith('./posts/drafts/')) {
return false
}
return true
},
title: (data) => {
if (data.title && data.title !== data.page.fileSlug) {
return data.title;
}
return getTitleFromFilename(data.page.inputPath);
},
createdAt: getPostCreatedAt,
updatedAt: (data) => {
return parseDate(data.updatedAt) ??
getGitModifiedTime(data.page.inputPath) ??
getFileModifiedTime(data.page.inputPath);
},
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.toISODate();
return `/post/${slug}/${isoDate}/`;
}
}
};