Naposledy aktivní 1746391523

I needed to convert 11ty formatted frontmatter to use Astro syntax for 20+ files. I needed it quickly and ChatGPT gave me the basics. Included is the chat with the bot so you can tweak it to suit your needs.

11ty-to-astro.mjs Raw
1// ChatGPT conversation to help with this script:
2// https://chatgpt.com/share/6817d17d-5a24-8002-9471-b5aa174f689d
3
4import fs from "fs";
5import path from "path";
6import matter from "gray-matter";
7import yaml from "js-yaml";
8
9// Configuration
10const inputDir = "./src/content/post/"; // Folder containing markdown files
11const backupDir = "./backup"; // Backup before modifying
12
13// Create backup directory if it doesn't exist
14if (!fs.existsSync(backupDir)) {
15 fs.mkdirSync(backupDir);
16}
17
18// Preferred frontmatter key order
19const preferredKeyOrder = [
20 "title",
21 "description",
22 "publishDate",
23 "updatedDate",
24 "tags",
25 "slug",
26 "draft",
27];
28
29function sortFrontmatterKeys(data) {
30 const sorted = {};
31 preferredKeyOrder.forEach((key) => {
32 if (data[key] !== undefined) {
33 sorted[key] = data[key];
34 }
35 });
36 Object.keys(data).forEach((key) => {
37 if (!sorted.hasOwnProperty(key)) {
38 sorted[key] = data[key];
39 }
40 });
41 return sorted;
42}
43
44// Format dates consistently
45function formatDate(value) {
46 if (value instanceof Date) {
47 return value.toISOString().split("T")[0];
48 }
49 return value;
50}
51
52// Extract date from filename if present
53function extractDateFromFilename(filename) {
54 const match = filename.match(/^(\d{4}-\d{2}-\d{2})-(.+)$/);
55 if (match) {
56 return {
57 date: match[1],
58 newFilename: match[2],
59 };
60 }
61 return null;
62}
63
64// Clean and fix a single file
65function fixFile(filePath) {
66 const rawContent = fs.readFileSync(filePath, "utf8");
67 const { data: frontmatter, content } = matter(rawContent);
68
69 let cleanedFrontmatter = { ...frontmatter };
70 const fileName = path.basename(filePath);
71 const dateInfo = extractDateFromFilename(fileName);
72
73 // Move date from filename into publishDate if missing
74 if (dateInfo) {
75 if (!cleanedFrontmatter.publishDate) {
76 cleanedFrontmatter.publishDate = dateInfo.date;
77 }
78 }
79
80 // Rename "date" -> "publishDate" if necessary
81 if (cleanedFrontmatter.date && !cleanedFrontmatter.publishDate) {
82 cleanedFrontmatter.publishDate = cleanedFrontmatter.date;
83 delete cleanedFrontmatter.date;
84 }
85
86 // Fix date formats
87 Object.keys(cleanedFrontmatter).forEach((key) => {
88 if (key.toLowerCase().includes("date")) {
89 cleanedFrontmatter[key] = formatDate(cleanedFrontmatter[key]);
90 }
91 });
92
93 // If publishDate missing, set draft: true
94 if (
95 !cleanedFrontmatter.publishDate && cleanedFrontmatter.draft === undefined
96 ) {
97 cleanedFrontmatter.draft = true;
98 }
99
100 // Sort frontmatter keys
101 cleanedFrontmatter = sortFrontmatterKeys(cleanedFrontmatter);
102
103 const yamlContent = yaml.dump(cleanedFrontmatter, {
104 lineWidth: 1000,
105 quotingType: '"',
106 });
107
108 const finalContent = `---\n${yamlContent}---\n\n${content.trim()}\n`;
109
110 // Backup original
111 const backupPath = path.join(backupDir, fileName);
112 fs.copyFileSync(filePath, backupPath);
113
114 // Determine new filename
115 let outputPath = filePath;
116 if (dateInfo) {
117 const newFilename = dateInfo.newFilename;
118 outputPath = path.join(path.dirname(filePath), newFilename);
119 }
120
121 // Write cleaned file (possibly with new filename)
122 fs.writeFileSync(outputPath, finalContent, "utf8");
123
124 // If filename changed, delete the old file
125 if (outputPath !== filePath) {
126 fs.unlinkSync(filePath);
127 console.log(`Fixed & Renamed: ${fileName} -> ${path.basename(outputPath)}`);
128 } else {
129 console.log(`Fixed: ${fileName}`);
130 }
131}
132
133// Process all markdown files
134function fixAllFiles() {
135 const files = fs.readdirSync(inputDir);
136 files.forEach((file) => {
137 if (file.endsWith(".md")) {
138 fixFile(path.join(inputDir, file));
139 }
140 });
141}
142
143fixAllFiles();