Skip to content

Commit a1f1cff

Browse files
authored
Merge pull request #3 from cnumr/cms
feat: architecture upstream sync, SEO complet et améliorations majeures
2 parents 400384c + 1b93ddd commit a1f1cff

30 files changed

Lines changed: 292 additions & 46 deletions

.env.example

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,9 @@ GITHUB_PERSONAL_ACCESS_TOKEN=
1818
# Required when building locally
1919
GITHUB_OWNER=
2020
GITHUB_REPO=
21-
GITHUB_BRANCH=
21+
GITHUB_BRANCH=
22+
23+
# SEO - URL du site (obligatoire en production pour les images OpenGraph/Twitter)
24+
SITE_URL=https://example.com
25+
# Optionnel - base path si le site est hébergé sur un sous-répertoire
26+
PUBLIC_BASE=

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Protéger le contenu spécifique au site lors des merges upstream
22
src/content/** merge=ours
3+
public/img_fiches/** merge=ours
34

45
# Protéger les fichiers TinaCMS générés (dépendent de TINA_PUBLIC_REF_NAME)
56
tina/tina-lock.json merge=ours

README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<p align="center">
22
<a href="https://collectif.greenit.fr/">
3-
<img align="center" alt="CNUMR" src="./public/logo-cnumr.png" width="160" />
3+
<img align="center" alt="CNUMR" src="./public/assets/logo-cnumr.png" width="160" />
44
</a>
5-
<img align="center" alt="Association Green IT" src="./public/logo-asso.png" width="200" />
5+
<img align="center" alt="Association Green IT" src="./public/assets/logo-asso.png" width="200" />
66
</p>
77

88
# gen-referentiel-core
@@ -47,12 +47,12 @@ Ce repository contient le code partagé entre plusieurs sites de référentiels.
4747

4848
Ce repo contient du contenu fake minimal pour tester le build :
4949

50-
| Type | Fichiers |
51-
|------|----------|
52-
| Fiches | 3 fiches exemples |
53-
| Personas | 2 personas de test |
54-
| Lexique | 3 termes |
55-
| Home | Page d'accueil de test |
50+
| Type | Fichiers |
51+
| -------- | ---------------------- |
52+
| Fiches | 3 fiches exemples |
53+
| Personas | 2 personas de test |
54+
| Lexique | 3 termes |
55+
| Home | Page d'accueil de test |
5656

5757
## Développement
5858

@@ -95,12 +95,12 @@ Le `.gitattributes` protège automatiquement le contenu local (`src/content/`) l
9595

9696
## Sites utilisant ce repo
9797

98-
| Site | Repository | Description |
99-
|------|------------|-------------|
100-
| RWP | best-practices-wordpress | Bonnes pratiques WordPress |
101-
| RWEB | best-practices | Bonnes pratiques Web |
102-
| REIPRO | best-practices-packaged-software | Intégration de progiciels |
103-
| RIA | (à venir) | Utilisation de l'IA |
98+
| Site | Repository | Description |
99+
| ------ | -------------------------------- | -------------------------- |
100+
| RWP | best-practices-wordpress | Bonnes pratiques WordPress |
101+
| RWEB | best-practices | Bonnes pratiques Web |
102+
| REIPRO | best-practices-packaged-software | Intégration de progiciels |
103+
| RIA | (à venir) | Utilisation de l'IA |
104104

105105
## Documentation
106106

app/[lang]/fiches/[slug]/page.tsx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,66 @@
11
import { FichesPage } from '../../../../components/pages/fiches-page';
22
import { InternalNavigation } from '../../../../components/pages/fiche/InternalNav';
3+
import { Metadata } from 'next';
34
import { client } from '../../../../tina/__generated__/databaseClient';
45
import { getRefConfig } from '../../../../referentiel-config';
56
import { getStaticPathsFromFilesystem } from '../../../../utils/get-static-paths';
7+
import { ui } from '../../../../i18n/ui';
8+
import { useTranslations } from '../../../../i18n/utils';
69

710
export function generateStaticParams() {
811
return getStaticPathsFromFilesystem('fiches');
912
}
13+
14+
export async function generateMetadata({
15+
params,
16+
}: {
17+
params: { lang: keyof typeof ui; slug: string };
18+
}): Promise<Metadata> {
19+
const { lang, slug } = params;
20+
const t = useTranslations(lang);
21+
22+
try {
23+
const res = await client.queries.fiches({
24+
relativePath: `${lang}/${slug}.mdx`,
25+
});
26+
27+
const fiche = res.data.fiches;
28+
const title = `${fiche.refID} - ${fiche.title} | ${t('seo.site_name')}`;
29+
const description = fiche.title;
30+
const imageUrl = t('seo.fb.image.url');
31+
const siteUrl = t('seo.url');
32+
33+
return {
34+
title,
35+
description,
36+
openGraph: {
37+
title,
38+
description,
39+
url: `${siteUrl}/${lang}/fiches/${slug}`,
40+
siteName: t('seo.site_name'),
41+
images: [
42+
{
43+
url: imageUrl,
44+
alt: fiche.title,
45+
},
46+
],
47+
locale: lang,
48+
type: 'article',
49+
},
50+
twitter: {
51+
card: 'summary_large_image',
52+
title,
53+
description,
54+
images: [t('seo.tw.image.url')],
55+
},
56+
};
57+
} catch {
58+
return {
59+
title: t('seo.site_name'),
60+
description: t('seo.default.description'),
61+
};
62+
}
63+
}
1064
export default async function Page({ params }) {
1165
const { lang, slug } = params;
1266

app/[lang]/fiches/page.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,46 @@ import CardView from '../../../components/card-view';
55
import { FichesCardFilter } from '../../../components/pages/fiche/FicheFilter';
66
import { FichesTableView } from '../../../components/pages/fiche/TableView';
77
import { Fragment } from 'react';
8+
import { Metadata } from 'next';
89
import { useTranslations } from '../../../i18n/utils';
9-
import { code_languages } from '../../../i18n/ui';
10+
import { code_languages, ui } from '../../../i18n/ui';
1011
import { client } from '../../../tina/__generated__/databaseClient';
1112

1213
export async function generateStaticParams() {
1314
return code_languages.map((lang) => ({ lang }));
1415
}
1516

17+
export async function generateMetadata({
18+
params,
19+
}: {
20+
params: { lang: keyof typeof ui };
21+
}): Promise<Metadata> {
22+
const { lang } = params;
23+
const t = useTranslations(lang);
24+
const title = `${t('Bonnes pratiques')} | ${t('seo.site_name')}`;
25+
const description = t('Consulter les Bonnes pratiques');
26+
27+
return {
28+
title,
29+
description,
30+
openGraph: {
31+
title,
32+
description,
33+
url: `${t('seo.url')}/${lang}/fiches`,
34+
siteName: t('seo.site_name'),
35+
images: [{ url: t('seo.fb.image.url'), alt: title }],
36+
locale: lang,
37+
type: 'website',
38+
},
39+
twitter: {
40+
card: 'summary_large_image',
41+
title,
42+
description,
43+
images: [t('seo.tw.image.url')],
44+
},
45+
};
46+
}
47+
1648
export default async function Home({ params }) {
1749
const { lang } = params;
1850
const { data }: { data: FichesConnectionQuery } = await client.queries.fichesConnection({

app/[lang]/layout.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,36 @@ export async function generateMetadata({
1919
};
2020
}): Promise<Metadata> {
2121
const t = useTranslations(params.lang);
22+
const title = `${t('seo.site_name')}${getRefConfig().i18n.refTitles[params.lang].long} | Collectif Green IT`;
23+
const description = t('seo.default.description');
24+
const imageUrl = t('seo.fb.image.url');
25+
const imageAlt = t('seo.image.alt');
26+
const siteUrl = t('seo.url');
2227

2328
return {
24-
title: `${t('seo.site_name')}${getRefConfig().i18n.refTitles[params.lang].long} | Collectif Green IT`,
25-
description: `${t('seo.default.description')}`,
29+
metadataBase: new URL(siteUrl),
30+
title,
31+
description,
32+
openGraph: {
33+
title,
34+
description,
35+
url: siteUrl,
36+
siteName: t('seo.site_name'),
37+
images: [
38+
{
39+
url: imageUrl,
40+
alt: imageAlt,
41+
},
42+
],
43+
locale: params.lang,
44+
type: 'website',
45+
},
46+
twitter: {
47+
card: 'summary_large_image',
48+
title,
49+
description,
50+
images: [t('seo.tw.image.url')],
51+
},
2652
};
2753
}
2854

app/[lang]/lexique/page.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Lexique } from '../../../tina/__generated__/types';
22
import Link from 'next/link';
33
import { MdxComponents } from '../../../components/mdx/mdx-components';
4+
import { Metadata } from 'next';
45
import { TinaMarkdown } from 'tinacms/dist/rich-text';
56
import { client } from '../../../tina/__generated__/databaseClient';
67
import { getRefConfig } from '../../../referentiel-config';
78
import { notFound } from 'next/navigation';
8-
import { code_languages } from '../../../i18n/ui';
9+
import { code_languages, ui } from '../../../i18n/ui';
910
import { useTranslations } from '../../../i18n/utils';
1011

1112
export async function generateStaticParams() {
@@ -16,6 +17,37 @@ export async function generateStaticParams() {
1617
return code_languages.map((lang) => ({ lang }));
1718
}
1819

20+
export async function generateMetadata({
21+
params,
22+
}: {
23+
params: { lang: keyof typeof ui };
24+
}): Promise<Metadata> {
25+
const { lang } = params;
26+
const t = useTranslations(lang);
27+
const title = `${t('Lexique')} | ${t('seo.site_name')}`;
28+
const description = t('Consulter le Lexique');
29+
30+
return {
31+
title,
32+
description,
33+
openGraph: {
34+
title,
35+
description,
36+
url: `${t('seo.url')}/${lang}/lexique`,
37+
siteName: t('seo.site_name'),
38+
images: [{ url: t('seo.fb.image.url'), alt: title }],
39+
locale: lang,
40+
type: 'website',
41+
},
42+
twitter: {
43+
card: 'summary_large_image',
44+
title,
45+
description,
46+
images: [t('seo.tw.image.url')],
47+
},
48+
};
49+
}
50+
1951
export default async function Home({ params }) {
2052
const { lang } = params;
2153

app/[lang]/mentions-legales/page.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
import { MentionsLegalesPage } from '../../../components/pages/mentions-legales-page';
2+
import { Metadata } from 'next';
23
import { client } from '../../../tina/__generated__/databaseClient';
4+
import { ui } from '../../../i18n/ui';
5+
import { useTranslations } from '../../../i18n/utils';
6+
7+
export async function generateMetadata({
8+
params,
9+
}: {
10+
params: { lang: keyof typeof ui };
11+
}): Promise<Metadata> {
12+
const { lang } = params;
13+
const t = useTranslations(lang);
14+
const title = `${t('Mentions légales')} | ${t('seo.site_name')}`;
15+
const description = t('seo.default.description');
16+
17+
return {
18+
title,
19+
description,
20+
openGraph: {
21+
title,
22+
description,
23+
url: `${t('seo.url')}/${lang}/mentions-legales`,
24+
siteName: t('seo.site_name'),
25+
images: [{ url: t('seo.fb.image.url'), alt: title }],
26+
locale: lang,
27+
type: 'website',
28+
},
29+
twitter: {
30+
card: 'summary_large_image',
31+
title,
32+
description,
33+
images: [t('seo.tw.image.url')],
34+
},
35+
};
36+
}
337

438
export default async function Page({ params }) {
539
const { lang } = params;

app/[lang]/personas/[slug]/page.tsx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import { Metadata } from 'next';
12
import { client } from '../../../../tina/__generated__/databaseClient';
23
import { getRefConfig } from '../../../../referentiel-config';
34
import { PersonasPage } from '../../../../components/pages/personas-page';
45
import { getStaticPathsFromFilesystem } from '../../../../utils/get-static-paths';
56
import { notFound } from 'next/navigation';
7+
import { ui } from '../../../../i18n/ui';
8+
import { useTranslations } from '../../../../i18n/utils';
69

710
export function generateStaticParams() {
811
if (!getRefConfig().featuresEnabled.linkToPersonas) {
@@ -11,6 +14,50 @@ export function generateStaticParams() {
1114
return getStaticPathsFromFilesystem('personas');
1215
}
1316

17+
export async function generateMetadata({
18+
params,
19+
}: {
20+
params: { lang: keyof typeof ui; slug: string };
21+
}): Promise<Metadata> {
22+
const { lang, slug } = params;
23+
const t = useTranslations(lang);
24+
25+
try {
26+
const res = await client.queries.personas({
27+
relativePath: `${lang}/${slug}.mdx`,
28+
});
29+
30+
const persona = res.data.personas;
31+
const title = `${persona.title} | ${t('seo.site_name')}`;
32+
const description = persona.title;
33+
34+
return {
35+
title,
36+
description,
37+
openGraph: {
38+
title,
39+
description,
40+
url: `${t('seo.url')}/${lang}/personas/${slug}`,
41+
siteName: t('seo.site_name'),
42+
images: [{ url: t('seo.fb.image.url'), alt: persona.title }],
43+
locale: lang,
44+
type: 'article',
45+
},
46+
twitter: {
47+
card: 'summary_large_image',
48+
title,
49+
description,
50+
images: [t('seo.tw.image.url')],
51+
},
52+
};
53+
} catch {
54+
return {
55+
title: t('seo.site_name'),
56+
description: t('seo.default.description'),
57+
};
58+
}
59+
}
60+
1461
export default async function Page({ params }) {
1562
if (!getRefConfig().featuresEnabled.linkToPersonas) {
1663
notFound();

0 commit comments

Comments
 (0)