#Getting slug of CC rendered page from filename

5 messages · Page 1 of 1 (latest)

obtuse cove
#

I am generating pages for a Content Collection using their filenames and am trying to figure out the best way to pass the desired URL for link rendering on other pages.

example article at src/content/articles/1970-01-01-example_article.md being rendered via src/pages/[year]/[month]/[day]/[article].astro:

---
import { PageLayout } from "salt-theme:layouts";

import { getCollection, render } from "astro:content";
export async function getStaticPaths() {
    const articles = await getCollection("articles");
    return articles.map((article) => ({
        params: {
            year: article.id.slice(0,4),
            month: article.id.slice(5,7),
            day: article.id.slice(8,10),
            article: article.id.slice(11),
         },
        props: {
            article,
        },
    }));
}

const { article } = Astro.props;
const { Content } = await render(article);
---

<PageLayout>
    <Content />
</PageLayout>

example of listing:

---
import { getCollection } from "astro:content";
const articles = await getCollection("articles");
---

<ul>
    {articles.map((post) =>
        <li><a href={post.data.slug}>{post.data.title}</a></li>
        <li><a href={`${post.id.slice(0,4)}/${post.id.slice(5,7)}/${post.id.slice(8,10)}/${post.id.slice(11)}`}>{post.data.title}</a></li>
    )}
</ul>

The first listing item is the sort of thing I'd like to use, because while the second one works, it is pretty clunky.

I'd assume there is a way to inject a new slug value via the renderer props but am not quite sure how.

I've also explored the API reference and was wondering if there is perhaps a way to query routePattern or get a context object within the Collect mapping?

All suggestions and directions appreciated!

candid bear
#

I think it's impossible to do that out of the box. I would recommend using a separate function to generate a slug from an entry name and using it whenever you need a slug. Or just wrap getCollection to add slugs to entries when requesting them using the same function.
Alternatively, you can try creating an extension to automatically add slugs. I am unfamiliar with Astro's extension system, so it's up to you to explore this option on your own.

obtuse cove
#

I suppose a related question is whether there is an easy way to override the object props to add a field? For instance, if I run a function that extracts the date from filenames can I then inject that date into the props?

candid bear
#

Can you elaborate on the use case you are asking about?
One of the approaches I have suggested is to simply wrap article collection request in another function, which will add slug property to entries. Like this:

const map = (name) => {
  const [year, month, day, article] = article.split('-');
  return { year, month, day, article };
};

const getArticles = async () => {
  const articles = await getCollection("articles");
  return articles.map((article) => ({...article, slug: map(article.id) }))
}
obtuse cove
#

I think that answers my question, will experiment a bit