How does one utilize the i18n template for eslint in Angular?
Asked Answered
G

2

1

I would like to be able to utilize the eslint angular template that checks for i18n tags as shown here https://github.com/angular-eslint/angular-eslint/blob/master/packages/eslint-plugin-template/src/rules/i18n.ts and listed here https://github.com/angular-eslint/angular-eslint#readme, but there isn't really any helpful instruction on how to activate it or what needs to be put in the config to make it work. I just need to know how to turn it "on" to start checking. Any help would be appreciated.

Update:

Here is an example of what I am trying (and failing) at doing:

In .eslintrc.json, I am trying to add @angular-eslint/template/i18n:

{
  "root": true,
  "ignorePatterns": [
    "projects/**/*"
  ],
  "overrides": [
    {
      "files": [
        "*.ts"
      ],
      "parserOptions": {
        "project": [
          "tsconfig.json"        ],
        "createDefaultProgram": true,
        "tsconfigRootDir": "",
        "ecmaVersion": 2017
      },
        "env": {
            "es6": true
        },
      "extends": [
        "plugin:@angular-eslint/ng-cli-compat",
        "plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
        "plugin:@angular-eslint/template/process-inline-templates"
      ],
      "rules": {
        "arrow-body-style": 0,
        "@typescript-eslint/naming-convention": [
            "error",
            {
                "selector": "enumMember",
                "format": [
                    "camelCase",
                    "UPPER_CASE"
                ]
            }
        ],
        "@typescript-eslint/consistent-type-definitions": "error",
        "@typescript-eslint/dot-notation": "off",
        "@typescript-eslint/explicit-member-accessibility": [
          "off",
          {
            "accessibility": "explicit"
          }
        ],
        "@typescript-eslint/no-non-null-assertion": "off",
        "brace-style": [
          "error",
          "1tbs"
        ],
        // note you must disable the base rule as it can report incorrect errors
        "no-shadow": "off",
        "@typescript-eslint/no-shadow": [
            "error"
        ]
      }
    },
    {
      "files": [
        "*.html"
      ],
      "extends": [
        "plugin:@angular-eslint/template/recommended"
      ],
      "rules": {
        "@angular-eslint/template/i18n": [
            "warn",
            { "items": ["check-id", "check-text"] }
        ]
      }
    }
  ]
}

When I do this, I get the error:

An unhandled exception occurred: .eslintrc.json#overrides[1]:
        Configuration for rule "@angular-eslint/template/i18n" is invalid:
        Value {"items":["check-id","check-text"],"checkId":true,"checkText":true,"checkAttributes":true,"ignoreAttributes":["charset","class","color","colspan","fill","formControlName","height","href","id","lang","src","stroke","stroke-width","style","svgIcon","tabindex","target","type","viewBox","width","xmlns"]} should NOT have additional properties.

If I change the name from @angular-eslint/template/i18n to template-i18n, it runs and scans all of my .html files, but returns an error for each one that says 1:1 error Definition for rule 'template-i18n' was not found template-i18n

Godbey answered 13/5, 2021 at 18:28 Comment(0)
L
1

Hello I updated per maplion's comments

Assuming its the i18n build and try to help you setup the build for localization i.e. i18n. Try these two options, the first is to configure your build with the i18n build. Second, is use another lib i18n-Lint which is easier IMHO. Short answer this enables the template you want to use "template-i18n": [true, "check-id", "check-text"]


First setup you schema on what you want to check, i.e. just id, strings or both in .eslintrc.json:

 // per MapLions feedback, i updated the full section, mine is different
 { 
 //  1 - tell it which files you want
  "files": [
    "*.html"
  ],
  // 2 - include this plugin
  "extends": [
    "plugin:@angular-eslint/template/recommended"
  ],
  "rules": {
    "@angular-eslint/template/i18n": [
        "warn",
        { // 3 - setup your rules here
            "checkId": true,
            "checkText": true,
            "checkAttributes": true
        }
    ]
  }
 }
  ...

Then enable it like so.

"template-i18n": [true, "check-id", "check-text"]
  • check-id Makes sure i18n attributes have ID specified
  • check-text Makes sure there are no elements with text content but no i18n attribute

in your rules setup up "@angular-eslint/template/i18n": "warn", then in your build you can setup the extract or tests

  {
    "name": myapp...",
    "version": "..",
    "angular-cli": {},
    "scripts": {
        "------------- your app -----------": "",
        "start": "ng serve --configuration=test --proxy-config proxy.conf.json --live-reload false",
./node_modules/@angular/cli/bin/ng build --configuration=prod-en-us",
        "build:prod:fr-ca": "node --max_old_space_size=10240 ./node_modules/@angular/cli/bin/ng build --configuration=prod-fr-ca",
        "build:prod:multilang": "npm run build:prod:en-us & npm run build:prod:fr-ca",
        "build:debug": "node --max_old_space_size=10240 ./node_modules/@angular/cli/bin/ng build --configuration=prod-en-us --verbose",

        
        "extract-i18n-html": "ng xi18n --output-path locale",
        "extract-i18n-ts": "ngx-extractor --input src/**/*.ts --format=xlf --out-file=src/locale/messages.xlf",
        "extract-i18n": "npm run extract-i18n-html & npm run extract-i18n-ts",
        "merge-i18n": "xliffmerge --profile xliffmerge.json -v",
        "i18n": "./node_modules/.bin/ng-xi18n --i18nFormat=xlf",
        "lint": "tslint \"src/**/*.ts",

        ....
        "------------- setup build for yourComponents -----------": "",
        "start:...",
        "build:...",
        "build:myComponents:prod:multilang": "npm run build:myComponents:prod:en-us & npm run build:myComponents:prod:fr-ca",
        "extract-i18n-html:myComponents": "ng xi18n myComponents --output-path src/locale",
        "extract-i18n-ts:myComponents": "ngx-extractor --input projects/myComponents/**/*.ts --format=xlf --out-file=projects/myComponents/src/locale/messages.xlf",
        "extract-i18n:myComponents": "npm run extract-i18n-html:myComponents & npm run extract-i18n-ts:myComponents",
        "merge-i18n:myComponents": "xliffmerge --profile projects/myComponents/xliffmerge.json -v",

        ...
        "------------- your  tests -----------": "",
        "test": "ng test",
        ...
    },
    "private": true,
    "dependencies": {
        "@angular/animations": "7.0.2",
        ...
        "@ngx-translate/i18n-polyfill": "0.2.0",
        ...
    },
    "devDependencies": {
        "@angular-devkit/build-angular": "0.10.3",
        ...
        "ngx-i18nsupport": "0.16.2",
        ....
    }
}

Option 2: i18n-lint

Use https://www.npmjs.com/package/i18n-lint

i18n--lint for linting angular typescript internationalization or localization

CLI
Installing i18n-lint globally via npm gives you the i18n-lint binary.

        $ npm install -g jwarby/i18n-lint
        
        $ i18n-lint --help

Usage: i18n-lint [OPTIONS] <file ...>

  Options:

    -h, --help                              output usage information
    -V, --version                           output the version number
    -a, --attributes <attributes>           Comma-separated list of HTML attributes to lint (default: 'alt,title')
    -i, --ignore-tags <tags>                Comma-separated list of names of tags to ignore whilst linting (default: 'script,style')
    -t, --template-delimiters <delimiters>  Template delimiters used in source files.  For example, Mustache-like templating languages should use ''
    -r, --reporter <reporter>               Specify which reporter to output results with
    --exclude <exclusion patterns>          Comma-separated list of glob patterns to ignore,  e.g. "/test_subdir/,ignored.html"
    --color                                 Force colored output
    --no-color                              Disable colored output

  Use `man i18n-lint` for more information
API
i18n-lint can be used in other projects as a library. After installing, simply require the module.

        $ npm install --save jwarby/i18n-lint
        
        var i18nlint = require('i18n-lint');

// Lint a file
var errors = i18nlint('myfile.html', {
  // ... options ...
});

// Lint a string
var errors = i18nlint.scan('<div>Untranslated String!</div>', {
  // ...options...

You can then use it

CLI
After installing, you should be able to type i18n-lint into a terminal.
# Display version and exit
$ i18n-lint --version

# Lint myfile.html
$ i18n-lint myfile.html

# Lint all HTML files using a glob pattern
$ i18n-lint views/**/*.html

# Set options using --<option name> <optionValue>
$ i18n-lint --some-option "someValue" views/**/*.html
      
Letha answered 18/5, 2021 at 19:37 Comment(4)
This is very helpful, thank you. I didn't even realize i18n-lint existed. I am having difficulty getting it to crawl more than a single folder level, though. If I use i18n-lint **/*.html for example, I only get the dist/index.html and the src/index.html, when currently, no html in the project has any i18n. Is there a way to accomplish this without the code-scripting you mention (i.e. with the cli)?Godbey
I think I got it figured out; I just need to wrap the glob pattern in quotes and it seems to work correctly.Godbey
In regards to the first option, can you be a bit more explicit as to where each of those things goes? I'm still fuzzy on how you reference the template and what not. For example, it seems like @angular-eslint/template/i18n should be an "extends" plugin, but that doesn't seem to work.Godbey
thanks for the feedback, glad you got it resolved :)Letha
G
0

Mr. Transformer set me on the right track and I was able to get his Option 1 to work with the following in .eslintrc.json:

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

Here's the full .eslintrc.json for reference:

{
  "root": true,
  "ignorePatterns": [
    "projects/**/*"
  ],
  "overrides": [
    {
      "files": [
        "*.ts"
      ],
      "parserOptions": {
        "project": [
          "tsconfig.json"        ],
        "createDefaultProgram": true,
        "tsconfigRootDir": "",
        "ecmaVersion": 2017
      },
        "env": {
            "es6": true
        },
      "extends": [
        "plugin:@angular-eslint/ng-cli-compat",
        "plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
        "plugin:@angular-eslint/template/process-inline-templates"
      ],
      "rules": {
        "arrow-body-style": 0,
        "@typescript-eslint/naming-convention": [
            "error",
            {
                "selector": "enumMember",
                "format": [
                    "camelCase",
                    "UPPER_CASE"
                ]
            }
        ],
        "@typescript-eslint/consistent-type-definitions": "error",
        "@typescript-eslint/dot-notation": "off",
        "@typescript-eslint/explicit-member-accessibility": [
          "off",
          {
            "accessibility": "explicit"
          }
        ],
        "@typescript-eslint/no-non-null-assertion": "off",
        "brace-style": [
          "error",
          "1tbs"
        ],
        // note you must disable the base rule as it can report incorrect errors
        "no-shadow": "off",
        "@typescript-eslint/no-shadow": [
            "error"
        ]
      }
    },
    {
      "files": [
        "*.html"
      ],
      "extends": [
        "plugin:@angular-eslint/template/recommended"
      ],
      "rules": {
        "@angular-eslint/template/i18n": [
            "warn",
            { 
                "checkId": true,
                "checkText": true,
                "checkAttributes": true
            }
        ]
      }
    }
  ]
}

Godbey answered 21/5, 2021 at 4:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.