Faire des catégories d'articles sur NextJS
Table des matières
- Contexte
- Modification du repository d'articles
- Creation d'un repository de tag
- Creation d'un liste d'article par tag
- Modification de la liste d'article
- Tester son blog sur son ordinateur
Contexte
Si vous avez suivi l'article précedent sur "comment créer un blog avec NextJS", nous sommes en possession d'un blog avec une seule liste d'articles. Pour aller plus loin, nous pouvons créer un système de catégories sur nos articles, pour pouvoir filtrer les articles par thème.
Modification du repository d'articles
Pour commencer, nous allons ajouter la notion de tag dans les articles
[...]
import slugify from 'slugify'
export interface Article {
[...]
tags: string[];
}
export interface ArticleFilters {
tag?: string;
}
export function getArticleList(filters: ArticleFilters): Article[] {
return list()
.map(fileName => ({
id: fileName.replace(/\.md$/, ''),
...read(fileName).data
} as Article))
.filter(article => !filters.tag || article.tags.map(tag => slugify(tag, { replacement: '-', lower: true })).findIndex(tag => tag === filters.tag) !== -1);
}
[...]
Maintenant que nous pouvons ajouter des tags dans nos articles, profitons-en pour les modifier
---
title: 1er article
date: '2020-01-01'
tags: ['Tag 1', 'Tag 2']
---
Ici le contenu de notre premmier article
---
title: 2ème article
date: '2020-01-02'
tags: ['Tag 2', 'Tag 3']
---
Ici le contenu de notre deuxième article
---
title: 3ème article
date: '2020-01-03'
tags: ['Tag 1', 'Tag 3']
---
Ici le contenu de notre troisième et dernier article
Creation d'un repository de tag
Pour gérer les tags, nous allons avoir besoin de slugifier ces derniers pour qu'ils puissent passer dans l'url.
Pour cela, nous allons installer un paquet dans nos dépendances:
yarn add slugify
Nous pouvons donc créer le repository de tags comme ceci:
import { list, read } from './articles'
import slugify from 'slugify'
export type Tag = string;
export function getTags(): Tag[] {
return list()
.flatMap(fileName => read(fileName).data.tags)
.filter((tag, index, tags) => tags.findIndex(search => search === tag) === index);
}
export function tagSlug(tag: Tag): string {
return slugify(tag, {
replacement: '-',
lower: true,
});
}
Creation d'un liste d'article par tag
L'étape suivante est de créer la page qui contiendra la liste d'article, filtrée par un tag. Pour cela, il faut créer une page avec le tag dans l'url.
import { GetStaticPaths, GetStaticProps } from 'next'
import Link from 'next/link'
import { getArticleList } from '../../repository/articles'
import { getTags, tagSlug } from '../../repository/tags'
export default function TagArticleList({ tag, articles }) {
return (
<div>
<h2>{tag}</h2>
{articles.map(({ id, date, title, tags }) => (
<Link href={`/${id}`} key={id}>
<div className="article">
<h3>{title}</h3>
<div>{date}</div>
{tags.map((tag) => (
<Link href={`/tags/${tagSlug(tag)}`} key={tag}>
{tag}
</Link>
))}
</div>
</Link>
))}
<style jsx>{`
.article {
background: #eaeaea;
padding: 10px 20px;
margin: 20px 0;
}
`}</style>
</div>
)
}
export const getStaticProps: GetStaticProps = async (context) => {
const tagId = context.params.tag.toString();
const tag = getTags().find(tag => tagSlug(tag) === tagId);
const articles = getArticleList({ tag: tagId })
return {
props: {
tag,
articles
}
}
}
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: getTags().map(tag => ({
params: { tag: tagSlug(tag) }
})),
fallback: false
}
}
Modification de la liste d'article
Une bonne idée serait de lister de manière unique les tags de tous les articles sur la page principale.
Pour cela, modifions le fichier index.tsx
import { GetStaticProps } from 'next'
import Head from 'next/head'
import Link from 'next/link'
import { getArticleList } from '../repository/articles'
import { getTags, tagSlug } from '../repository/tags'
export default function ArticleList({ articles, tags }) {
return (
<div>
<Head>
<title>Mon super Blog</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<h1>Articles</h1>
{tags.map((tag) => (
<Link href={`/tags/${tagSlug(tag)}`} key={tag}>
{tag}
</Link>
))}
{articles.map(({ id, date, title, tags }) => (
<Link href={`/${id}`} key={id}>
<div className="article">
<h3>{title}</h3>
<div>{date}</div>
{tags.map((tag) => (
<Link href={`/tags/${tagSlug(tag)}`} key={tag}>
{tag}
</Link>
))}
</div>
</Link>
))}
<style jsx>{`
.article {
background: #eaeaea;
padding: 10px 20px;
margin: 20px 0;
}
`}</style>
</div>
)
}
export const getStaticProps: GetStaticProps = async () => {
return {
props: {
articles: getArticleList({}),
tags: getTags(),
}
}
}
Tester son blog sur son ordinateur
Et voilà, nous avons ajouté un système de tag sur notre blog, vous pouvez lancer la commande suivante pour tester les modifications.
yarn dev
Nous pouvons voir que la liste des tags est générée au-dessus des 3 articles.
Et que si nous cliquons sur un tag, le site nous emmène bien vers une liste d'articles triés par ce tag.