Skip to content

Latest commit

 

History

History
1484 lines (1102 loc) · 16.7 KB

File metadata and controls

1484 lines (1102 loc) · 16.7 KB

@angular-eslint/template/i18n

Ensures following best practices for i18n. Checks for missing i18n attributes on elements and attributes containing texts. Can also check for texts without i18n attribute, elements that do not use custom ID (@@) feature and duplicate custom IDs


Rule Options

The rule accepts an options object with the following properties:

interface Options {
  boundTextAllowedPattern?: string;
  /**
   * Default: `true`
   */
  checkAttributes?: boolean;
  /**
   * Default: `true`
   */
  checkDuplicateId?: boolean;
  /**
   * Default: `true`
   */
  checkId?: boolean;
  /**
   * Default: `true`
   */
  checkText?: boolean;
  /**
   * Default: `["autocomplete","charset","class","color","colspan","dir","fill","for","formArrayName","formControlName","formGroupName","height","href","id","lang","list","name","ngClass","ngProjectAs","role","routerLink","routerLinkActive","src","stroke","stroke-width","style","svgIcon","tabindex","target","type","value","viewBox","width","xmlns"]`
   */
  ignoreAttributes?: string[];
  ignoreTags?: string[];
  requireDescription?: boolean;
}

Usage Examples

The following examples are generated automatically from the actual unit tests within the plugin, so you can be assured that their behavior is accurate based on the current commit.


❌ - Toggle examples of incorrect code for this rule

Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

❌ Invalid Code

<div tooltip="This requires translation"></div>
     ~~~~~~~



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "ignoreTags": []
      }
    ]
  }
}

❌ Invalid Code

<div>
  <span>test{{data_from_backend}}</span>
        ~~~~~~~~~~~~~~~~~~~~~~~~~
</div>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkAttributes": false
      }
    ]
  }
}

❌ Invalid Code

{ value, plural, =0 {<div>No elements</div>} =1 {111} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkId": false
      }
    ]
  }
}

❌ Invalid Code

<div>
  <ng-container>Some text&nbsp;t@ tr1nslate</ng-container>
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~
</div>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

❌ Invalid Code

<p>Lorem ipsum <em i18n="@@dolor">dolor</em> sit amet.</p>
   ~~~~~~~~~~~~                              ~~~~~~~~~



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

❌ Invalid Code

<div tooltip="This requires translation" i18n-tooltip></div>
     ~~~~~~~



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "ignoreAttributes": [
          "span[label]"
        ]
      }
    ]
  }
}

❌ Invalid Code

<div>
  <span i18n label="label is ignored in 'ignoreAttributes'">
  ~
    Missing custom ID
  </span>
        ~
</div>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

❌ Invalid Code

<div
  i18n-tooltip="@@custom-id"
  tooltip="This requires translation"
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  label="Custom label"
  ~~~~~~~~~~~~~~~~~~~~
  i18n-label="@@custom-id"
></div>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "ignoreTags": []
      }
    ]
  }
}

❌ Invalid Code

<h3 i18n="@@myId">Hello</h3>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<p i18n="@@myId">Good bye</p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

❌ Invalid Code

<div i18n-tooltip="@@custom-id" tooltip="This requires translation">
                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  <span i18n="@@custom-id">Some text to translate</span>
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</div>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

❌ Invalid Code

<div i18n-tooltip="@@custom-id" tooltip="This requires translation">
                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  <span i18n="@@custom-id">Some text to translate</span>
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</div>
<div i18n-label="@@custom-id" label="A label"></div>
                              ~~~~~~~~~~~~~~~



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "ignoreAttributes": [
          "span[label]"
        ]
      }
    ]
  }
}

❌ Invalid Code

<div
  tooltip="This requires translation"
  ~~~~~~~
  i18n-placeholder
  placeholder="More translation, please"
  ~~~~~~~~~~~
  class="red"
>
  <div
    *ngIf="true"
    width="100px"
    label="Templates need translation too."
    ~~~~~
  >
    <span i18n label="label is ignored in 'ignoreAttributes'">
    ~
      Missing custom ID
    </span>
          ~
  </div>
</div>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkId": false,
        "requireDescription": true
      }
    ]
  }
}

❌ Invalid Code

<h1 i18n>Hello</h1>
~~~~~~~~~~~~~~~~~~~



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "requireDescription": true
      }
    ]
  }
}

❌ Invalid Code

<h1 i18n="@@custom-id">Hello</h1>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkId": false,
        "requireDescription": true
      }
    ]
  }
}

❌ Invalid Code

<span i18n="A balloon that displays data" data-balloon="Translated title" i18n-data-balloon>
                                          ~~~~~~~~~~~~
  Hello
</span>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "requireDescription": true
      }
    ]
  }
}

❌ Invalid Code

<h1 i18n="Title of the sample@@custom-id" i18n-title="@@title-id" title="Translated title">
                                                                  ~~~~~
  Hello
</h1>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "requireDescription": true,
        "checkId": false
      }
    ]
  }
}

❌ Invalid Code

<img [src]="logo" i18n-title title="App Logo" i18n-alt="App logo" alt="App Logo"/>
                             ~~~~~



✅ - Toggle examples of correct code for this rule

Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<div>
  <span i18n="@@custom-id">Some text to translate</span>
</div>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<div>
  <span class="red" i18n="@@custom-id">
    Some text to translate
  </span>
</div>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkId": false,
        "ignoreAttributes": [
          "tooltip"
        ]
      }
    ]
  }
}

✅ Valid Code

<div tooltip="This tooltip property is ignored">
  <span i18n>Some text to translate</span>
</div>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkText": false
      }
    ]
  }
}

✅ Valid Code

<div i18n-tooltip="@@tooltip.label" tooltip="This tooltip property is ignored">
  <span>Some text to translate</span>
</div>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "ignoreTags": [
          "mat-icon"
        ]
      }
    ]
  }
}

✅ Valid Code

<div i18n-tooltip="@@tooltip.label" tooltip="This tooltip property is ignored">
  <mat-icon>valid</mat-icon>
</div>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<div>-{{data_from_backend}}</div>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<div>1{{data_from_backend}}</div>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<div>-1{{data_from_backend}}</div>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "boundTextAllowedPattern": "My company untranslatable name"
      }
    ]
  }
}

✅ Valid Code

<div>
  My company untranslatable name{{data_from_backend}}
</div>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "ignoreTags": [
          "my-component"
        ]
      }
    ]
  }
}

✅ Valid Code

<my-component size="s"></my-component>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkAttributes": false,
        "checkId": true,
        "checkText": false
      }
    ]
  }
}

✅ Valid Code

<p i18n="@@customId">Lorem ipsum <em>dolor</em> sit amet.</p>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<a
  mat-button
  ngClass="class"
  routerLink="exclusions"
  i18n="@@keywording.tools.exclusions"
>
  Exclusions
</a>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkId": true,
        "checkText": true
      }
    ]
  }
}

✅ Valid Code

<a
  mat-button
  routerLink="exclusions"
  i18n="@@keywording.tools.exclusions"
>
  Exclusions
</a>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<ng-template #errorMessage>
  {{ error.title }}
</ng-template>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<ng-container i18n="@@description">
  { value, plural, =0 {<div>No elements</div>} =1 {111} }
</ng-container>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkId": false
      }
    ]
  }
}

✅ Valid Code

<span i18n>
  The author is {gender, select, male {male} female {female} other {other}}
</span>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<mat-option *ngFor="let mode of modes" [value]="mode.id" i18n="@@option">
  {mode.name, select, mode {mode} other { {{mode.name}} } }
</mat-option>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<ng-container ngProjectAs="top">&ngsp;</ng-container>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkText": false
      }
    ]
  }
}

✅ Valid Code

<p [ngPlural]="components">
  <ng-template ngPluralCase="1">1 component removed</ng-template>
  <ng-template ngPluralCase="1">{{components}} components removed</ng-template>
</p>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkAttributes": false,
        "checkId": false,
        "checkText": false
      }
    ]
  }
}

✅ Valid Code

<div tooltip="This requires translation"></div>
<div>
  <span i18n label="valid with i18n">Some text to translate</span>
</div>
<div tooltip="This requires translation" i18n-tooltip></div>
<div>
  <ng-container>Some text&nbsp;t@ tr1nslate</ng-container>
</div>
<div>
  <span>-{{data_from_backend}}</span>
</div>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<div label="1">
  <div matBadge="&#8288;">5</div>
</div>



Default Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error"
    ]
  }
}

✅ Valid Code

<div ariaselected="0"></div>
<div>+</div>
<span>&nbsp;</span>
<span>123</span>
<ng-content select=".content-area"></ng-content>
<ul i18n="@@list">
  <li>ItemA</li>
  <li>ItemB</li>
  <li>ItemC</li>
</ul>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkId": false,
        "requireDescription": true
      }
    ]
  }
}

✅ Valid Code

<h1 i18n="An introduction header for this sample">Hello i18n!</h1>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "requireDescription": true
      }
    ]
  }
}

✅ Valid Code

<h1 i18n="An introduction header for this sample@@custom-id">Hello i18n!</h1>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkId": false,
        "requireDescription": true
      }
    ]
  }
}

✅ Valid Code

<h1 i18n="An introduction header for this sample" i18n-title="Title of the sample" title="Translated title">
  Hello i18n!
</h1>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "requireDescription": true
      }
    ]
  }
}

✅ Valid Code

<h1 i18n="An introduction header for this sample@@custom-id" i18n-title="Title of the sample@@title-id" title="Translated title">
  Hello i18n!
</h1>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkId": false,
        "requireDescription": true
      }
    ]
  }
}

✅ Valid Code

<img
  [src]="logo"
  i18n-title="Logo for the app"
  title="App Logo"
  i18n-alt="Translated alt logo"
  alt="Alternate logo"
/>



Custom Config

{
  "rules": {
    "@angular-eslint/template/i18n": [
      "error",
      {
        "checkDuplicateId": false
      }
    ]
  }
}

✅ Valid Code

<span i18n="@@custom-id">Some text to translate</span>
<span i18n="@@custom-id">Some text to translate</span>