Skip to content

Commit

Permalink
Merge pull request #8600 from weseek/feat/141574-143040-apply-locale-…
Browse files Browse the repository at this point in the history
…to-defualt-page-title

feat: Apply locale to defualt page title
  • Loading branch information
yuki-takei committed May 1, 2024
2 parents c95dd0a + cf83c86 commit bb85b12
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 17 deletions.
16 changes: 16 additions & 0 deletions apps/app/config/i18next.config.js
@@ -0,0 +1,16 @@
const { Lang, AllLang } = require('@growi/core');

/** @type {Lang} */
const defaultLang = Lang.en_US;

/** @type {import('i18next').InitOptions} */
const initOptions = {
fallbackLng: defaultLang.toString(),
supportedLngs: AllLang,
defaultNS: 'translation',
};

module.exports = {
defaultLang,
initOptions,
};
29 changes: 20 additions & 9 deletions apps/app/config/next-i18next.config.js
Expand Up @@ -2,36 +2,47 @@ const isDev = process.env.NODE_ENV === 'development';

const path = require('path');

const { AllLang, Lang } = require('@growi/core');
const { AllLang } = require('@growi/core');
const { isServer } = require('@growi/core/dist/utils');
const I18nextChainedBackend = isDev ? require('i18next-chained-backend').default : undefined;
const I18NextHttpBackend = require('i18next-http-backend').default;
const I18NextLocalStorageBackend = require('i18next-localstorage-backend').default;

const { defaultLang } = require('./i18next.config');

const HMRPlugin = isDev ? require('i18next-hmr/plugin').HMRPlugin : undefined;

/** @type {import('next-i18next').UserConfig} */
module.exports = {
defaultLang: Lang.en_US,
...require('./i18next.config').initOptions,

i18n: {
defaultLocale: Lang.en_US,
defaultLocale: defaultLang.toString(),
locales: AllLang,
},
defaultNS: 'translation',

localePath: path.resolve('./public/static/locales'),
serializeConfig: false,

// eslint-disable-next-line no-nested-ternary
use: isDev
? isServer()
? [new HMRPlugin({ webpack: { server: true } })]
: [I18nextChainedBackend, new HMRPlugin({ webpack: { client: true } })]
: [
require('i18next-chained-backend').default,
new HMRPlugin({ webpack: { client: true } }),
]
: [],
backend: {
backends: isServer() ? [] : [I18NextLocalStorageBackend, I18NextHttpBackend],
backends: isServer()
? []
: [
require('i18next-localstorage-backend').default,
require('i18next-http-backend').default,
],
backendOptions: [
// options for i18next-localstorage-backend
{ expirationTime: isDev ? 0 : 24 * 60 * 60 * 1000 }, // 1 day in production
// options for i18next-http-backend
{ loadPath: '/static/locales/{{lng}}/{{ns}}.json' },
],
},

};
7 changes: 4 additions & 3 deletions apps/app/package.json
Expand Up @@ -125,9 +125,7 @@
"helmet": "^4.6.0",
"http-errors": "^2.0.0",
"i18next": "^23.10.1",
"i18next-chained-backend": "^4.6.2",
"i18next-http-backend": "^2.5.0",
"i18next-localstorage-backend": "^4.2.0",
"i18next-resources-to-backend": "^1.2.1",
"is-absolute-url": "^4.0.1",
"is-iso-date": "^0.0.1",
"ldapjs": "^3.0.2",
Expand Down Expand Up @@ -253,7 +251,10 @@
"fslightbox-react": "^1.7.6",
"handsontable": "=6.2.2",
"happy-dom": "^13.2.0",
"i18next-chained-backend": "^4.6.2",
"i18next-hmr": "^3.0.4",
"i18next-http-backend": "^2.5.0",
"i18next-localstorage-backend": "^4.2.0",
"jest": "^29.5.0",
"jest-date-mock": "^1.0.8",
"jest-localstorage-mock": "^2.4.14",
Expand Down
3 changes: 3 additions & 0 deletions apps/app/public/static/locales/en_US/translation.json
Expand Up @@ -863,5 +863,8 @@
"show_wip_page": "Show WIP",
"size_s": "Size: S",
"size_l": "Size: L"
},
"create_page": {
"untitled": "Untitled"
}
}
3 changes: 3 additions & 0 deletions apps/app/public/static/locales/ja_JP/translation.json
Expand Up @@ -896,5 +896,8 @@
"show_wip_page": "WIP を表示",
"size_s": "サイズ: S",
"size_l": "サイズ: L"
},
"create_page": {
"untitled": "無題のページ"
}
}
3 changes: 3 additions & 0 deletions apps/app/public/static/locales/zh_CN/translation.json
Expand Up @@ -866,5 +866,8 @@
"show_wip_page": "显示 WIP",
"size_s": "尺寸: S",
"size_l": "尺寸: L"
},
"create_page": {
"untitled": "Untitled"
}
}
6 changes: 3 additions & 3 deletions apps/app/src/client/util/locale-utils.ts
Expand Up @@ -2,7 +2,7 @@ import type { IncomingHttpHeaders } from 'http';

import { Lang } from '@growi/core';

import * as nextI18NextConfig from '^/config/next-i18next.config';
import { defaultLang } from '^/config/i18next.config';

// https://docs.google.com/spreadsheets/d/1FoYdyEraEQuWofzbYCDPKN7EdKgS_2ZrsDrOA8scgwQ
const DIAGRAMS_NET_LANG_MAP = {
Expand Down Expand Up @@ -31,7 +31,7 @@ const getPreferredLanguage = (sortedAcceptLanguagesArray: string[]): Lang => {
const matchingLang = Object.keys(ACCEPT_LANG_MAP).find(key => lang.includes(key));
if (matchingLang) return ACCEPT_LANG_MAP[matchingLang];
}
return nextI18NextConfig.defaultLang;
return defaultLang;
};

/**
Expand All @@ -44,7 +44,7 @@ export const detectLocaleFromBrowserAcceptLanguage = (headers: IncomingHttpHeade
const acceptLanguages = headers['accept-language'];

if (acceptLanguages == null) {
return nextI18NextConfig.defaultLang;
return defaultLang;
}

// 1. trim blank spaces.
Expand Down
6 changes: 4 additions & 2 deletions apps/app/src/server/routes/apiv3/page/create-page.ts
Expand Up @@ -22,6 +22,7 @@ import {
import type { PageDocument, PageModel } from '~/server/models/page';
import PageTagRelation from '~/server/models/page-tag-relation';
import { configManager } from '~/server/service/config-manager';
import { getTranslation } from '~/server/service/i18next';
import loggerFactory from '~/utils/logger';

import { apiV3FormValidator } from '../../../middlewares/apiv3-form-validator';
Expand All @@ -43,8 +44,9 @@ async function generateUntitledPath(parentPath: string, basePathname: string, in
}

async function determinePath(_parentPath?: string, _path?: string, optionalParentPath?: string): Promise<string> {
// TODO: https://redmine.weseek.co.jp/issues/142729
const basePathname = 'Untitled';
const { t } = await getTranslation();

const basePathname = t?.('create_page.untitled') || 'Untitled';

if (_path != null) {
const path = normalizePath(_path);
Expand Down
41 changes: 41 additions & 0 deletions apps/app/src/server/service/i18next.ts
@@ -0,0 +1,41 @@
import type { Lang } from '@growi/core';
import type { TFunction, i18n } from 'i18next';
import { createInstance } from 'i18next';
import resourcesToBackend from 'i18next-resources-to-backend';

import { defaultLang, initOptions } from '^/config/i18next.config';

import { configManager } from './config-manager';


const initI18next = async(lang: Lang = defaultLang) => {
const i18nInstance = createInstance();
await i18nInstance
.use(
resourcesToBackend(
(language: string, namespace: string) => {
return import(`^/public/static/locales/${language}/${namespace}.json`);
},
),
)
.init({
...initOptions,
lng: lang,
});
return i18nInstance;
};

type Translation = {
t: TFunction,
i18n: i18n
}

export async function getTranslation(lang?: Lang): Promise<Translation> {
const globalLang = configManager.getConfig('crowi', 'app:globalLang') as Lang;
const i18nextInstance = await initI18next(globalLang);

return {
t: i18nextInstance.getFixedT(lang ?? globalLang),
i18n: i18nextInstance,
};
}
7 changes: 7 additions & 0 deletions yarn.lock
Expand Up @@ -10061,6 +10061,13 @@ i18next-localstorage-backend@^4.2.0:
dependencies:
"@babel/runtime" "^7.22.15"

i18next-resources-to-backend@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/i18next-resources-to-backend/-/i18next-resources-to-backend-1.2.1.tgz#fded121e63e3139ce839c9901b9449dbbea7351d"
integrity sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==
dependencies:
"@babel/runtime" "^7.23.2"

i18next@^23.10.1:
version "23.10.1"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.10.1.tgz#217ce93b75edbe559ac42be00a20566b53937df6"
Expand Down

0 comments on commit bb85b12

Please sign in to comment.