Skip to content

Commit

Permalink
feat(macro): Add support for passing custom i18n instance (#1139)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroenvisser101 authored Sep 28, 2021
1 parent 6b2d662 commit 5cad96f
Show file tree
Hide file tree
Showing 7 changed files with 410 additions and 41 deletions.
30 changes: 28 additions & 2 deletions docs/ref/macro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ transformed into ``i18n._`` call.

By default, the ``i18n`` object is imported from ``@lingui/core``.
If you use a custom instance of ``i18n`` object, you need to set
:conf:`runtimeConfigModule`
:conf:`runtimeConfigModule` or pass a custom instance to :jsmacro:`t`.

The only exception is :jsmacro:`defineMessage` which is transformed into
message descriptor. In other words, the message isn't translated directly
Expand Down Expand Up @@ -122,6 +122,16 @@ Examples of JS macros
+-------------------------------------------------------------+--------------------------------------------------------------------+
| .. code-block:: js | .. code-block:: js |
| | |
| t(customI18n)`Refresh inbox` | /*i18n*/ |
| | customI18n._("Refresh inbox") |
+-------------------------------------------------------------+--------------------------------------------------------------------+
| .. code-block:: js | .. code-block:: js |
| | |
| t(customI18n)`Attachment ${name} saved` | /*i18n*/ |
| | customI18n._("Attachment {name} saved", { name }) |
+-------------------------------------------------------------+--------------------------------------------------------------------+
| .. code-block:: js | .. code-block:: js |
| | |
| plural(count, { | /*i18n*/ |
| one: "Message", | i18n._("{count, plural, one {Message} other {Messages}}", { |
| other: "Messages" | count |
Expand Down Expand Up @@ -184,7 +194,7 @@ into a *Message Descriptor* wrapped inside of ``i18n._`` call.

By default, the ``i18n`` object is imported from ``@lingui/core``.
If you use a custom instance of ``i18n`` object, you need to set
:conf:`runtimeConfigModule`
:conf:`runtimeConfigModule` or pass a custom instance to :jsmacro:`t`.

*Message Descriptor* is an object with message ID, default message and other parameters.
``i18n._`` accepts message descriptors and performs translation and formatting:
Expand Down Expand Up @@ -265,6 +275,22 @@ other expressions are referenced by numeric index:
0: new Date()
});
Optionally, a custom ``i18n`` instance can be passed that can be used
instead of the global instance:

.. code-block:: jsx
import { t } from "@lingui/macro"
import { i18n } from "./lingui"
const message = t(i18n)`Hello World`
// ↓ ↓ ↓ ↓ ↓ ↓
import { i18n } from "./lingui"
const message =
/*i18n*/
i18n._("Hello World")
It's also possible to pass custom ``id`` and ``comment`` for translators by
calling ``t`` macro with a message descriptor:

Expand Down
160 changes: 151 additions & 9 deletions packages/macro/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,68 @@
declare module '@lingui/macro' {
import type { MessageDescriptor } from "@lingui/core"
declare module "@lingui/macro" {
import type { MessageDescriptor, I18n } from "@lingui/core"

export type BasicType = {
id?: string
comment?: string
}

/**
* Translates a message descriptor
*
* @example
* ```
* import { t } from "@lingui/macro";
* const message = t({
* id: "msg.hello",
* comment: "Greetings at the homepage",
* message: `Hello ${name}`,
* });
* ```
*
* @example
* ```
* import { t } from "@lingui/macro";
* const message = t({
* id: "msg.plural",
* message: plural(value, { one: "...", other: "..." }),
* });
* ```
*
* @param messageDescriptior The descriptor to translate
*/
export function t(messageDescriptior: MessageDescriptor): string

/**
* Translates a template string using the global I18n instance
*
* @example
* ```
* import { t } from "@lingui/macro";
* const message = t`Hello ${name}`;
* ```
*/
export function t(
literals: TemplateStringsArray,
...placeholders: any[]
): string

/**
* Translates a template string using a given I18n instance
*
* @example
* ```
* import { t } from "@lingui/macro";
* import { I18n } from "@lingui/core";
* const i18n = new I18n({
* locale: "nl",
* messages: { "Hello {0}": "Hallo {0}" },
* });
* const message = t(i18n)`Hello ${name}`;
* ```
*/
export function t(
literals: TemplateStringsArray | MessageDescriptor,
i18n: I18n,
literals: TemplateStringsArray,
...placeholders: any[]
): string

Expand All @@ -21,20 +76,107 @@ declare module '@lingui/macro' {
other?: T
} & UnderscoreDigit<T>

export function plural(arg: number | string, options: ChoiceOptions & BasicType): string
/**
* Pluralize a message
*
* @example
* ```
* import { plural } from "@lingui/macro";
* const message = plural(count, {
* one: "# Book",
* other: "# Books",
* });
* ```
*
* @param value Determines the plural form
* @param options Object with available plural forms
*/
export function plural(
value: number | string,
options: ChoiceOptions & BasicType
): string

/**
* Pluralize a message using ordinal forms
*
* Similar to `plural` but instead of using cardinal plural forms,
* it uses ordinal forms.
*
* @example
* ```
* import { selectOrdinal } from "@lingui/macro";
* const message = selectOrdinal(count, {
* one: "1st",
* two: "2nd",
* few: "3rd",
* other: "#th",
* });
* ```
*
* @param value Determines the plural form
* @param options Object with available plural forms
*/
export function selectOrdinal(
arg: number | string,
value: number | string,
options: ChoiceOptions & BasicType
): string
export function select(arg: string, choices: Record<string, string> & BasicType): string

/**
* Selects a translation based on a value
*
* Select works like a switch statement. It will
* select one of the forms in `options` object which
* key matches exactly `value`.
*
* @example
* ```
* import { select } from "@lingui/macro";
* const message = select(gender, {
* male: "he",
* female: "she",
* other: "they",
* });
* ```
*
* @param value The key of choices to use
* @param choices
*/
export function select(
value: string,
choices: Record<string, string> & BasicType
): string

/**
* Defines multiple messages for extraction
*/
export function defineMessages<M extends Record<string, MessageDescriptor>>(
messages: M
): M
export function defineMessage(descriptor: MessageDescriptor): MessageDescriptor

/**
* Define a message for later use
*
* `defineMessage` can be used to add comments for translators,
* or to override the message ID.
*
* @example
* ```
* import { defineMessage } from "@lingui/macro";
* const message = defineMessage({
* comment: "Greetings on the welcome page",
* message: `Welcome, ${name}!`,
* });
* ```
*
* @param descriptor The message descriptor
*/
export function defineMessage(
descriptor: MessageDescriptor
): MessageDescriptor

export type ChoiceProps = {
value?: string | number
} & ChoiceOptions<string>
} & ChoiceOptions<string>

/**
* The types should be changed after this PR is merged
Expand All @@ -60,4 +202,4 @@ declare module '@lingui/macro' {
export const Plural: any
export const Select: any
export const SelectOrdinal: any
}
}
Loading

1 comment on commit 5cad96f

@vercel
Copy link

@vercel vercel bot commented on 5cad96f Sep 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.