-
I use createContentLoader on my site to create an index page that contains a summary of many articles, that can further be sorted/filtered with Vue Component toggles - it's very handy and is a great way to collaborate/communicate on articles. One limitation that I've been unable to solve, is that I've been unable to list the lastUpdated page data of each page with the other frontmatter page properties that collect . In my all-articles.md page I have this in my script;
I've had a tinker, but I don't think it's returning the lastUpdated page property with the page frontmatter properties. LastUpdated is working as I expect. It's enabled within my project and returns the committed date within the page footer, but I'd like a better understanding of how else I can capture/combine the lastUpdated page property via createContentLoader. Is it possible to import the lastUpdated property from each page and combine with my posts data, so it can too be displayed in the index page summary info? EDIT:
The above snippet draws in the post.frontmatter and displays the post title as expected. I'm attempting to do the same thing with lastupdated.
I've tried this, but unfortunately didn't work. Appreciate any help with this. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
Finding more time to experiment, learn and debug, I loaded the below into a page on my site and opened up F12 in the browser.
This allowed me to inspect the content of posts where I then confirmed that it doesn't contain the last-updated data, hence a last updated date can't be extracted through its use. How might I return the last updated dates as an object, similar to how createContentLoader draws in all of the frontmatter data? That way I could then combine the two objects and introduce some useful filter/sorts to find articles, using their last-updated date. |
Beta Was this translation helpful? Give feedback.
-
Just to comment here and thank @brc-dd for their great help, this script worked very well; import { spawn } from "cross-spawn";
import fs from "fs";
import path from "path";
import pMap from "p-map";
import { createContentLoader } from "vitepress";
// Define the custom loader using createContentLoader
const loader = createContentLoader("/**/*.md", {
async transform(rawData) {
const data = await pMap(
rawData,
async (item) => {
// console.log(item.url);
const lastUpdated = await getLastUpdated(item.url);
return { ...item, lastUpdated };
},
{ concurrency: 64 }
);
// Sort the data based on the lastUpdated field
data.sort((a, b) => b.lastUpdated - a.lastUpdated);
// console.log(JSON.stringify(data, null, 2));
return data;
},
});
// getLastUpdated function to fetch the last update time of a markdown file
async function getLastUpdated(url) {
// Access global VITEPRESS_CONFIG
const siteConfig = globalThis.VITEPRESS_CONFIG;
let file = url.replace(/(^|\/)$/, "$1index");
file = file.replace(/(\.html)?$/, ".md");
file = siteConfig.rewrites.inv[file] || file;
file = path.join(siteConfig.srcDir, file);
return new Promise((resolve, reject) => {
const cwd = path.dirname(file);
if (!fs.existsSync(cwd)) return resolve(0);
const fileName = path.basename(file);
const child = spawn("git", ["log", "-1", '--pretty="%ai"', fileName], {
cwd,
});
let output = "";
child.stdout.on("data", (data) => (output += String(data)));
child.on("close", () => resolve(new Date(output).getTime()));
child.on("error", reject);
});
}
// Export the data and the loader
export const data = await loader.load();
export default loader; |
Beta Was this translation helpful? Give feedback.
Just to comment here and thank @brc-dd for their great help, this script worked very well;