Create core I18N types + content

This commit is contained in:
Sam Becker 2025-05-06 22:15:31 -07:00
parent b635ba28cc
commit f0a90172f5
6 changed files with 111 additions and 5 deletions

View File

@ -254,6 +254,16 @@ Vercel Postgres can be switched to another Postgres-compatible, pooling provider
1. Ensure connection string is set to "Transaction Mode" via port `6543`
2. Disable SSL by setting `DISABLE_POSTGRES_SSL = 1`
💬   I18N
-
Partial internationalization (non-admin, user-facing text) provided for a handful of languages. If you'd like to add support for a new language, [open a PR](https://github.com/sambecker/exif-photo-blog/compare) using [`ES_EN`](https://github.com/sambecker/exif-photo-blog) for reference.
### Supported Languages
- `ES_ES`
- `PT_BR`
- `PT_PT`
📖  FAQ
-
#### How do I receive template updates?

View File

@ -9,6 +9,7 @@ import {
import IconSearch from '../components/icons/IconSearch';
import { useAppState } from '@/state/AppState';
import {
APP_TEXT,
GRID_HOMEPAGE_ENABLED,
SHOW_KEYBOARD_SHORTCUT_TOOLTIPS,
} from './config';
@ -66,7 +67,7 @@ export default function AppViewSwitcher({
hrefRef={refHrefFeed}
active={currentSelection === 'feed'}
tooltip={{...SHOW_KEYBOARD_SHORTCUT_TOOLTIPS && {
content: 'Feed',
content: APP_TEXT.nav.feed,
keyCommand: KEY_COMMANDS.feed,
}}}
noPadding
@ -79,7 +80,7 @@ export default function AppViewSwitcher({
hrefRef={refHrefGrid}
active={currentSelection === 'grid'}
tooltip={{...SHOW_KEYBOARD_SHORTCUT_TOOLTIPS && {
content: 'Grid',
content: APP_TEXT.nav.grid,
keyCommand: KEY_COMMANDS.grid,
}}}
noPadding
@ -103,7 +104,7 @@ export default function AppViewSwitcher({
noPadding
tooltip={{
...!isAdminMenuOpen && SHOW_KEYBOARD_SHORTCUT_TOOLTIPS && {
content: 'Admin Menu',
content: APP_TEXT.nav.admin,
keyCommand: KEY_COMMANDS.admin,
},
}}
@ -116,7 +117,7 @@ export default function AppViewSwitcher({
/>}
tooltip={{
...!isAdminMenuOpen && SHOW_KEYBOARD_SHORTCUT_TOOLTIPS && {
content: 'Admin Menu',
content: APP_TEXT.nav.admin,
keyCommand: KEY_COMMANDS.admin,
},
}}
@ -128,7 +129,7 @@ export default function AppViewSwitcher({
icon={<IconSearch includeTitle={false} />}
onClick={() => setIsCommandKOpen?.(true)}
tooltip={{...SHOW_KEYBOARD_SHORTCUT_TOOLTIPS && {
content: 'Search',
content: APP_TEXT.nav.search,
keyCommandModifier: KEY_COMMANDS.search[0],
keyCommand: KEY_COMMANDS.search[1],
}}}

View File

@ -5,6 +5,7 @@ import {
import { getOrderedCategoriesFromString } from '@/category';
import type { StorageType } from '@/platforms/storage';
import { makeUrlAbsolute, shortenUrl } from '@/utility/url';
import { getContentForLanguage } from '@/i18n';
// HARD-CODED GLOBAL CONFIGURATION
@ -98,6 +99,10 @@ const SITE_DOMAIN_SHORT = shortenUrl(SITE_DOMAIN);
// SITE META
export const APP_TEXT = await getContentForLanguage(
process.env.NEXT_PUBLIC_LANGUAGE,
);
export const NAV_TITLE =
process.env.NEXT_PUBLIC_NAV_TITLE;

17
src/i18n/index.ts Normal file
View File

@ -0,0 +1,17 @@
import US_EN from './languages/us-en';
export type I18N = typeof US_EN;
export const LANGUAGES: Record<
string,
(() => Promise<Partial<I18N>>) | undefined
> = {
'pt-br': () => import('./languages/pt-br').then(module => module.default),
};
export const getContentForLanguage = async (
language = '',
): Promise<I18N> => ({
...US_EN,
...await LANGUAGES[language.toLocaleLowerCase()]?.(),
});

View File

@ -0,0 +1,21 @@
import { I18N } from '..';
const language: Partial<I18N> = {
core: {
photo: 'Foto',
photoPlural: 'Fotos',
},
nav: {
home: 'Início',
feed: 'Feed',
grid: 'Grade',
admin: 'Menu de Admin',
search: 'Pesquisar',
prev: 'Anterior',
prevShort: 'Ant',
next: 'Próximo',
nextShort: 'Prox',
},
};
export default language;

View File

@ -0,0 +1,52 @@
const language = {
core: {
photo: 'Photo',
photoPlural: 'Photos',
},
nav: {
home: 'Home',
feed: 'Feed',
grid: 'Grid',
admin: 'Admin',
search: 'Search',
prev: 'Previous',
prevShort: 'Prev',
next: 'Next',
nextShort: 'Next',
},
categories: {
camera: 'Camera',
cameraPlural: 'Cameras',
lens: 'Lens',
lensPlural: 'Lenses',
tag: 'Tag',
tagPlural: 'Tags',
recipe: 'Recipe',
recipePlural: 'Recipes',
film: 'Film',
filmPlural: 'Films',
focalLength: 'Focal Length',
focalLengthPlural: 'Focal Lengths',
},
footer: {
repo: 'Made with',
system: 'System',
light: 'Light',
dark: 'Dark',
},
auth: {
signIn: 'Sign in',
signOut: 'Sign out',
email: 'Admin Email',
password: 'Admin Password',
},
tooltips: {
'35mm': '35mm Equivalent',
imageViewer: 'Open Image Viewer',
sharePhoto: 'Share Photo',
recipeInfo: 'Recipe Info',
recipeCopy: 'Copy Recipe Text',
},
};
export default language;