Closed brandonroberts closed 1 year ago
@brandonroberts
What do you think about having a more flexible result, so attributes type can be provided based on the project needs? This will also provide the ability to set proper typing for plain markdown content without frontmatter.
export interface ContentFile<
Attributes extends Record<string, any> = Record<string, any>
> {
filename: string;
content: string;
attributes: Attributes;
}
const CONTENT_FILES_TOKEN = new InjectionToken<ContentFile[]>(
'@analogjs/content Content Files',
{
providedIn: 'root',
factory() {
const rawContentFiles = import.meta.glob('/src/content/**/*.md', {
eager: true,
as: 'raw',
});
return Object.keys(rawContentFiles).map((filename) => {
const { body, attributes } = fm<Record<string, any>>(
rawContentFiles[filename]
);
return {
filename,
content: body,
attributes,
};
});
},
}
);
export function injectContentFiles<
Attributes extends Record<string, any>
>(): ContentFile<T>[] {
return inject(CONTENT_FILES_TOKEN) as ContentFile<Attributes>[];
}
// usage:
interface PostAttributes {
title: string;
coverSrc: string;
published: boolean;
}
@Component({
selector: 'app-blog',
standalone: true,
imports: [NgFor],
template: `
<article *ngFor="let post of publishedPosts">
<h2>{{ post.attributes.title }}</h2>
<img [src]="post.attributes.coverSrc" [alt]="post.attributes.title" />
</article>
`,
})
export default class BlogComponent {
private readonly posts = injectContentFiles<PostAttributes>();
readonly publishedPosts = this.posts.filter(
(post) => post.attributes.published
);
}
Changes:
injectContentMetadata
is renamed to injectContentFiles
.frontmatter
is renamed to attributes
.AnalogContentMetadata
is renamed to ContentFile
and Frontmatter
is removed, so attributes can be typed via generic.Definitely prefer the more flexible option with better types.
@markostanimirovic @brandonroberts I can implement as laid out here: https://github.com/analogjs/analog/issues/222#issuecomment-1384677257 If you guys are not already working on this and want to assign this issue to me 👍
@goetzrobin 👍
Which scope/s are relevant/related to the feature request?
content
Information
Define an injectable token or service that provides a list of the files markdown files scanned from the
src/content
folder in an array that includes frontmatter.Example structure below
Usage
This could be used to list blog posts for example and could be filtered further based on needs, such as only listing
published
posts as an example.Describe any alternatives/workarounds you're currently using
No response
I would be willing to submit a PR to fix this issue