ノード型を組み合わせることはできますか?(例:1文の中に複数の複数形がある場合)

    はい、Intlayerのノード型は組み合わせることができます。例えば、plural()の中に別のplural()をネストしたり、plural()とinsert()を組み合わせたりすることが可能です。

    1つの文の中に2つの独立した複数形変数を表現したい場合(例:「1つのファイルが2つのフォルダーにあります」 vs 「3つのファイルが1つのフォルダーにあります」)、主に2つのアプローチがあります:

    1. 個別のplural()キーを持つinsert()を使用する(推奨):クリーンで保守性が高く、言語ごとの正しい語順を維持できます。
    2. plural()の中にplural()をネストする(直接的な合成):構文としては有効ですが、複雑な複数形ルールを持つ言語では分岐の組み合わせが爆発的に増加する可能性があります。

    insert()とplural()を組み合わせる

    最も柔軟でイディオマティックなパターンは、複数化する対象ごとに個別のpluralキーを宣言し、それらをinsert()テンプレートで組み合わせることです。

    1. コンテンツを宣言する

    src/fileSummary.content.ts
    import { insert, plural, t, type Dictionary } from "intlayer";
    
    const fileSummaryContent = {
      key: "file_summary",
      content: {
        // 挿入テンプレートにより言語ごとの要素の並び順を定義
        summary: t({
          ja: insert("{{folders}}の中に{{files}}"), // 日本語独自の語順
          en: insert("{{files}} in {{folders}}"),
          fr: insert("{{files}} dans {{folders}}"),
        }),
        files: t({
          ja: plural({
            other: "{{count}} 個のファイル",
          }),
          en: plural({
            one: "{{count}} file",
            other: "{{count}} files",
          }),
          fr: plural({
            one: "{{count}} fichier",
            other: "{{count}} fichiers",
          }),
        }),
        folders: t({
          ja: plural({
            other: "{{count}} 個のフォルダー",
          }),
          en: plural({
            one: "{{count}} folder",
            other: "{{count}} folders",
          }),
          fr: plural({
            one: "{{count}} dossier",
            other: "{{count}} dossiers",
          }),
        }),
      },
    } satisfies Dictionary;
    
    export default fileSummaryContent;
    

    2. コンポーネントで使用する

    src/components/FileSummary.tsx
    import type { FC } from "react";
    import { useIntlayer } from "react-intlayer";
    
    export const FileSummary: FC<{ fileCount: number; folderCount: number }> = ({
      fileCount,
      folderCount,
    }) => {
      const { summary, files, folders } = useIntlayer("file_summary");
    
      return (
        <p>
          {summary({
            files: files(fileCount),
            folders: folders(folderCount),
          })}
        </p>
      );
    };
    
    src/components/FileSummary.vue
    <script setup lang="ts">
    import { useIntlayer } from "vue-intlayer";
    
    defineProps<{
      fileCount: number;
      folderCount: number;
    }>();
    
    const { summary, files, folders } = useIntlayer("file_summary");
    </script>
    
    <template>
      <p>
        {{
          summary({
            files: files(fileCount),
            folders: folders(folderCount),
          })
        }}
      </p>
    </template>
    
    src/components/FileSummary.svelte
    <script lang="ts">
      import { useIntlayer } from "svelte-intlayer";
    
      export let fileCount: number;
      export let folderCount: number;
    
      const content = useIntlayer("file_summary");
    </script>
    
    <p>
      {$content.summary({
        files: $content.files(fileCount),
        folders: $content.folders(folderCount),
      })}
    </p>
    

    このアプローチが推奨される理由

    • 文構造と語順:言語によって形容詞、数値、目的語の並び順が異なります(例えば、日本語やドイツ語ではファイルとフォルダーの語順が逆になる場合があります)。insert()テンプレートを使用することで、複数形ルールを壊すことなく、翻訳者が語順を完全にコントロールできます。
    • 組み合わせ爆発の防止:言語Aに2つの複数形があり(英語:one, other)、言語Bに4つの複数形がある場合(ロシア語:one, few, many, other)、複数形をネストするとロシア語では $4 \times 4 = 16$ 通りの分岐が必要になります。キーを分割すれば、$4 + 4 = 8$ 通りの宣言で済みます。
    • 再利用性:filesやfoldersの複数形定義をUIの他の場所で再利用できます。