Skip to content

Commit ea760e2

Browse files
committed
feat(blog): add i18n
Signed-off-by: Emilien Escalle <emilien.escalle@escemi.com>
1 parent e449126 commit ea760e2

43 files changed

Lines changed: 772 additions & 1031 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.devcontainer/devcontainer.json

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
77
"ghcr.io/devcontainers/features/github-cli:1": {}
88
},
9-
"forwardPorts": [
10-
4321
11-
],
9+
"forwardPorts": [4321],
1210
"secrets": {},
1311
"remoteEnv": {
1412
"GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}"
@@ -33,18 +31,14 @@
3331
"servers": {
3432
"playwright": {
3533
"command": "npx",
36-
"args": [
37-
"@playwright/mcp@latest"
38-
]
34+
"args": ["@playwright/mcp@latest"]
3935
},
4036
"lighthouse": {
4137
"command": "npx",
42-
"args": [
43-
"lighthouse-mcp"
44-
]
38+
"args": ["lighthouse-mcp"]
4539
}
4640
}
4741
}
4842
}
4943
}
50-
}
44+
}

.github/linters/.jscpd.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"threshold": 5,
3+
"gitignore": true,
4+
"ignore": [
5+
"**/node_modules/**",
6+
"**/dist/**",
7+
"**/.astro/**",
8+
"**/coverage/**",
9+
"**/.vscode/**"
10+
]
11+
}

.vscode/astrowind/config-schema.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,14 @@
231231
"required": ["isEnabled", "pathname", "robots"]
232232
}
233233
},
234-
"required": ["isEnabled", "postsPerPage", "post", "list", "category", "tag"]
234+
"required": [
235+
"isEnabled",
236+
"postsPerPage",
237+
"post",
238+
"list",
239+
"category",
240+
"tag"
241+
]
235242
}
236243
},
237244
"required": ["blog"]

.vscode/settings.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
{
22
"css.customData": ["./vscode.tailwind.json"],
3-
"eslint.validate": ["javascript", "javascriptreact", "astro", "typescript", "typescriptreact"],
3+
"eslint.validate": [
4+
"javascript",
5+
"javascriptreact",
6+
"astro",
7+
"typescript",
8+
"typescriptreact"
9+
],
410
"files.associations": {
511
"*.mdx": "markdown"
612
},

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Cloud Native Provence Landing Page
1+
# Cloud Native Provence - Landing Page
22

3-
Conference website for Cloud Native Provence, with bilingual routing (`fr` / `en`) and translated page slugs.
3+
Conference site for Cloud Native Provence, with bilingual routing (`fr` / `en`) and translated page slugs.
44

55
## Development workflow
66

@@ -12,13 +12,13 @@ make help
1212

1313
Main targets:
1414

15-
- `make setup` install project dependencies
16-
- `make start` start local dev server (`application`)
17-
- `make build` production build
18-
- `make test-app` run application tests with coverage
19-
- `make lint` run linters/checks
20-
- `make lint-fix` run fixers
21-
- `make ci` lint + build + test pipeline
15+
- `make setup` - install project dependencies
16+
- `make start` - start local dev server (`application`)
17+
- `make build` - production build
18+
- `make test` - run application tests with coverage
19+
- `make lint` - run linters/checks
20+
- `make lint-fix` - run fixers
21+
- `make ci` - lint + build + test pipeline
2222

2323
## Tests and coverage
2424

@@ -30,11 +30,11 @@ make test
3030

3131
## Dev Container
3232

33-
This repository includes a VS Code Dev Container in `.devcontainer/devcontainer.json`.
33+
This repository includes a Visual Studio Code Dev Container in `.devcontainer/devcontainer.json`.
3434

3535
Quick start:
3636

37-
1. Open the repository in VS Code.
37+
1. Open the repository in Visual Studio Code.
3838
2. Run `Dev Containers: Reopen in Container`.
3939
3. Inside the container:
4040

@@ -48,7 +48,7 @@ The dev container provides:
4848
- Node.js
4949
- Docker-in-Docker
5050
- GitHub CLI
51-
- VS Code extensions for Astro, ESLint, Prettier, Tailwind, Makefile, Copilot
51+
- Visual Studio Code extensions for Astro, ESLint, Prettier, Tailwind, Makefile, Copilot
5252

5353
The app is available on port `4321`.
5454

@@ -59,13 +59,14 @@ Routing is locale-first and centralized:
5959
- `/` redirects to `/fr`
6060
- `/fr` and `/en` are localized homepages
6161
- `/{lang}/{translated-slug}` serves localized content pages
62+
- `/{lang}/blog/...` serves localized blog list, posts, categories, and tags
6263

6364
Key files:
6465

65-
- `application/src/pages/index.astro` root redirect
66-
- `application/src/pages/[lang]/index.astro` localized homepage
67-
- `application/src/pages/[lang]/[page].astro` localized dynamic pages
68-
- `application/src/i18n/routes.ts` slug mapping and path translation helpers
66+
- `application/src/pages/index.astro` - root redirect
67+
- `application/src/pages/[lang]/index.astro` - localized homepage
68+
- `application/src/pages/[lang]/[page].astro` - localized dynamic pages
69+
- `application/src/i18n/routes.ts` - slug mapping and path translation helpers
6970

7071
Translated static pages:
7172

@@ -100,7 +101,6 @@ Translated static pages:
100101
│ ├── i18n/
101102
│ ├── layouts/
102103
│ ├── pages/
103-
│ │ ├── [...blog]/
104104
│ │ ├── [lang]/
105105
│ │ ├── about/
106106
│ │ ├── brand-guidelines/

application/astro.config.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,18 @@ const hasExternalScripts = false;
2121
const whenExternalScripts = (items: (() => AstroIntegration) | (() => AstroIntegration)[] = []) =>
2222
hasExternalScripts ? (Array.isArray(items) ? items.map((item) => item()) : [items()]) : [];
2323

24+
const defaultLocale = 'fr';
25+
2426
export default defineConfig({
2527
site: 'https://cloudnative-provence.fr',
2628
base: '/',
2729
output: 'static',
30+
redirects: {
31+
'/': '/' + defaultLocale,
32+
},
2833
i18n: {
29-
locales: ['fr', 'en'],
30-
defaultLocale: 'fr',
34+
locales: [defaultLocale, 'en'],
35+
defaultLocale,
3136
},
3237
integrations: [
3338
tailwind({
@@ -77,7 +82,7 @@ export default defineConfig({
7782
],
7883

7984
image: {
80-
domains: ['cdn.pixabay.com'],
85+
domains: [],
8186
},
8287

8388
markdown: {

application/public/favicon.ico

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../src/assets/favicons/favicon.ico

application/src/components/blog/GridItem.astro

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ import Image from '~/components/common/Image.astro';
66
77
import { findImage } from '~/utils/images';
88
import { getPermalink } from '~/utils/permalinks';
9+
import { getLangFromUrl } from '~/i18n/utils';
910
1011
export interface Props {
1112
post: Post;
1213
}
1314
1415
const { post } = Astro.props;
1516
const image = await findImage(post.image);
17+
const currentLang = getLangFromUrl(Astro.url);
1618
17-
const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post') : '';
19+
const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post', currentLang) : '';
1820
---
1921

2022
<article

application/src/components/blog/ListItem.astro

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@ import type { Post } from '~/types';
1010
import { getPermalink } from '~/utils/permalinks';
1111
import { findImage } from '~/utils/images';
1212
import { getFormattedDate } from '~/utils/utils';
13+
import { getLangFromUrl } from '~/i18n/utils';
1314
1415
export interface Props {
1516
post: Post;
1617
}
1718
1819
const { post } = Astro.props;
1920
const image = (await findImage(post.image)) as ImageMetadata | undefined;
21+
const currentLang = getLangFromUrl(Astro.url);
2022
21-
const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post') : '';
23+
const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post', currentLang) : '';
2224
---
2325

2426
<article
@@ -82,7 +84,7 @@ const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post') :
8284
<>
8385
{' '}
8486
·{' '}
85-
<a class="hover:underline" href={getPermalink(post.category.slug, 'category')}>
87+
<a class="hover:underline" href={getPermalink(post.category.slug, 'category', currentLang)}>
8688
{post.category.title}
8789
</a>
8890
</>

application/src/components/blog/RelatedPosts.astro

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import { getRelatedPosts } from '~/utils/blog';
55
import BlogHighlightedPosts from '../widgets/BlogHighlightedPosts.astro';
66
import type { Post } from '~/types';
77
import { getBlogPermalink } from '~/utils/permalinks';
8+
import { getLangFromUrl } from '~/i18n/utils';
89
910
export interface Props {
1011
post: Post;
1112
}
1213
1314
const { post } = Astro.props;
15+
const currentLang = getLangFromUrl(Astro.url);
1416
1517
const relatedPosts = post.tags ? await getRelatedPosts(post, 4) : [];
1618
---
@@ -24,7 +26,7 @@ const relatedPosts = post.tags ? await getRelatedPosts(post, 4) : [];
2426
}}
2527
title="Related Posts"
2628
linkText="View All Posts"
27-
linkUrl={getBlogPermalink()}
29+
linkUrl={getBlogPermalink(currentLang)}
2830
postIds={relatedPosts.map((post) => post.id)}
2931
/>
3032
) : null

0 commit comments

Comments
 (0)