Redéfinir le markdown angulaire avec Analog.js

L’analogique en est encore à ses débuts, mais il se passe beaucoup de choses ! Parcourez une application de démonstration pour explorer les fonctionnalités et découvrez ses capacités de démarque.
Je suis intrigué par Analog depuis que j’ai vu la vidéo de Brandon Roberts le montrant en train de construire Angulaire avec Vite. C’était la première étape pour obtenir le package Angular SSR que nous souhaitions vraiment.
L’équipe Angular a incroyablement intensifié son jeu au cours de la dernière année et demie, mais Angular SSR ne peut toujours même pas être déployé sur Vercel ou Cloudflare sans Analog sans problème. Je pense que cela finira par être corrigé lorsqu’ils fusionneront avec Asle framework interne de Google, mais pour l’instant nous avons Analog.
j’ai construit un Application Todo analogique avec Firebase pour montrer quelques nouvelles fonctionnalités, mais maintenant je suis plus intrigué par les capacités de démarque. Markdown est intégré.
TL;DR
Nous allons créer un blog avec Analogique! Ma version se concentre sur le .md
fichiers au lieu du content
annuaire. Vous pouvez créer des fichiers de démarques dans le pages
répertoire, et cela fonctionne. J’ai également ajouté la possibilité d’analyser les fichiers de démarques dans le pages
répertoire pour les titres et les métadonnées, qui ne fonctionne pas immédiatement. L’analogique pourrait être meilleur, mais il facilite le déploiement et la gestion du serveur !
Créez notre application
Tout d’abord, nous devons créer notre application analogique.
npm create analog@latest
L’analogique prend en charge le ng update
format. Si nous voulons mettre à jour plus tard, nous pouvons utiliser :
ng update @analogjs/platform@latest
Analog utilise Vite avec Angular, nous pouvons donc exécuter npm run start
ou npm run dev
ou ng serve
.
npm run start
Analog prend en charge Markdown et Front-matter
Si vous souhaitez créer un fichier markdown, créez un .md
fichier avec votre contenu et placez les métadonnées de première ligne en haut. Ceci est similaire à Contenu Nuxt. Nous avons également besoin d’un PostAttribute
taper. Nous pouvons mettre ça dedans models.ts
.
export interface PostAttributes {
title: string;
slug: string;
description: string;
publishedAt: string;
content: string;
};
Contenu
Écrivez vos articles et mettez-les dans le pages/blog
dossier. J’aime séparer mes fichiers habituels de ma démarque. J’ai généré des articles sur l’IA. Mon application utilise également Tailwind. Le slug
doit correspondre au nom du fichier. Assurez-vous que le moteur de rendu Markdown est activé app.config.ts
.
provideContent(withMarkdownRenderer())
Composant d’application
Il s’agit de votre composant d’accueil, où vous pouvez déclarer votre mise en page. j’utilise prose
de Tailwind pour définir les styles ici. Je génère également un an pour un droit d’auteur.
📝 Généralement, vous souhaitez générer les années et les dates sur le serveur puis hydrater la valeur du serveur auprès du client ; sur Le jour de l’An la date de votre serveur peut ne pas se réhydrater avec la même année que celle du client. J’ai juste simplifié le code.
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet],
template: `
<main class="p-3 m-3 prose md:prose-lg lg:prose-xl max-w-none">
<router-outlet></router-outlet>
<p>© Rocky Billy {{ year }}</p>
</main>
`,
styles: [],
})
export class AppComponent {
readonly year = new Date().getFullYear();
}
Résolveurs
La clé pour utiliser Angular SSR est de toujours utiliser des résolveurs lors du chargement des données. Si vous ne le faites pas, vos données risquent de ne pas se charger complètement avant que l’application ne soit rendue. Voici quelques fonctions d’assistance que j’ai créées pour cela.
export const injectResolver = <T>(name: string) =>
inject(ActivatedRoute).data.pipe<T>(map(r => r[name]));
export const injectSnapResolver = <T>(name: string) =>
inject(ActivatedRoute).snapshot.data[name] as T;
Cela facilite l’injection des données.
Obtenir la démarque
Actuellement, il n’existe aucune méthode permettant d’obtenir des noms de fichiers en dehors du content
annuaire. J’ai purgé le code source pour comprendre comment procéder. import.meta.glob
est la fonction magique Vite qui vous permet de faire cela. J’ai l’intention de faire un PR pour rendre cela plus facile plus tard.
function getSlug(filename: string) {
const parts = filename.match(/^(\\|\/)(.+(\\|\/))*(.+)\.(.+)$/);
return parts?.length ? parts[4] : '';
}
export const indexResolver: ResolveFn<any> = async () => {
const data = import.meta.glob('/src/app/pages/blog/*.md', {
eager: true,
import: 'default',
query: { 'analog-content-list': true },
});
return Object.keys(data).map((filename) => {
const attributes = data[filename] as any;
const slug = attributes['slug'];
return {
filename: filename.split("https://www.telerik.com/").pop()?.split('.')[0],
slug: slug ? encodeURI(slug) : encodeURI(getSlug(filename)),
title: attributes.title
};
});
};
Affichage des pages du blog
Nous utilisons la fonction précédente et l’injectons dans notre résolveur pour obtenir les noms de tous les fichiers de notre blog
dossier avec un .md
extension.
import { Component} from '@angular/core';
import {
RouterLink,
RouterOutlet
} from '@angular/router';
import { AsyncPipe, NgFor, NgIf } from '@angular/common';
import { RouteMeta } from '@analogjs/router';
import { PostAttributes } from '../models';
import { indexResolver, injectSnapResolver } from '../utils';
export const routeMeta: RouteMeta = {
resolve: { data: indexResolver }
};
@Component({
standalone: true,
imports: [RouterOutlet, RouterLink, NgFor, NgIf, AsyncPipe],
template: `
<h1>Rocky Billy's Blog</h1>
<ul>
<li *ngFor="let post of posts">
<a [routerLink]="['blog', post.slug]">{{
post.title
}}</a>
</li>
</ul>
`,
})
export default class BlogComponent {
readonly posts = injectSnapResolver<PostAttributes[]>('data');
Remarquez à quel point l’injection du résolveur est facile. Utilisez simplement le routeMeta
objet avec ma coutume injectSnapResolver
fonction.
Déploiement
Alors c’est tout!
Analog utilise Vite, ce qui rend le déploiement extrêmement simple. Puisque mon application utilise SSR, j’ai décidé de l’héberger sur Netlify. Il y a préréglages intégrés pour chaque environnement d’hébergement, même les serveurs Edge.
Dépôt : GitHub
Démo : Le blog de Rocky Billy
Articles similaires
Quelques autres articles ont abordé le concept du blog, mais je souhaite proposer le mien.
Avenir
J’adore Analog et je suis super excité par le .de fonctionnalités expérimentales. Cela vous permet de créer un composant angulaire sans le passe-partout, et votre composant ressemblera à un fichier Svelte ou Vue. Analog est encore très jeune, mais j’ai l’intention de l’aider à se développer là où je peux.
Source link