website: update translation docs (#5875)
* website/docs: remove lingui references Signed-off-by: Jens Langhammer <jens@goauthentik.io> * replace deprecated cryptography types Signed-off-by: Jens Langhammer <jens@goauthentik.io> * tell eslint to avoid escapes in strings when possible Signed-off-by: Jens Langhammer <jens@goauthentik.io> * ignore generated locale code Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
d9eaefa68a
commit
69f0460f69
4
Makefile
4
Makefile
|
@ -52,7 +52,7 @@ lint:
|
||||||
migrate:
|
migrate:
|
||||||
python -m lifecycle.migrate
|
python -m lifecycle.migrate
|
||||||
|
|
||||||
i18n-extract: i18n-extract-core web-extract
|
i18n-extract: i18n-extract-core web-i18n-extract
|
||||||
|
|
||||||
i18n-extract-core:
|
i18n-extract-core:
|
||||||
ak makemessages --ignore web --ignore internal --ignore web --ignore web-api --ignore website -l en
|
ak makemessages --ignore web --ignore internal --ignore web --ignore web-api --ignore website -l en
|
||||||
|
@ -150,7 +150,7 @@ web-lint:
|
||||||
web-check-compile:
|
web-check-compile:
|
||||||
cd web && npm run tsc
|
cd web && npm run tsc
|
||||||
|
|
||||||
web-extract:
|
web-i18n-extract:
|
||||||
cd web && npm run extract
|
cd web && npm run extract
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
|
|
|
@ -7,7 +7,7 @@ from cryptography import x509
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import hashes, serialization
|
from cryptography.hazmat.primitives import hashes, serialization
|
||||||
from cryptography.hazmat.primitives.asymmetric import ec, rsa
|
from cryptography.hazmat.primitives.asymmetric import ec, rsa
|
||||||
from cryptography.hazmat.primitives.asymmetric.types import PRIVATE_KEY_TYPES
|
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes
|
||||||
from cryptography.x509.oid import NameOID
|
from cryptography.x509.oid import NameOID
|
||||||
|
|
||||||
from authentik import __version__
|
from authentik import __version__
|
||||||
|
@ -40,7 +40,7 @@ class CertificateBuilder:
|
||||||
self.cert.save()
|
self.cert.save()
|
||||||
return self.cert
|
return self.cert
|
||||||
|
|
||||||
def generate_private_key(self) -> PRIVATE_KEY_TYPES:
|
def generate_private_key(self) -> PrivateKeyTypes:
|
||||||
"""Generate private key"""
|
"""Generate private key"""
|
||||||
if self._use_ec_private_key:
|
if self._use_ec_private_key:
|
||||||
return ec.generate_private_key(curve=ec.SECP256R1)
|
return ec.generate_private_key(curve=ec.SECP256R1)
|
||||||
|
|
|
@ -6,7 +6,7 @@ from uuid import uuid4
|
||||||
|
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import hashes
|
from cryptography.hazmat.primitives import hashes
|
||||||
from cryptography.hazmat.primitives.asymmetric.types import PRIVATE_KEY_TYPES, PUBLIC_KEY_TYPES
|
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes, PublicKeyTypes
|
||||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||||
from cryptography.x509 import Certificate, load_pem_x509_certificate
|
from cryptography.x509 import Certificate, load_pem_x509_certificate
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
@ -37,8 +37,8 @@ class CertificateKeyPair(SerializerModel, ManagedModel, CreatedUpdatedModel):
|
||||||
)
|
)
|
||||||
|
|
||||||
_cert: Optional[Certificate] = None
|
_cert: Optional[Certificate] = None
|
||||||
_private_key: Optional[PRIVATE_KEY_TYPES] = None
|
_private_key: Optional[PrivateKeyTypes] = None
|
||||||
_public_key: Optional[PUBLIC_KEY_TYPES] = None
|
_public_key: Optional[PublicKeyTypes] = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def serializer(self) -> Serializer:
|
def serializer(self) -> Serializer:
|
||||||
|
@ -56,7 +56,7 @@ class CertificateKeyPair(SerializerModel, ManagedModel, CreatedUpdatedModel):
|
||||||
return self._cert
|
return self._cert
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def public_key(self) -> Optional[PUBLIC_KEY_TYPES]:
|
def public_key(self) -> Optional[PublicKeyTypes]:
|
||||||
"""Get public key of the private key"""
|
"""Get public key of the private key"""
|
||||||
if not self._public_key:
|
if not self._public_key:
|
||||||
self._public_key = self.private_key.public_key()
|
self._public_key = self.private_key.public_key()
|
||||||
|
@ -65,7 +65,7 @@ class CertificateKeyPair(SerializerModel, ManagedModel, CreatedUpdatedModel):
|
||||||
@property
|
@property
|
||||||
def private_key(
|
def private_key(
|
||||||
self,
|
self,
|
||||||
) -> Optional[PRIVATE_KEY_TYPES]:
|
) -> Optional[PrivateKeyTypes]:
|
||||||
"""Get python cryptography PrivateKey instance"""
|
"""Get python cryptography PrivateKey instance"""
|
||||||
if not self._private_key and self.key_data != "":
|
if not self._private_key and self.key_data != "":
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -9,7 +9,7 @@ from urllib.parse import urlparse, urlunparse
|
||||||
|
|
||||||
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
|
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
|
||||||
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
|
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
|
||||||
from cryptography.hazmat.primitives.asymmetric.types import PRIVATE_KEY_TYPES
|
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes
|
||||||
from dacite.core import from_dict
|
from dacite.core import from_dict
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
|
@ -215,7 +215,7 @@ class OAuth2Provider(Provider):
|
||||||
)
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def jwt_key(self) -> tuple[str | PRIVATE_KEY_TYPES, str]:
|
def jwt_key(self) -> tuple[str | PrivateKeyTypes, str]:
|
||||||
"""Get either the configured certificate or the client secret"""
|
"""Get either the configured certificate or the client secret"""
|
||||||
if not self.signing_key:
|
if not self.signing_key:
|
||||||
# No Certificate at all, assume HS256
|
# No Certificate at all, assume HS256
|
||||||
|
|
|
@ -4,3 +4,4 @@ node_modules
|
||||||
dist
|
dist
|
||||||
# don't lint nyc coverage output
|
# don't lint nyc coverage output
|
||||||
coverage
|
coverage
|
||||||
|
src/locale-codes.ts
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
"rules": {
|
"rules": {
|
||||||
"indent": "off",
|
"indent": "off",
|
||||||
"linebreak-style": ["error", "unix"],
|
"linebreak-style": ["error", "unix"],
|
||||||
"quotes": ["error", "double"],
|
"quotes": ["error", "double", { "avoidEscape": true }],
|
||||||
"semi": ["error", "always"],
|
"semi": ["error", "always"],
|
||||||
"@typescript-eslint/ban-ts-comment": "off"
|
"@typescript-eslint/ban-ts-comment": "off"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,3 +6,4 @@ dist
|
||||||
coverage
|
coverage
|
||||||
# Import order matters
|
# Import order matters
|
||||||
poly.ts
|
poly.ts
|
||||||
|
src/locale-codes.ts
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"trailingComma": "all",
|
"trailingComma": "all",
|
||||||
"useTabs": false,
|
"useTabs": false,
|
||||||
"vueIndentScriptAndStyle": false,
|
"vueIndentScriptAndStyle": false,
|
||||||
"importOrder": ["^@lingui/(.*)$", "^(@?)lit(.*)$", "\\.css$", "^@goauthentik/api$", "^[./]"],
|
"importOrder": ["^(@?)lit(.*)$", "\\.css$", "^@goauthentik/api$", "^[./]"],
|
||||||
"importOrderSeparation": true,
|
"importOrderSeparation": true,
|
||||||
"importOrderSortSpecifiers": true,
|
"importOrderSortSpecifiers": true,
|
||||||
"importOrderParserPlugins": ["typescript", "classProperties", "decorators-legacy"]
|
"importOrderParserPlugins": ["typescript", "classProperties", "decorators-legacy"]
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
import { formatter } from "@lingui/format-po-gettext";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
sourceLocale: "en",
|
|
||||||
locales: [
|
|
||||||
"en",
|
|
||||||
"pseudo-LOCALE",
|
|
||||||
"fr_FR",
|
|
||||||
"tr",
|
|
||||||
"es",
|
|
||||||
"pl",
|
|
||||||
"zh_TW",
|
|
||||||
"zh-Hans",
|
|
||||||
"zh-Hant",
|
|
||||||
"de",
|
|
||||||
],
|
|
||||||
pseudoLocale: "pseudo-LOCALE",
|
|
||||||
fallbackLocales: {
|
|
||||||
"pseudo-LOCALE": "en",
|
|
||||||
"default": "en",
|
|
||||||
},
|
|
||||||
compileNamespace: "ts",
|
|
||||||
catalogs: [
|
|
||||||
{
|
|
||||||
path: "src/locales/{locale}",
|
|
||||||
include: ["src"],
|
|
||||||
exclude: ["**/node_modules/**", "**/dist/**"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
format: formatter({ lineNumbers: false }),
|
|
||||||
};
|
|
|
@ -5,9 +5,8 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"extract-locales": "lit-localize extract",
|
"extract-locales": "lit-localize extract",
|
||||||
"build-locales": "run-s build-locales:build build-locales:repair",
|
"build-locales": "run-s build-locales:build",
|
||||||
"build-locales:build": "lit-localize build",
|
"build-locales:build": "lit-localize build",
|
||||||
"build-locales:repair": "prettier --write ./src/locale-codes.ts",
|
|
||||||
"build": "lit-localize build && node --max-old-space-size=4096 node_modules/.bin/rollup -c ./rollup.config.js",
|
"build": "lit-localize build && node --max-old-space-size=4096 node_modules/.bin/rollup -c ./rollup.config.js",
|
||||||
"build-proxy": "lit-localize build && node --max-old-space-size=4096 node_modules/.bin/rollup -c ./rollup.proxy.js",
|
"build-proxy": "lit-localize build && node --max-old-space-size=4096 node_modules/.bin/rollup -c ./rollup.proxy.js",
|
||||||
"watch": "lit-localize build && node --max-old-space-size=8192 node_modules/.bin/rollup -c -w",
|
"watch": "lit-localize build && node --max-old-space-size=8192 node_modules/.bin/rollup -c -w",
|
||||||
|
|
|
@ -4,38 +4,38 @@
|
||||||
/**
|
/**
|
||||||
* The locale code that templates in this source code are written in.
|
* The locale code that templates in this source code are written in.
|
||||||
*/
|
*/
|
||||||
export const sourceLocale = "en";
|
export const sourceLocale = `en`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The other locale codes that this application is localized into. Sorted
|
* The other locale codes that this application is localized into. Sorted
|
||||||
* lexicographically.
|
* lexicographically.
|
||||||
*/
|
*/
|
||||||
export const targetLocales = [
|
export const targetLocales = [
|
||||||
"de",
|
`de`,
|
||||||
"en",
|
`en`,
|
||||||
"es",
|
`es`,
|
||||||
"fr_FR",
|
`fr_FR`,
|
||||||
"pl",
|
`pl`,
|
||||||
"pseudo-LOCALE",
|
`pseudo-LOCALE`,
|
||||||
"tr",
|
`tr`,
|
||||||
"zh_TW",
|
`zh_TW`,
|
||||||
"zh-Hans",
|
`zh-Hans`,
|
||||||
"zh-Hant",
|
`zh-Hant`,
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All valid project locale codes. Sorted lexicographically.
|
* All valid project locale codes. Sorted lexicographically.
|
||||||
*/
|
*/
|
||||||
export const allLocales = [
|
export const allLocales = [
|
||||||
"de",
|
`de`,
|
||||||
"en",
|
`en`,
|
||||||
"en",
|
`en`,
|
||||||
"es",
|
`es`,
|
||||||
"fr_FR",
|
`fr_FR`,
|
||||||
"pl",
|
`pl`,
|
||||||
"pseudo-LOCALE",
|
`pseudo-LOCALE`,
|
||||||
"tr",
|
`tr`,
|
||||||
"zh_TW",
|
`zh_TW`,
|
||||||
"zh-Hans",
|
`zh-Hans`,
|
||||||
"zh-Hant",
|
`zh-Hant`,
|
||||||
] as const;
|
] as const;
|
||||||
|
|
|
@ -4,7 +4,7 @@ title: Translations
|
||||||
|
|
||||||
Translation in authentik is done in two places. Most of the text is defined in the frontend in `web/`, and a subset of messages is defined in the backend.
|
Translation in authentik is done in two places. Most of the text is defined in the frontend in `web/`, and a subset of messages is defined in the backend.
|
||||||
|
|
||||||
The frontend uses [lingui](https://lingui.js.org/), and the backend uses the built-in django translation tools.
|
The frontend uses [@lit/localize](https://lit.dev/docs/localization/overview/), and the backend uses the built-in django translation tools.
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
Please review the [Writing documentation](./docs/writing-documentation) guidelines as they apply to documentation too.
|
Please review the [Writing documentation](./docs/writing-documentation) guidelines as they apply to documentation too.
|
||||||
|
@ -24,22 +24,21 @@ To simplify translation you can use https://www.transifex.com/authentik/authenti
|
||||||
|
|
||||||
Run `npm i` in the `/web` folder to install all dependencies.
|
Run `npm i` in the `/web` folder to install all dependencies.
|
||||||
|
|
||||||
Ensure the language code is in the `package.json` file in `web/`:
|
Ensure the language code is in the `lit-localize.json` file in `web/`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
// [...]
|
// [...]
|
||||||
"lingui": {
|
"targetLocales": [
|
||||||
|
"en",
|
||||||
|
"pseudo-LOCALE",
|
||||||
|
"a-new-locale"
|
||||||
// [...]
|
// [...]
|
||||||
"locales": [
|
],
|
||||||
"en",
|
|
||||||
"pseudo-LOCALE",
|
|
||||||
"a-new-locale"
|
|
||||||
],
|
|
||||||
// [...]
|
// [...]
|
||||||
```
|
```
|
||||||
|
|
||||||
Afterwards, run `npx lingui extract` to generate a base .po file.
|
Afterwards, run `make web-i18n-extract` to generate a base .xlf file.
|
||||||
|
|
||||||
The .po files can be edited by any text editor, or using a tool such as [POEdit](https://poedit.net/).
|
The .xlf files can be edited by any text editor, or using a tool such as [POEdit](https://poedit.net/).
|
||||||
|
|
||||||
To see the change, run `npm run watch` in the `web/` directory.
|
To see the change, run `make web-watch` in the root directory of the repository.
|
||||||
|
|
Reference in New Issue