Refactor how post meta is parsed

This commit is contained in:
Will Boyd
2025-02-05 15:58:26 -05:00
parent 5f5ab6f2bd
commit 9fb7ae47c5
3 changed files with 37 additions and 57 deletions
+6 -6
View File
@@ -17,16 +17,16 @@ export function categories(post) {
return categories.filter((category) => category !== 'uncategorized'); return categories.filter((category) => category !== 'uncategorized');
} }
// get cover image filename, previously decoded and set on post.meta // get cover image filename, previously decoded and set on post
// this one is unique as it relies on special logic executed by the parser // this one is unique as it relies on special logic executed by the parser
export function coverImage(post) { export function coverImage(post) {
return post.meta.coverImage; return post.coverImage;
} }
// get post date, previously saved as a luxon datetime object on post.meta // get post date, previously saved as a luxon datetime object on post
// this value is also used for year/month folders, date prefixes, etc. as needed // this value is also used for year/month folders, date prefixes, etc. as needed
export function date(post) { export function date(post) {
return post.meta.date; return post.date;
} }
// get excerpt, not decoded, newlines collapsed // get excerpt, not decoded, newlines collapsed
@@ -39,9 +39,9 @@ export function id(post) {
return post.data.post_id[0]; return post.data.post_id[0];
} }
// get slug, previously decoded and set on post.meta // get slug, previously decoded and set on post
export function slug(post) { export function slug(post) {
return post.meta.slug; return post.slug;
} }
// get array of decoded tag names // get array of decoded tag names
+28 -43
View File
@@ -60,26 +60,7 @@ function collectPosts(channelData, postTypes, config) {
const postsForType = getItemsOfType(channelData, postType) const postsForType = getItemsOfType(channelData, postType)
.filter(postData => postData.status[0] !== 'trash' && postData.status[0] !== 'draft') .filter(postData => postData.status[0] !== 'trash' && postData.status[0] !== 'draft')
.filter(postData => !(postType === 'page' && postData.post_name[0] === 'sample-page')) .filter(postData => !(postType === 'page' && postData.post_name[0] === 'sample-page'))
.map(postData => ({ .map(postData => buildPost(postData, turndownService, config));
// raw post data, used by frontmatter getters
data: postData,
// meta data isn't written to file, but is used to help with other things
meta: {
type: postType,
id: getPostId(postData),
slug: getPostSlug(postData),
date: getPostDate(postData, config),
coverImageId: getPostCoverImageId(postData),
// these are possibly set later in mergeImagesIntoPosts()
coverImage: undefined,
imageUrls: []
},
// contents of the post in markdown
content: translator.getPostContent(postData, turndownService, config)
}));
if (postTypes.length > 1) { if (postTypes.length > 1) {
console.log(`${postsForType.length} "${postType}" posts found.`); console.log(`${postsForType.length} "${postType}" posts found.`);
@@ -94,26 +75,30 @@ function collectPosts(channelData, postTypes, config) {
return allPosts; return allPosts;
} }
function getPostId(postData) { function buildPost(data, turndownService, config) {
return postData.post_id[0]; return {
// full raw post data, used by some frontmatter getters
data,
// contents of the post in markdown
content: translator.getPostContent(data, turndownService, config),
// these are not written to file, but help with other things
type: data.post_type[0],
id: data.post_id[0],
slug: decodeURIComponent(data.post_name[0]),
date: luxon.DateTime.fromRFC2822(data.pubDate[0], { zone: config.customDateTimezone }),
coverImageId: getPostMetaValue(data.postmeta, '_thumbnail_id'),
// these are possibly set later in mergeImagesIntoPosts()
coverImage: undefined,
imageUrls: []
};
} }
function getPostSlug(postData) { function getPostMetaValue(metas, key) {
return decodeURIComponent(postData.post_name[0]); const meta = metas && metas.find((meta) => meta.meta_key[0] === key);
} return meta ? meta.meta_value[0] : undefined;
function getPostDate(postData, config) {
return luxon.DateTime.fromRFC2822(postData.pubDate[0], { zone: config.customDateTimezone });
}
function getPostCoverImageId(postData) {
if (postData.postmeta === undefined) {
return undefined;
}
const postmeta = postData.postmeta.find(postmeta => postmeta.meta_key[0] === '_thumbnail_id');
const id = postmeta ? postmeta.meta_value[0] : undefined;
return id;
} }
function collectAttachedImages(channelData) { function collectAttachedImages(channelData) {
@@ -161,18 +146,18 @@ function mergeImagesIntoPosts(images, posts) {
let shouldAttach = false; let shouldAttach = false;
// this image was uploaded as an attachment to this post // this image was uploaded as an attachment to this post
if (image.postId === post.meta.id) { if (image.postId === post.id) {
shouldAttach = true; shouldAttach = true;
} }
// this image was set as the featured image for this post // this image was set as the featured image for this post
if (image.id === post.meta.coverImageId) { if (image.id === post.coverImageId) {
shouldAttach = true; shouldAttach = true;
post.meta.coverImage = shared.getFilenameFromUrl(image.url); post.coverImage = shared.getFilenameFromUrl(image.url);
} }
if (shouldAttach && !post.meta.imageUrls.includes(image.url)) { if (shouldAttach && !post.imageUrls.includes(image.url)) {
post.meta.imageUrls.push(image.url); post.imageUrls.push(image.url);
} }
}); });
}); });
+3 -8
View File
@@ -54,7 +54,7 @@ async function writeMarkdownFilesPromise(posts, config) {
} else { } else {
const payload = { const payload = {
item: post, item: post,
name: post.meta.type + ' - ' + post.meta.slug, name: post.type + ' - ' + post.slug,
destinationPath, destinationPath,
delay delay
}; };
@@ -112,7 +112,7 @@ async function writeImageFilesPromise(posts, config) {
const payloads = posts.flatMap(post => { const payloads = posts.flatMap(post => {
const postPath = buildPostPath(post, config); const postPath = buildPostPath(post, config);
const imagesDir = path.join(path.dirname(postPath), 'images'); const imagesDir = path.join(path.dirname(postPath), 'images');
return post.meta.imageUrls.flatMap(imageUrl => { return post.imageUrls.flatMap(imageUrl => {
const filename = shared.getFilenameFromUrl(imageUrl); const filename = shared.getFilenameFromUrl(imageUrl);
const destinationPath = path.join(imagesDir, filename); const destinationPath = path.join(imagesDir, filename);
if (checkFile(destinationPath)) { if (checkFile(destinationPath)) {
@@ -177,12 +177,7 @@ async function loadImageFilePromise(imageUrl, config) {
} }
function buildPostPath(post, config) { function buildPostPath(post, config) {
const outputDir = config.output; return shared.buildPostPath(config.output, post.type, post.date, post.slug, config);
const type = post.meta.type;
const date = post.meta.date;
const slug = post.meta.slug;
return shared.buildPostPath(outputDir, type, date, slug, config);
} }
function checkFile(path) { function checkFile(path) {