Inhaltliche Routen
Analog unterstützt auch die Verwendung von Markdown-Inhalten als Routen und das Rendern von Markdown-Inhalten in Komponenten.
Einrichtung
Fügen in der Datei src/app/app.config.ts die Funktion provideContent() zusammen mit der Funktion withMarkdownRenderer() in das Array providers ein.
import { ApplicationConfig } from '@angular/core';
import { provideContent, withMarkdownRenderer } from '@analogjs/content';
export const appConfig: ApplicationConfig = {
  providers: [
    // ... other providers
    provideContent(withMarkdownRenderer()),
  ],
};
Definieren von Inhaltsrouten
Die Inhaltsrouten unterstützen Frontmatter, Metatags und Syntaxhervorhebung mit PrismJS.
Die Beispielroute unten in src/app/pages/about.md definiert eine /about-Route.
---
title: About
meta:
  - name: description
    content: About Page Description
  - property: og:title
    content: About
---
## About Analog
Analog is a meta-framework for Angular.
[Back Home](./)
PrismJS-Syntaxhervorhebung
Analog unterstützt die Syntaxhervorhebung mit PrismJS. Um die Syntaxhervorhebung mit PrismJS zu aktivieren, füge withPrismHighlighter() zur Funktion provideContent() in app.config.ts hinzu.
import { ApplicationConfig } from '@angular/core';
import { provideContent, withMarkdownRenderer } from '@analogjs/content';
+ import { withPrismHighlighter } from '@analogjs/content/prism-highlighter';
export const appConfig: ApplicationConfig = {
  providers: [
    // ... other providers
-   provideContent(withMarkdownRenderer()),
+   provideContent(withMarkdownRenderer(), withPrismHighlighter()),
  ],
};
Verwendung des diff Highlight Plugins
Analog unterstützt das Hervorheben von Diff-Änderungen mit PrismJS.
Füge die Sprache prism-diff zu den additionalLangs im Plugin analog hinzu:
import { defineConfig } from 'vite';
import analog from '@analogjs/platform';
export default defineConfig({
  // ...
  plugins: [
    analog({
      content: {
        prismOptions: {
          additionalLangs: ['prism-diff'],
        },
      },
    }),
  ],
});
Fügen den Plugin-Import diff-highlight in die app.config.ts ein:
import 'prismjs/plugins/diff-highlight/prism-diff-highlight';
Verwenden den diff language tag, um es hervorzuheben oder
diff-<language>, um die Diff-Änderungen in einer bestimmten Sprache hervorzuheben.
```diff
- This is a sentence.
+ This is a longer sentence.
```
```diff-typescript
- const foo = 'bar';
+ const foo = 'baz';
```
Um geänderte Zeilenhintergründe und nicht nur den Text hervorzuheben, fügen Sie diesen Import in Ihr globales Stylesheet ein:
@import 'prismjs/plugins/diff-highlight/prism-diff-highlight.css';
Shiki Syntax-Hervorhebung
Analog unterstützt auch die Syntaxhervorhebung mit Shiki. Um die Syntaxhervorhebung mit Shiki zu aktivieren, füge withShikiHighlighter() zur Funktion provideContent() in app.config.ts hinzu.
import { ApplicationConfig } from '@angular/core';
import { provideContent, withMarkdownRenderer } from '@analogjs/content';
+ import { withShikiHighlighter } from '@analogjs/content/shiki-highlighter';
export const appConfig: ApplicationConfig = {
  providers: [
    // ... other providers
-   provideContent(withMarkdownRenderer()),
+   provideContent(withMarkdownRenderer(), withShikiHighlighter()),
  ],
};
Um die Syntaxhervorhebung mit shiki zu aktivieren, konfiguriere das Plugin analog in der vite.config.ts.
import { defineConfig } from 'vite';
import analog from '@analogjs/platform';
export default defineConfig({
  // ...
  plugins: [
    analog({
      content: {
        highlighter: 'shiki',
      },
    }),
  ],
});
Shiki Highlighter konfigurieren
Weitere Informationen zur Konfiguration von Shiki findest du unter [Shiki-Dokumentation] (https://shiki.style/).
Um Shiki zu konfigurieren, können Optionen an das Objekt shikiOptions übergeben werden.
import { defineConfig } from 'vite';
import analog from '@analogjs/platform';
export default defineConfig({
  // ...
  plugins: [
    analog({
      content: {
        highlighter: 'shiki',
        shikiOptions: {
          highlight: {
            // alternate theme
            theme: 'ayu-dark'
          }
          highlighter: {
             // add more languages
            additionalLangs: ['mermaid'],
          },
        },
      },
    }),
  ],
});
Standardmäßig hat shikiOptions die folgenden Optionen.
{
  "container": "%s",
  "highlight": {
    "theme": "github-dark"
  }
  "highlighter": {
    "langs": [
      "json",
      "ts",
      "tsx",
      "js",
      "jsx",
      "html",
      "css",
      "angular-html",
      "angular-ts",
    ],
    "themes": ["github-dark", "github-light"]
  }
}
Definieren von Inhaltsdateien
Für mehr Flexibilität können Markdown-Inhaltsdateien im Ordner src/content bereitgestellt werden. Hier könne Markdown-Dateien wie z. B. Blogbeiträge auflistet werden.
---
title: My First Post
slug: 2022-12-27-my-first-post
description: My First Post Description
coverImage: https://images.unsplash.com/photo-1493612276216-ee3925520721?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=464&q=80
---
Hello World
Verwendung der Liste der Inhaltsdateien
Um eine Liste mit der Inhaltsdateien im Ordner src/content zu erhalten, verwende die Funktion injectContentFiles<Attributes>(filterFn?: InjectContentFilesFilterFunction<Attributes>) aus dem Paket @analogjs/content in der Komponente. Um die Dateien einzugrenzen, kann die Prädikatsfunktion filterFn als Argument verwendet werden. Du kannst den Typ InjectContentFilesFilterFunction<T> verwenden, um Ihr Prädikat einzurichten.
import { Component } from '@angular/core';
import { RouterLink, RouterOutlet } from '@angular/router';
import { injectContentFiles } from '@analogjs/content';
import { NgFor } from '@angular/common';
export interface PostAttributes {
  title: string;
  slug: string;
  description: string;
  coverImage: string;
}
@Component({
  standalone: true,
  imports: [RouterOutlet, RouterLink, NgFor],
  template: `
    <ul>
      <li *ngFor="let post of posts">
        <a [routerLink]="['/blog', 'posts', post.slug]">{{
          post.attributes.title
        }}</a>
      </li>
    </ul>
  `,
})
export default class BlogComponent {
  readonly posts = injectContentFiles<PostAttributes>((contentFile) =>
    contentFile.filename.includes('/src/content/blog/')
  );
}
Verwendung der Analog Markdown-Komponente
Analog bietet eine MarkdownComponent und injectContent() Funktion für die Darstellung von Markdown-Inhalten mit Frontmatter.
Die Funktion injectContent() verwendet standardmäßig den Routenparameter slug, um die Inhaltsdatei aus dem Ordner src/content zu holen.
// /src/app/pages/blog/posts.[slug].page.ts
import { injectContent, MarkdownComponent } from '@analogjs/content';
import { AsyncPipe, NgIf } from '@angular/common';
import { Component } from '@angular/core';
export interface PostAttributes {
  title: string;
  slug: string;
  description: string;
  coverImage: string;
}
@Component({
  standalone: true,
  imports: [MarkdownComponent, AsyncPipe, NgIf],
  template: `
    <ng-container *ngIf="post$ | async as post">
      <h1>{{ post.attributes.title }}</h1>
      <analog-markdown [content]="post.content"></analog-markdown>
    </ng-container>
  `,
})
export default class BlogPostComponent {
  readonly post$ = injectContent<PostAttributes>();
}
Einen Resolver für Metatags verwenden
In Ihrer Routenkonfiguration kann das Objekt RouteMeta verwendet werden, um Meta-Tags für eine Route aufzulösen. Dies geschieht, indem der Eigenschaft meta die Funktion postMetaResolver zugewiesen wird.
Nachfolgend ein Beispiel für die Verwendung einer Funktion postMetaResolver, die die Meta-Tags für einen Beitrag abruft. Diese Funktion gibt ein Array von Meta-Tags zurück.
export const postMetaResolver: ResolveFn<MetaTag[]> = (route) => {
  const postAttributes = injectActivePostAttributes(route);
  return [
    {
      name: 'description',
      content: postAttributes.description,
    },
    {
      name: 'author',
      content: 'Analog Team',
    },
    {
      property: 'og:title',
      content: postAttributes.title,
    },
    {
      property: 'og:description',
      content: postAttributes.description,
    },
    {
      property: 'og:image',
      content: postAttributes.coverImage,
    },
  ];
};
Die Meta-Tags können auch asynchron erstellt werden. Weise dafür die Funktion postMetaResolver der Eigenschaft meta zu.
export const routeMeta: RouteMeta = {
  title: postTitleResolver,
  meta: postMetaResolver,
};
Auf die aufgelösten Meta-Tags kann in der Komponente auch über den Dienst ActivatedRoute zugegriffen werden.
export default class BlogPostComponent {
  readonly route = inject(ActivatedRoute);
  readonly metaTags$ = this.route.data.pipe(map(data => data['meta']));
  // In the template
  <my-component [metaTags]="metaTags$ | async"></my-component>
}
Unterstützung für Mermaid aktivieren
Die Markdown-Komponente von Analog unterstützen [Mermaid] (https://mermaid.js.org/). Um die Unterstützung durch die MarkdownComponent zu aktivieren, definiere einen dynamischen Import für loadMermaid in withMarkdownRenderer().
withMarkdownRenderer({
  loadMermaid: () => import('mermaid'),
});
Nach der Aktivierung werden Mermaid Blöcke von Mermaid in SVGs umgewandelt.
Beispiel für ein Mermaid-Diagramm:
graph TD
    A[Before] -->|Playing with AnalogJS| B(Now Yes !)
Unterstützung für Inhaltsunterverzeichnisse
Analog unterstützt auch Unterverzeichnisse innerhalb des Inhaltsordners.
Die Funktion injectContent() kann auch mit einem Objekt verwendet werden, das den Routenparameter und den Namen des Unterverzeichnisses enthält.
Dies kann nützlich sein, wenn z.B. Blog-Posts sowie ein Portfolio von Projekten als Markdown-Dateien vorhanden sind, die auf der Website verwendet werden sollen.
src/
└── app/
│   └── pages/
│       └── project.[slug].page.ts
└── content/
    ├── posts/
    │   ├── my-first-post.md
    │   └── my-second-post.md
    └── projects/
          ├── my-first-project.md
        └── my-second-project.md
// /src/app/pages/project.[slug].page.ts
import { injectContent, MarkdownComponent } from '@analogjs/content';
import { AsyncPipe, NgIf } from '@angular/common';
import { Component } from '@angular/core';
export interface ProjectAttributes {
  title: string;
  slug: string;
  description: string;
  coverImage: string;
}
@Component({
  standalone: true,
  imports: [MarkdownComponent, AsyncPipe, NgIf],
  template: `
    <ng-container *ngIf="project$ | async as project">
      <h1>{{ project.attributes.title }}</h1>
      <analog-markdown [content]="project.content"></analog-markdown>
    </ng-container>
  `,
})
export default class ProjectComponent {
  readonly project$ = injectContent<ProjectAttributes>({
    param: 'slug',
    subdirectory: 'projects',
  });
}
Laden benutzerdefinierter Inhalte
Standardmäßig verwendet Analog die Route-Parameter, um den Dateinamen für den Abruf einer Inhaltsdatei aus dem Ordner src/content zu erstellen. Analog unterstützt auch die Verwendung eines benutzerdefinierten Dateinamens für das Abrufen von Inhalten aus dem Ordner src/content. Dies kann nützlich sein, wenn es zum Beispiel eine benutzerdefinierte Markdown-Datei gibt, die auf einer Seite geladen werden soll.
Die Funktion injectContent() kann verwendet werden, indem ein Objekt übergeben wird, das die Eigenschaft customFilename enthält.
readonly post$ = injectContent<ProjectAttributes>({
  customFilename: 'path/to/custom/file',
});