@intlayer/docs 9.1.0 → 9.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/ar/dynamic_dictionaries/variants.md +248 -5
- package/docs/de/dynamic_dictionaries/variants.md +208 -1
- package/docs/en/dynamic_dictionaries/variants.md +208 -1
- package/docs/en-GB/dynamic_dictionaries/variants.md +208 -1
- package/docs/es/dynamic_dictionaries/variants.md +208 -1
- package/docs/fr/dynamic_dictionaries/variants.md +208 -1
- package/docs/hi/dynamic_dictionaries/variants.md +210 -3
- package/docs/id/dynamic_dictionaries/variants.md +208 -1
- package/docs/it/dynamic_dictionaries/variants.md +209 -2
- package/docs/ja/dynamic_dictionaries/variants.md +209 -2
- package/docs/ko/dynamic_dictionaries/variants.md +209 -2
- package/docs/pl/dynamic_dictionaries/variants.md +209 -2
- package/docs/pt/dynamic_dictionaries/variants.md +208 -1
- package/docs/ru/dynamic_dictionaries/variants.md +209 -2
- package/docs/tr/dynamic_dictionaries/variants.md +209 -2
- package/docs/uk/dynamic_dictionaries/variants.md +208 -1
- package/docs/vi/dynamic_dictionaries/variants.md +210 -3
- package/docs/zh/dynamic_dictionaries/variants.md +209 -2
- package/package.json +6 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-08-04
|
|
4
4
|
title: 변형
|
|
5
5
|
description: Intlayer 콘텐츠 파일에서 variant 메타데이터 필드를 사용하여 이름이 지정되었거나 구조화된 콘텐츠 대안 — A/B 테스트, 시즌 배너, 기능 플래그 텍스트, CMS 레코드, 사용자별 콘텐츠 — 을 선언하고 코드 변경 없이 런타임에 전환합니다.
|
|
6
6
|
keywords:
|
|
@@ -22,7 +22,13 @@ history:
|
|
|
22
22
|
changes: "변형 기능 출시"
|
|
23
23
|
- version: 9.1.0
|
|
24
24
|
date: 2026-06-26
|
|
25
|
-
changes: "
|
|
25
|
+
changes: "`variant`는 이제 문자열 또는 객체를 허용합니다 — 이전의 `meta` / 동적 레코드는 객체 변형으로 선언됩니다"
|
|
26
|
+
- version: 9.1.1
|
|
27
|
+
date: 2026-07-31
|
|
28
|
+
changes: "변형은 재정의하는 키만 선언합니다. 선언되지 않은 변형은 기본 항목으로 대체됩니다"
|
|
29
|
+
- version: 9.1.2
|
|
30
|
+
date: 2026-08-04
|
|
31
|
+
changes: "프로바이더가 앰비언트 `variant` 프로퍼티를 받고, 셀렉터가 순서가 있는 우선순위 체인을 받습니다"
|
|
26
32
|
author: aymericzip
|
|
27
33
|
---
|
|
28
34
|
|
|
@@ -77,6 +83,37 @@ const dictionary = {
|
|
|
77
83
|
export default dictionary;
|
|
78
84
|
```
|
|
79
85
|
|
|
86
|
+
### 부분 변형
|
|
87
|
+
|
|
88
|
+
변형은 **재정의하는 키만 선언합니다**. 나머지는 기본 항목에서 상속됩니다.
|
|
89
|
+
|
|
90
|
+
```ts fileName="hero-banner.summer.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
91
|
+
import { t, type Dictionary } from "intlayer";
|
|
92
|
+
|
|
93
|
+
const dictionary = {
|
|
94
|
+
key: "hero-banner",
|
|
95
|
+
variant: "summer",
|
|
96
|
+
content: {
|
|
97
|
+
headline: t({
|
|
98
|
+
en: "Build faster all summer",
|
|
99
|
+
fr: "Développez plus vite tout l'été",
|
|
100
|
+
}),
|
|
101
|
+
},
|
|
102
|
+
} satisfies Dictionary;
|
|
103
|
+
|
|
104
|
+
export default dictionary;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
109
|
+
// → { headline: "Développez plus vite tout l'été", cta: "Commencer" } — `cta`가 상속됨
|
|
110
|
+
|
|
111
|
+
useIntlayer("hero-banner", { variant: "never-declared" });
|
|
112
|
+
// → 기본 항목
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
따라서 텍스트가 실제로 다른 곳에만 변형 파일을 추가하면 됩니다. 변형을 선언했지만 기본 항목이 없는 경우에만 키가 `null`로 확인됩니다.
|
|
116
|
+
|
|
80
117
|
### 이름 지정 변형 사용
|
|
81
118
|
|
|
82
119
|
#### 기본 변형
|
|
@@ -464,6 +501,176 @@ const content = useIntlayer("product", {
|
|
|
464
501
|
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
465
502
|
```
|
|
466
503
|
|
|
504
|
+
## 앰비언트 변형
|
|
505
|
+
|
|
506
|
+
테넌트, 학교 유형, 요금제 등급처럼 세션 전체에서 고정되는 변형 차원이 있습니다. 이런 값은 한 번만 결정되며, 어떤 컴포넌트도 직접 전달할 필요가 없어야 합니다.
|
|
507
|
+
|
|
508
|
+
> 이 값을 주입하려고 `useIntlayer`를 직접 만든 훅으로 감싸지 마세요. 빌드 타임 최적화는 프레임워크 패키지에서 임포트한 리터럴 `useIntlayer("key")` 호출만 다시 작성하므로, 래퍼 뒤에 있는 것은 번들에 포함되지 않습니다.
|
|
509
|
+
|
|
510
|
+
대신 `locale`과 똑같이 프로바이더에서 변형을 한 번만 선언하세요:
|
|
511
|
+
|
|
512
|
+
<Tabs group="framework">
|
|
513
|
+
<Tab label="React" value="react">
|
|
514
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
515
|
+
import { IntlayerProvider } from "react-intlayer";
|
|
516
|
+
|
|
517
|
+
export const App = ({ locale, schoolType }) => (
|
|
518
|
+
<IntlayerProvider locale={locale} variant={schoolType}>
|
|
519
|
+
<Hero />
|
|
520
|
+
</IntlayerProvider>
|
|
521
|
+
);
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
</Tab>
|
|
525
|
+
<Tab label="Next.js" value="nextjs">
|
|
526
|
+
```tsx fileName="layout.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
527
|
+
import { IntlayerServerProvider } from "next-intlayer/server";
|
|
528
|
+
import { IntlayerClientProvider } from "next-intlayer";
|
|
529
|
+
|
|
530
|
+
export default async function Layout({ children, params }) {
|
|
531
|
+
const { locale } = await params;
|
|
532
|
+
const schoolType = await getSchoolType();
|
|
533
|
+
|
|
534
|
+
return (
|
|
535
|
+
<IntlayerServerProvider locale={locale} variant={schoolType}>
|
|
536
|
+
<IntlayerClientProvider locale={locale} variant={schoolType}>
|
|
537
|
+
{children}
|
|
538
|
+
</IntlayerClientProvider>
|
|
539
|
+
</IntlayerServerProvider>
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
</Tab>
|
|
545
|
+
<Tab label="Vue" value="vue">
|
|
546
|
+
```ts fileName="main.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
547
|
+
import { createApp } from "vue";
|
|
548
|
+
import { installIntlayer } from "vue-intlayer";
|
|
549
|
+
import App from "./App.vue";
|
|
550
|
+
|
|
551
|
+
const app = createApp(App);
|
|
552
|
+
|
|
553
|
+
installIntlayer(app, { locale: "en", variant: schoolType });
|
|
554
|
+
|
|
555
|
+
app.mount("#app");
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
</Tab>
|
|
559
|
+
<Tab label="Svelte" value="svelte">
|
|
560
|
+
```svelte fileName="+layout.svelte" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
561
|
+
<script lang="ts">
|
|
562
|
+
import { setupIntlayer } from "svelte-intlayer";
|
|
563
|
+
|
|
564
|
+
export let schoolType: string;
|
|
565
|
+
|
|
566
|
+
setupIntlayer("en", schoolType);
|
|
567
|
+
</script>
|
|
568
|
+
|
|
569
|
+
<slot />
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
</Tab>
|
|
573
|
+
<Tab label="Preact" value="preact">
|
|
574
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
575
|
+
import { IntlayerProvider } from "preact-intlayer";
|
|
576
|
+
|
|
577
|
+
export const App = ({ locale, schoolType }) => (
|
|
578
|
+
<IntlayerProvider locale={locale} variant={schoolType}>
|
|
579
|
+
<Hero />
|
|
580
|
+
</IntlayerProvider>
|
|
581
|
+
);
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
</Tab>
|
|
585
|
+
<Tab label="Solid" value="solid">
|
|
586
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
587
|
+
import { IntlayerProvider } from "solid-intlayer";
|
|
588
|
+
|
|
589
|
+
export const App = (props) => (
|
|
590
|
+
<IntlayerProvider locale={props.locale} variant={props.schoolType}>
|
|
591
|
+
<Hero />
|
|
592
|
+
</IntlayerProvider>
|
|
593
|
+
);
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
</Tab>
|
|
597
|
+
<Tab label="Angular" value="angular">
|
|
598
|
+
```typescript fileName="app.config.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
599
|
+
import { ApplicationConfig } from "@angular/core";
|
|
600
|
+
import { provideIntlayer } from "angular-intlayer";
|
|
601
|
+
|
|
602
|
+
export const appConfig: ApplicationConfig = {
|
|
603
|
+
providers: [provideIntlayer("en", true, schoolType)],
|
|
604
|
+
};
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
</Tab>
|
|
608
|
+
<Tab label="Vanilla JS" value="vanilla">
|
|
609
|
+
```javascript fileName="main.js"
|
|
610
|
+
import { installIntlayer } from "vanilla-intlayer";
|
|
611
|
+
|
|
612
|
+
installIntlayer({ locale: "en", variant: schoolType });
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
</Tab>
|
|
616
|
+
</Tabs>
|
|
617
|
+
|
|
618
|
+
이제 프로바이더 아래의 모든 사전 읽기가 해당 변형으로 해석되며, 호출 지점의 셀렉터가 항상 우선합니다:
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
useIntlayer("hero-banner");
|
|
622
|
+
// → 프로바이더의 변형
|
|
623
|
+
|
|
624
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
625
|
+
// → "summer" — 프로바이더 변형을 대체하며, 확장하지 않습니다
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### 형태
|
|
629
|
+
|
|
630
|
+
`variant` 프로퍼티는 세 가지 형태를 받습니다:
|
|
631
|
+
|
|
632
|
+
| 형태 | 의미 |
|
|
633
|
+
| --------------------------------------------------------- | ---------------------------------------- |
|
|
634
|
+
| `variant="school1"` | 모든 키에 적용되는 하나의 이름 있는 변형 |
|
|
635
|
+
| `variant={["school1", "default"]}` | 순서가 있는 우선순위 체인 |
|
|
636
|
+
| `variant={{ "hero-banner": "school1", default: "base" }}` | 사전 키별 변형 |
|
|
637
|
+
|
|
638
|
+
#### 우선순위 체인
|
|
639
|
+
|
|
640
|
+
체인은 각 키가 선언한 항목에 대해 왼쪽에서 오른쪽으로 시도하며, 가장 먼저 선언된 것이 선택됩니다. 아무것도 선언되어 있지 않으면 단일 값일 때와 똑같이 암묵적인 기본 항목이 사용됩니다.
|
|
641
|
+
|
|
642
|
+
```tsx
|
|
643
|
+
<IntlayerProvider variant={["school1", "school2"]} />
|
|
644
|
+
// `hero-banner`는 `school1` 항목을 선언하지 않지만 `school2`를 선언함 → "school2"
|
|
645
|
+
// 둘 다 선언하지 않은 키 → 기본 항목
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
따라서 `["black_friday", "summer"]`는 «이 키에 black friday가 있으면 그것, 없으면 summer, 그것도 없으면 기본값»으로 읽힙니다. 체인은 호출 지점에서도 사용할 수 있습니다:
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
useIntlayer("hero-banner", { variant: ["black_friday", "summer"] });
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
> 이는 콘텐츠 파일의 `variant` **필드**가 받는 배열과 정반대라는 점에 유의하세요. 그쪽에서는 배열이 요소마다 항목을 하나씩 *선언*하지만, 여기서는 우선순위 순서대로 그것들을 *소비*합니다.
|
|
655
|
+
|
|
656
|
+
#### 키별 맵
|
|
657
|
+
|
|
658
|
+
각 사전 키를 개별적으로 지정합니다. 예약된 `default` 항목이 나열되지 않은 모든 키를 처리합니다:
|
|
659
|
+
|
|
660
|
+
```tsx
|
|
661
|
+
<IntlayerProvider
|
|
662
|
+
variant={{
|
|
663
|
+
"hero-banner": "school1",
|
|
664
|
+
product: ["school1", "default"],
|
|
665
|
+
default: "base",
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
> 프로바이더에서 일반 객체는 **항상** 키별 맵으로 읽히며, 객체 변형으로는 해석되지 않습니다 — 둘은 구조적으로 동일하기 때문입니다. 객체 변형을 전역으로 지정하려면 항목 아래에 중첩하세요: `variant={{ default: { id: "prod_abc" } }}`.
|
|
671
|
+
|
|
672
|
+
맵의 키는 선언된 사전 키와 대조되므로, 오타 — 또는 `variant={{ id: "prod_abc" }}`처럼 객체 변형을 직접 작성한 경우 — 는 컴파일 오류가 됩니다.
|
|
673
|
+
|
|
467
674
|
## 로딩 모드
|
|
468
675
|
|
|
469
676
|
객체 변형은 종종 지연 로드됩니다. 이를 제어하려면 사전에 `importMode`를 설정하세요:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-08-04
|
|
4
4
|
title: Warianty
|
|
5
5
|
description: Użyj pola metadanych variant w plikach treści Intlayer, aby zadeklarować nazwane lub strukturalne alternatywy treści — testy A/B, banery sezonowe, teksty z feature flag, rekordy CMS, treść zależną od użytkownika — i przełączać się między nimi w czasie wykonywania bez zmian w kodzie.
|
|
6
6
|
keywords:
|
|
@@ -22,7 +22,13 @@ history:
|
|
|
22
22
|
changes: "Wydanie funkcji wariantów"
|
|
23
23
|
- version: 9.1.0
|
|
24
24
|
date: 2026-06-26
|
|
25
|
-
changes: "`variant`
|
|
25
|
+
changes: "`variant` akceptuje teraz ciąg znaków lub obiekt — dawne rekordy `meta` / dynamiczne są deklarowane jako warianty obiektowe"
|
|
26
|
+
- version: 9.1.1
|
|
27
|
+
date: 2026-07-31
|
|
28
|
+
changes: "Wariant deklaruje tylko klucze, które nadpisuje; niezadeklarowane warianty powracają do domyślnego wpisu"
|
|
29
|
+
- version: 9.1.2
|
|
30
|
+
date: 2026-08-04
|
|
31
|
+
changes: "Dostawcy przyjmują otaczający prop `variant`; selektory przyjmują uporządkowany łańcuch preferencji"
|
|
26
32
|
author: aymericzip
|
|
27
33
|
---
|
|
28
34
|
|
|
@@ -77,6 +83,37 @@ const dictionary = {
|
|
|
77
83
|
export default dictionary;
|
|
78
84
|
```
|
|
79
85
|
|
|
86
|
+
### Warianty częściowe
|
|
87
|
+
|
|
88
|
+
Wariant deklaruje **tylko klucze, które nadpisuje**; reszta jest dziedziczona z wpisu domyślnego.
|
|
89
|
+
|
|
90
|
+
```ts fileName="hero-banner.summer.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
91
|
+
import { t, type Dictionary } from "intlayer";
|
|
92
|
+
|
|
93
|
+
const dictionary = {
|
|
94
|
+
key: "hero-banner",
|
|
95
|
+
variant: "summer",
|
|
96
|
+
content: {
|
|
97
|
+
headline: t({
|
|
98
|
+
en: "Build faster all summer",
|
|
99
|
+
fr: "Développez plus vite tout l'été",
|
|
100
|
+
}),
|
|
101
|
+
},
|
|
102
|
+
} satisfies Dictionary;
|
|
103
|
+
|
|
104
|
+
export default dictionary;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
109
|
+
// → { headline: "Développez plus vite tout l'été", cta: "Commencer" } — `cta` odziedziczone
|
|
110
|
+
|
|
111
|
+
useIntlayer("hero-banner", { variant: "never-declared" });
|
|
112
|
+
// → wpis domyślny
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Dlatego dodajesz plik wariantu tylko tam, gdzie brzmienie faktycznie się różni. Klucz jest rozwiązywany na `null` tylko wtedy, gdy deklaruje warianty, ale nie ma domyślnego wpisu.
|
|
116
|
+
|
|
80
117
|
### Korzystanie z wariantów nazwanych
|
|
81
118
|
|
|
82
119
|
#### Wariant domyślny
|
|
@@ -464,6 +501,176 @@ const content = useIntlayer("product", {
|
|
|
464
501
|
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
465
502
|
```
|
|
466
503
|
|
|
504
|
+
## Wariant otaczający
|
|
505
|
+
|
|
506
|
+
Niektóre wymiary wariantu są stałe przez całą sesję — najemca, typ szkoły, poziom planu. Są rozstrzygane raz i żaden komponent nie powinien przekazywać ich ręcznie.
|
|
507
|
+
|
|
508
|
+
> Nie opakowuj `useIntlayer` we własny hook, aby je wstrzyknąć. Optymalizacja na etapie budowania przepisuje wyłącznie dosłowne wywołanie `useIntlayer("key")` zaimportowane z pakietu frameworka, więc nic za opakowaniem nie trafi do bundla.
|
|
509
|
+
|
|
510
|
+
Zamiast tego zadeklaruj wariant raz na dostawcy, dokładnie jak `locale`:
|
|
511
|
+
|
|
512
|
+
<Tabs group="framework">
|
|
513
|
+
<Tab label="React" value="react">
|
|
514
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
515
|
+
import { IntlayerProvider } from "react-intlayer";
|
|
516
|
+
|
|
517
|
+
export const App = ({ locale, schoolType }) => (
|
|
518
|
+
<IntlayerProvider locale={locale} variant={schoolType}>
|
|
519
|
+
<Hero />
|
|
520
|
+
</IntlayerProvider>
|
|
521
|
+
);
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
</Tab>
|
|
525
|
+
<Tab label="Next.js" value="nextjs">
|
|
526
|
+
```tsx fileName="layout.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
527
|
+
import { IntlayerServerProvider } from "next-intlayer/server";
|
|
528
|
+
import { IntlayerClientProvider } from "next-intlayer";
|
|
529
|
+
|
|
530
|
+
export default async function Layout({ children, params }) {
|
|
531
|
+
const { locale } = await params;
|
|
532
|
+
const schoolType = await getSchoolType();
|
|
533
|
+
|
|
534
|
+
return (
|
|
535
|
+
<IntlayerServerProvider locale={locale} variant={schoolType}>
|
|
536
|
+
<IntlayerClientProvider locale={locale} variant={schoolType}>
|
|
537
|
+
{children}
|
|
538
|
+
</IntlayerClientProvider>
|
|
539
|
+
</IntlayerServerProvider>
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
</Tab>
|
|
545
|
+
<Tab label="Vue" value="vue">
|
|
546
|
+
```ts fileName="main.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
547
|
+
import { createApp } from "vue";
|
|
548
|
+
import { installIntlayer } from "vue-intlayer";
|
|
549
|
+
import App from "./App.vue";
|
|
550
|
+
|
|
551
|
+
const app = createApp(App);
|
|
552
|
+
|
|
553
|
+
installIntlayer(app, { locale: "en", variant: schoolType });
|
|
554
|
+
|
|
555
|
+
app.mount("#app");
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
</Tab>
|
|
559
|
+
<Tab label="Svelte" value="svelte">
|
|
560
|
+
```svelte fileName="+layout.svelte" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
561
|
+
<script lang="ts">
|
|
562
|
+
import { setupIntlayer } from "svelte-intlayer";
|
|
563
|
+
|
|
564
|
+
export let schoolType: string;
|
|
565
|
+
|
|
566
|
+
setupIntlayer("en", schoolType);
|
|
567
|
+
</script>
|
|
568
|
+
|
|
569
|
+
<slot />
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
</Tab>
|
|
573
|
+
<Tab label="Preact" value="preact">
|
|
574
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
575
|
+
import { IntlayerProvider } from "preact-intlayer";
|
|
576
|
+
|
|
577
|
+
export const App = ({ locale, schoolType }) => (
|
|
578
|
+
<IntlayerProvider locale={locale} variant={schoolType}>
|
|
579
|
+
<Hero />
|
|
580
|
+
</IntlayerProvider>
|
|
581
|
+
);
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
</Tab>
|
|
585
|
+
<Tab label="Solid" value="solid">
|
|
586
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
587
|
+
import { IntlayerProvider } from "solid-intlayer";
|
|
588
|
+
|
|
589
|
+
export const App = (props) => (
|
|
590
|
+
<IntlayerProvider locale={props.locale} variant={props.schoolType}>
|
|
591
|
+
<Hero />
|
|
592
|
+
</IntlayerProvider>
|
|
593
|
+
);
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
</Tab>
|
|
597
|
+
<Tab label="Angular" value="angular">
|
|
598
|
+
```typescript fileName="app.config.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
599
|
+
import { ApplicationConfig } from "@angular/core";
|
|
600
|
+
import { provideIntlayer } from "angular-intlayer";
|
|
601
|
+
|
|
602
|
+
export const appConfig: ApplicationConfig = {
|
|
603
|
+
providers: [provideIntlayer("en", true, schoolType)],
|
|
604
|
+
};
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
</Tab>
|
|
608
|
+
<Tab label="Vanilla JS" value="vanilla">
|
|
609
|
+
```javascript fileName="main.js"
|
|
610
|
+
import { installIntlayer } from "vanilla-intlayer";
|
|
611
|
+
|
|
612
|
+
installIntlayer({ locale: "en", variant: schoolType });
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
</Tab>
|
|
616
|
+
</Tabs>
|
|
617
|
+
|
|
618
|
+
Każdy odczyt słownika poniżej dostawcy rozstrzyga się teraz względem tego wariantu, a selektor w miejscu wywołania zawsze wygrywa:
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
useIntlayer("hero-banner");
|
|
622
|
+
// → wariant dostawcy
|
|
623
|
+
|
|
624
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
625
|
+
// → "summer" — zastępuje wariant dostawcy, nie rozszerza go
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Formy
|
|
629
|
+
|
|
630
|
+
Prop `variant` przyjmuje trzy formy:
|
|
631
|
+
|
|
632
|
+
| Forma | Znaczenie |
|
|
633
|
+
| --------------------------------------------------------- | ---------------------------------------- |
|
|
634
|
+
| `variant="school1"` | jeden nazwany wariant dla każdego klucza |
|
|
635
|
+
| `variant={["school1", "default"]}` | uporządkowany łańcuch preferencji |
|
|
636
|
+
| `variant={{ "hero-banner": "school1", default: "base" }}` | jeden wariant na klucz słownika |
|
|
637
|
+
|
|
638
|
+
#### Łańcuch preferencji
|
|
639
|
+
|
|
640
|
+
Łańcuch jest przechodzony od lewej do prawej względem wpisów deklarowanych przez każdy klucz i wygrywa pierwszy zadeklarowany. Gdy żaden nie jest zadeklarowany, używany jest niejawny wpis domyślny — dokładnie tak jak dla pojedynczej wartości.
|
|
641
|
+
|
|
642
|
+
```tsx
|
|
643
|
+
<IntlayerProvider variant={["school1", "school2"]} />
|
|
644
|
+
// `hero-banner` nie deklaruje wpisu `school1`, ale deklaruje `school2` → "school2"
|
|
645
|
+
// klucz, który nie deklaruje żadnego z nich → wpis domyślny
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Zatem `["black_friday", "summer"]` czyta się jako „black friday, jeśli ten klucz go ma, w przeciwnym razie summer, w przeciwnym razie domyślny”. Łańcuchy są akceptowane także w miejscu wywołania:
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
useIntlayer("hero-banner", { variant: ["black_friday", "summer"] });
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
> Zauważ, że jest to lustrzane odbicie tablicy przyjmowanej przez **pole** `variant` pliku treści: tam tablica _deklaruje_ jeden wpis na element, tutaj _konsumuje_ je w kolejności priorytetu.
|
|
655
|
+
|
|
656
|
+
#### Mapa według klucza
|
|
657
|
+
|
|
658
|
+
Adresuj każdy klucz słownika osobno. Zarezerwowany wpis `default` obejmuje wszystkie klucze niewymienione na liście:
|
|
659
|
+
|
|
660
|
+
```tsx
|
|
661
|
+
<IntlayerProvider
|
|
662
|
+
variant={{
|
|
663
|
+
"hero-banner": "school1",
|
|
664
|
+
product: ["school1", "default"],
|
|
665
|
+
default: "base",
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
> Na dostawcy zwykły obiekt jest **zawsze** odczytywany jako mapa według klucza, nigdy jako wariant obiektowy — oba są strukturalnie identyczne. Aby ustalić wariant obiektowy globalnie, zagnieźdź go pod wpisem: `variant={{ default: { id: "prod_abc" } }}`.
|
|
671
|
+
|
|
672
|
+
Ponieważ klucze mapy są sprawdzane względem zadeklarowanych kluczy słowników, literówka — lub wariant obiektowy zapisany wprost, taki jak `variant={{ id: "prod_abc" }}` — jest błędem kompilacji.
|
|
673
|
+
|
|
467
674
|
## Tryb ładowania
|
|
468
675
|
|
|
469
676
|
Warianty obiektowe są często ładowane leniwie. Ustaw `importMode` w słowniku, aby to kontrolować:
|