content
Currently if you want to display a single post, you can use the injectContent()
function to get the rendered markdown as a string. If you want to display the metadata from the content within the component, you basically have to reimplement injectContent()
to return the content with metadata.
import { AsyncPipe, DatePipe, NgIf } from '@angular/common';
import { Component } from '@angular/core';
import { MarkdownComponent } from '@analogjs/content';
import { ContentFile, injectContentFiles } from '@analogjs/content';
import { injectActivatedRoute } from '@analogjs/router';
export function injectPost(slug: string) {
const route = injectActivatedRoute();
return injectContentFiles<Post>().find(
(posts) =>
posts.filename === `/src/content/${route.snapshot.paramMap.get(slug)}.md`
);
}
@Component({
selector: 'post',
standalone: true,
imports: [MarkdownComponent, AsyncPipe, NgIf, DatePipe, ReadingTimePipe],
template: `
<div class="flex flex-grow justify-center min-h-screen" *ngIf="post">
<article class="w-screen max-w-4xl p-8">
<h2 class="text-gray-600 text-2xl">{{ post.attributes.title }}</h2>
<span class="font-light text-sm">
{{ post.attributes.publishedDate | date : 'MMMM dd, yyyy' }} -
{{ post.content | readingtime }} min read
</span>
<analog-markdown [content]="post.content"></analog-markdown>
</article>
</div>
`,
})
export default class BlogPostComponent {
post = injectPost('slug');
}
The proposed change would return the content with metadata instead of the string itself
import { AsyncPipe, DatePipe, NgIf } from '@angular/common';
import { Component } from '@angular/core';
import { MarkdownComponent, injectContent } from '@analogjs/content';
export interface Post {
title: string;
slug: string;
published: boolean;
publishedDate: string;
}
@Component({
selector: 'post',
standalone: true,
imports: [MarkdownComponent, AsyncPipe, NgIf, DatePipe, ReadingTimePipe],
template: `
<div class="flex flex-grow justify-center min-h-screen" *ngIf="post">
<article class="w-screen max-w-4xl p-8">
<h2 class="text-gray-600 text-2xl">{{ post.attributes.title }}</h2>
<span class="font-light text-sm">
{{ post.attributes.publishedDate | date : 'MMMM dd, yyyy' }} -
{{ post.content | readingtime }} min read
</span>
<analog-markdown [content]="post.content"></analog-markdown>
</article>
</div>
`,
})
export default class BlogPostComponent {
post = injectContent<Post>();
}
No response
@brandonroberts just ran into the same issue working on my personal website! I can work on this if you want
Awesome! What do you think we should do when no file is found for the current route?
Currently the customFallback
param is returned.
When returning an object we have other options:
export function injectContent<
Attributes extends Record<string, any> = Record<string, any>
>(
param = 'slug',
fallback = 'No Content Found'
): Observable<ContentFile<Attributes> | undefined> {
const route = inject(ActivatedRoute);
const contentFiles = injectContentFiles<Attributes>();
return route.paramMap.pipe(
map((params) => params.get(param)),
map((slug) => {
return contentFiles.find(
(file) => file.filename === `/src/content/${slug}.md`
);
})
);
}
customFallback
as its contentexport function injectContent<
Attributes extends Record<string, any> = Record<string, any>
>(
param = 'slug',
fallback = 'No Content Found'
): Observable<ContentFile<Attributes | Record<string, never>>> {
const route = inject(ActivatedRoute);
const contentFiles = injectContentFiles<Attributes | Record<string, never>>();
return route.paramMap.pipe(
map((params) => params.get(param)),
map((slug) => {
return (
contentFiles.find(
(file) => file.filename === `/src/content/${slug}.md`
) || {
attributes: {},
filename: '',
content: fallback,
}
);
})
);
}
Let me know what you think
Owner Name | analogjs |
Repo Name | analog |
Full Name | analogjs/analog |
Language | TypeScript |
Created Date | 2022-07-06 |
Updated Date | 2023-03-28 |
Star Count | 885 |
Watcher Count | 18 |
Fork Count | 67 |
Issue Count | 33 |
Issue Title | Created Date | Updated Date |
---|