Replies: 3 comments
-
I agree with you. |
Beta Was this translation helpful? Give feedback.
-
I agree it would be nice if there was official API flexibility to modify the built-in behavior such as with an optional slugify callback for a content collection. Otherwise the built-in behaviour has to be overridden somewhere meanwhile that default behaviour is always there. Sure this is easy enough to do but it can arguably make a codebase harder to understand to devs less familiar with Astro -- especially when code does something that seems to betray documented functionality, especially if that code is written somewhere other than where the content collection is defined. A recent use-case was a project with a preference to have the date in filename of blog posts with date prefix not to be included in the slug. Another would be incorporating a directory organization scheme of a given content collection into the slug per a certain convention. Any custom slugify / override callback should be given full data (not just be passed the |
Beta Was this translation helpful? Give feedback.
-
Seconding this suggestion. I have also run into a similar use-case as the one mentioned by @firxworx . For reference, I am providing the workaround approach I have used in my case below: // src/utils/aug.ts
import {
type AnyEntryMap,
type CollectionEntry,
getCollection,
} from "astro:content";
import path from "path";
/**
* Extract slug and date from the provided filepath,
* mimicing behaviour from Jekyll.
*/
export async function parseFilepath(filepath: string): Promise<{
slug: string;
date: Date;
}> {
let baseName = path.basename(filepath, path.extname(filepath));
let parts = baseName.split("-");
let date = new Date(parts.slice(0, 3).join("-"));
let slug = parts.slice(3).join("-");
return { slug, date };
}
export type CollectionEntryAug<C extends keyof AnyEntryMap> =
// the type of 'slug' is relaxed to be any string
// also a new property 'date' is added
Omit<CollectionEntry<C>, "slug"> & {
slug: string;
date: Date;
};
/**
* Augment an entry with slug and date properties, parsed from its filepath.
*/
export async function augmentEntry<C extends keyof AnyEntryMap>(
entry: CollectionEntry<C>,
): Promise<CollectionEntryAug<C>> {
let { slug, date } = await parseFilepath(entry.id);
return {
...entry,
// || to allow for file-based metadata being overriden in frontmatter
slug: entry.data.slug || slug,
date: entry.data.date || date,
};
}
export async function getCollectionAug<C extends keyof AnyEntryMap>(
collection: C,
): Promise<CollectionEntryAug<C>[]> {
let entries = await getCollection(collection);
return Promise.all(entries.map(augmentEntry));
} The solution above not only modifies the slug from the filename, but also makes available the parsed It is a drop-in workaround, where you can (almost always) replace I also found another workaround approach here: https://equk.co.uk/2023/02/02/generating-slug-from-title-in-astro/ Note: neither of these workarounds address using |
Beta Was this translation helpful? Give feedback.
-
Body
Summary
Currently the slug is either based on file name, or comes from the value of
slug
in front matter.This works for simple use cases. But needs lot of duplicatation and manual updation.
Background & Motivation
Urls of our pages are generated based on multiple fields which comes from frontmatter
Any change in how slugs should be generated forces us to fix slugs in every page.
Goals
Beta Was this translation helpful? Give feedback.
All reactions