Skip to content

Commit 2211d09

Browse files
authored
Merge pull request #807 from semoal/feat-accept-t-as-expression
feat: accept t as function
2 parents 53ffaa8 + 4b430a0 commit 2211d09

3 files changed

Lines changed: 110 additions & 1 deletion

File tree

docs/ref/macro.rst

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ Examples of JS macros
138138
+-------------------------------------------------------------+--------------------------------------------------------------------+
139139
| .. code-block:: js | .. code-block:: js |
140140
| | |
141+
| t({ | i18n._(/*i18n*/{ |
142+
| id: "msg.refresh", | id: "msg.refresh", |
143+
| message: "Refresh inbox" | message: "Refresh inbox" |
144+
| }) | }) |
145+
+-------------------------------------------------------------+--------------------------------------------------------------------+
146+
| .. code-block:: js | .. code-block:: js |
147+
| | |
141148
| describeMessage({ | /*i18n*/{ |
142149
| id: "msg.refresh", | id: "msg.refresh", |
143150
| message: "Refresh inbox" | message: "Refresh inbox" |
@@ -174,7 +181,7 @@ Examples of JSX macros
174181
+-------------------------------------------------------------+--------------------------------------------------------------------+
175182
| .. code-block:: jsx | .. code-block:: jsx |
176183
| | |
177-
| <Trans id=" msg.refresh"> | <Trans |
184+
| <Trans id="msg.refresh"> | <Trans |
178185
| Refresh inbox | id="msg.refresh" |
179186
| </Trans> | message="Refresh inbox" |
180187
| | /> |
@@ -271,6 +278,46 @@ other expressions are referenced by numeric index:
271278
values: { 0: date(name) }
272279
})
273280
281+
It's also possible to pass custom ``id`` and ``comment`` for translators by
282+
calling ``t`` macro with a message descriptor:
283+
284+
.. code-block:: jsx
285+
286+
import { t } from "@lingui/macro"
287+
const message = t({
288+
id: 'msg.hello',
289+
comment: 'Greetings at the homepage',
290+
message: `Hello ${name}`
291+
})
292+
293+
// ↓ ↓ ↓ ↓ ↓ ↓
294+
295+
import { i18n } from "@lingui/core"
296+
const message = i18n._(/*i18n*/{
297+
id: 'msg.hello',
298+
comment: 'Greetings at the homepage',
299+
message: 'Hello {name}'
300+
})
301+
302+
In this case the ``message`` is used as a default message and it's transformed
303+
as if it were wrapped in ``t`` macro. ``message`` also accepts any other macros:
304+
305+
.. code-block:: jsx
306+
307+
import { t } from "@lingui/macro"
308+
const message = t({
309+
id: 'msg.plural',
310+
message: plural(value, { one: "...", other: "..." })
311+
})
312+
313+
// ↓ ↓ ↓ ↓ ↓ ↓
314+
315+
import { i18n } from "@lingui/core"
316+
const message = i18n._(/*i18n*/{
317+
id: 'msg.plural',
318+
message: '{value, plural, one {...} other {...}}'
319+
})
320+
274321
plural
275322
^^^^^^
276323

@@ -363,6 +410,11 @@ two counters:
363410
However, simple is better because in the end it's the translator who's gonna
364411
have to translate these long and complex strings.
365412

413+
.. important::
414+
415+
Use ``plural`` inside :jsmacro:`t` macro if you want to add custom ``id``
416+
or ``comment`` for translators.
417+
366418
selectOrdinal
367419
^^^^^^^^^^^^^
368420

@@ -393,6 +445,11 @@ cardinal plural forms it uses ordinal forms:
393445
values: { count }
394446
})
395447
448+
.. important::
449+
450+
Use ``selectOrdinal`` inside :jsmacro:`t` macro if you want to add custom ``id``
451+
or ``comment`` for translators.
452+
396453
select
397454
^^^^^^
398455

@@ -422,6 +479,11 @@ provided in ``options`` object which key matches exactly ``value``:
422479
values: { gender }
423480
})
424481
482+
.. important::
483+
484+
Use ``select`` inside :jsmacro:`t` macro if you want to add custom ``id``
485+
or ``comment`` for translators.
486+
425487
defineMessage
426488
^^^^^^^^^^^^^
427489

packages/macro/src/macroJs.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ export default class MacroJs {
9898
return
9999
}
100100

101+
if (this.types.isCallExpression(path.node) && this.isIdentifier(path.node.callee, "t")) {
102+
this.replaceTAsFunction(path)
103+
return
104+
}
105+
101106
const tokens = this.tokenizeNode(path.node)
102107

103108
const messageFormat = new ICUMessageFormat()
@@ -142,6 +147,26 @@ export default class MacroJs {
142147
path.replaceWith(descriptor)
143148
}
144149

150+
/**
151+
* macro `t` is called with MessageDescriptor, after that
152+
* we create a new node to append it to i18n._
153+
*/
154+
replaceTAsFunction = (path) => {
155+
const descriptor = this.processDescriptor(path.node.arguments[0])
156+
const newNode = this.types.callExpression(
157+
this.types.memberExpression(
158+
this.types.identifier(this.i18nImportName),
159+
this.types.identifier("_")
160+
),
161+
[descriptor]
162+
)
163+
164+
this.addExtractMark(path)
165+
166+
// @ts-ignore
167+
path.replaceWith(newNode)
168+
}
169+
145170
/**
146171
* `processDescriptor` expand macros inside messsage descriptor.
147172
* Message descriptor is used in `defineMessage`.

packages/macro/test/js-t.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,28 @@ export default [
8282
i18n._("Multiline\\nstring")
8383
`,
8484
},
85+
{
86+
name: "Support id and comment in t macro as callExpression",
87+
input: `
88+
import { t } from '@lingui/macro'
89+
t({
90+
id: 'msgId_2',
91+
message: 'text',
92+
comment: 'description for translators'
93+
})
94+
t({ id: 'msgId', comment: 'description for translators', message: plural(val, { one: '...', other: '...' }) })
95+
`,
96+
expected: `
97+
import { i18n } from "@lingui/core"
98+
/*i18n*/
99+
i18n._({ id: "msgId_2", message: 'text', comment: 'description for translators' })
100+
101+
/*i18n*/
102+
i18n._({ id: "msgId", comment: 'description for translators', message: '{val, plural, one {...} other {...}}', values: {
103+
val: val,
104+
} })
105+
`,
106+
},
85107
{
86108
name: "Newlines after continuation character are removed",
87109
filename: "js-t-continuation-character.js",

0 commit comments

Comments
 (0)