Skip to content

Commit 290c308

Browse files
Add 10 more template rules (45/127 total: 35%)
Co-authored-by: NullVoxPopuli <[email protected]>
1 parent b6e6cdb commit 290c308

30 files changed

Lines changed: 1003 additions & 0 deletions

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,19 +219,26 @@ rules in templates can be disabled with eslint directives with mustache or html
219219
| Name | Description | 💼 | 🔧 | 💡 |
220220
| :--------------------------------------------------------------------------------------------------------- | :----------------------------------------------------- | :-------------------------------------------------------------- | :- | :- |
221221
| [template-no-args-paths](docs/rules/template-no-args-paths.md) | disallow @args in paths | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
222+
| [template-no-bare-yield](docs/rules/template-no-bare-yield.md) | disallow yield without parameters | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
222223
| [template-no-debugger](docs/rules/template-no-debugger.md) | disallow {{debugger}} in templates | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
223224
| [template-no-duplicate-attributes](docs/rules/template-no-duplicate-attributes.md) | disallow duplicate attribute names in templates | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | 🔧 | |
224225
| [template-no-duplicate-id](docs/rules/template-no-duplicate-id.md) | disallow duplicate id attributes | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
225226
| [template-no-forbidden-elements](docs/rules/template-no-forbidden-elements.md) | disallow specific HTML elements | | | |
227+
| [template-no-html-comments](docs/rules/template-no-html-comments.md) | disallow HTML comments in templates | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
226228
| [template-no-inline-styles](docs/rules/template-no-inline-styles.md) | disallow inline styles | | | |
227229
| [template-no-input-block](docs/rules/template-no-input-block.md) | disallow block usage of {{input}} helper | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
228230
| [template-no-input-tagname](docs/rules/template-no-input-tagname.md) | disallow tagName attribute on {{input}} helper | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
229231
| [template-no-log](docs/rules/template-no-log.md) | disallow {{log}} in templates | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
232+
| [template-no-negated-condition](docs/rules/template-no-negated-condition.md) | disallow negated conditions in if/unless | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
230233
| [template-no-obsolete-elements](docs/rules/template-no-obsolete-elements.md) | disallow obsolete HTML elements | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
234+
| [template-no-outlet-outside-routes](docs/rules/template-no-outlet-outside-routes.md) | disallow {{outlet}} outside of route templates | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
231235
| [template-no-this-in-template-only-components](docs/rules/template-no-this-in-template-only-components.md) | disallow this in template-only components (gjs/gts) | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
232236
| [template-no-unnecessary-concat](docs/rules/template-no-unnecessary-concat.md) | disallow unnecessary string concatenation | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | 🔧 | |
237+
| [template-no-unnecessary-curly-in-string-attrs](docs/rules/template-no-unnecessary-curly-in-string-attrs.md) | disallow unnecessary curly braces in string attributes | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
233238
| [template-no-valueless-arguments](docs/rules/template-no-valueless-arguments.md) | disallow valueless named arguments | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
234239
| [template-require-button-type](docs/rules/template-require-button-type.md) | require button elements to have a valid type attribute | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | 🔧 | |
240+
| [template-require-each-key](docs/rules/template-require-each-key.md) | require key attribute in {{#each}} loops | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
241+
| [template-simple-unless](docs/rules/template-simple-unless.md) | require simple conditions in unless blocks | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
235242
| [template-splat-attributes-only](docs/rules/template-splat-attributes-only.md) | disallow ...spread other than ...attributes | ![gjs logo](/docs/svgs/gjs.svg) ![gts logo](/docs/svgs/gts.svg) | | |
236243

237244
### Components
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# template-no-bare-yield
2+
3+
✅ The `extends: 'plugin:ember/strict-gjs'` or `extends: 'plugin:ember/strict-gts'` property in a configuration file enables this rule.
4+
5+
Disallow `{{yield}}` without parameters outside of contextual components.
6+
7+
## Rule Details
8+
9+
This rule enforces passing parameters to `{{yield}}` to make component APIs more explicit.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
{{yield}}
18+
</template>
19+
```
20+
21+
Examples of **correct** code for this rule:
22+
23+
```gjs
24+
<template>
25+
{{yield this}}
26+
</template>
27+
28+
<template>
29+
{{yield @model}}
30+
</template>
31+
```
32+
33+
## Config
34+
35+
<!-- begin auto-generated rule meta list -->
36+
- strictGjs: true
37+
- strictGts: true
38+
<!-- end auto-generated rule meta list -->
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# template-no-html-comments
2+
3+
✅ The `extends: 'plugin:ember/strict-gjs'` or `extends: 'plugin:ember/strict-gts'` property in a configuration file enables this rule.
4+
5+
Disallow HTML comments in templates. HTML comments will be visible in the rendered output, which may expose sensitive information or clutter the DOM.
6+
7+
## Rule Details
8+
9+
This rule disallows HTML comments (`<!-- -->`) in templates and suggests using Glimmer comments (`{{! }}` or `{{!-- --}}`) instead.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
<!-- This is an HTML comment -->
18+
<div>Content</div>
19+
</template>
20+
```
21+
22+
Examples of **correct** code for this rule:
23+
24+
```gjs
25+
<template>
26+
{{! This is a Glimmer comment }}
27+
<div>Content</div>
28+
</template>
29+
30+
<template>
31+
{{!-- This is a block Glimmer comment --}}
32+
<div>Content</div>
33+
</template>
34+
```
35+
36+
## Config
37+
38+
<!-- begin auto-generated rule meta list -->
39+
- strictGjs: true
40+
- strictGts: true
41+
<!-- end auto-generated rule meta list -->
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# template-no-invalid-aria-attributes
2+
3+
✅ The `extends: 'plugin:ember/strict-gjs'` or `extends: 'plugin:ember/strict-gts'` property in a configuration file enables this rule.
4+
5+
Disallow invalid ARIA attributes. Only use valid ARIA attributes as defined in the ARIA specification.
6+
7+
## Rule Details
8+
9+
This rule validates that only standard ARIA attributes are used on elements.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
<div aria-fake="value">Content</div>
18+
</template>
19+
20+
<template>
21+
<div aria-invalid-attr="value">Content</div>
22+
</template>
23+
```
24+
25+
Examples of **correct** code for this rule:
26+
27+
```gjs
28+
<template>
29+
<div aria-label="Label">Content</div>
30+
</template>
31+
32+
<template>
33+
<div aria-hidden="true">Content</div>
34+
</template>
35+
36+
<template>
37+
<div aria-describedby="description-id">Content</div>
38+
</template>
39+
```
40+
41+
## Config
42+
43+
<!-- begin auto-generated rule meta list -->
44+
- strictGjs: true
45+
- strictGts: true
46+
<!-- end auto-generated rule meta list -->
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# template-no-invalid-link-title
2+
3+
✅ The `extends: 'plugin:ember/strict-gjs'` or `extends: 'plugin:ember/strict-gts'` property in a configuration file enables this rule.
4+
5+
Disallow invalid `title` attributes on link elements. The title should not be empty or the same as the link text.
6+
7+
## Rule Details
8+
9+
This rule ensures that link titles provide additional context and are not redundant with the link text.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
<a href="/page" title="">Page</a>
18+
</template>
19+
20+
<template>
21+
<a href="/page" title="Page">Page</a>
22+
</template>
23+
```
24+
25+
Examples of **correct** code for this rule:
26+
27+
```gjs
28+
<template>
29+
<a href="/page" title="More information about page">Page</a>
30+
</template>
31+
32+
<template>
33+
<a href="/page">Page</a>
34+
</template>
35+
```
36+
37+
## Config
38+
39+
<!-- begin auto-generated rule meta list -->
40+
- strictGjs: true
41+
- strictGts: true
42+
<!-- end auto-generated rule meta list -->
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# template-no-negated-condition
2+
3+
✅ The `extends: 'plugin:ember/strict-gjs'` or `extends: 'plugin:ember/strict-gts'` property in a configuration file enables this rule.
4+
5+
Disallow negated conditions in `{{#if}}` blocks. Use `{{#unless}}` instead or rewrite the condition.
6+
7+
## Rule Details
8+
9+
This rule discourages the use of `{{#if (not condition)}}` in favor of `{{#unless condition}}` for better readability.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
{{#if (not isValid)}}
18+
Invalid
19+
{{/if}}
20+
</template>
21+
```
22+
23+
Examples of **correct** code for this rule:
24+
25+
```gjs
26+
<template>
27+
{{#unless isValid}}
28+
Invalid
29+
{{/unless}}
30+
</template>
31+
32+
<template>
33+
{{#if isValid}}
34+
Valid
35+
{{/if}}
36+
</template>
37+
```
38+
39+
## Config
40+
41+
<!-- begin auto-generated rule meta list -->
42+
- strictGjs: true
43+
- strictGts: true
44+
<!-- end auto-generated rule meta list -->
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# template-no-outlet-outside-routes
2+
3+
✅ The `extends: 'plugin:ember/strict-gjs'` or `extends: 'plugin:ember/strict-gts'` property in a configuration file enables this rule.
4+
5+
Disallow `{{outlet}}` outside of route templates. The `outlet` helper should only be used in route templates to render nested routes.
6+
7+
## Rule Details
8+
9+
This rule prevents the use of `{{outlet}}` in component templates where it doesn't make sense.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
// In a component template
17+
<template>
18+
<div>
19+
{{outlet}}
20+
</div>
21+
</template>
22+
```
23+
24+
Examples of **correct** code for this rule:
25+
26+
```gjs
27+
// In a component template
28+
<template>
29+
<div>Content</div>
30+
</template>
31+
```
32+
33+
## Config
34+
35+
<!-- begin auto-generated rule meta list -->
36+
- strictGjs: true
37+
- strictGts: true
38+
<!-- end auto-generated rule meta list -->
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# template-no-unnecessary-curly-in-string-attrs
2+
3+
✅ The `extends: 'plugin:ember/strict-gjs'` or `extends: 'plugin:ember/strict-gts'` property in a configuration file enables this rule.
4+
5+
Disallow unnecessary curly braces around string literals in attributes.
6+
7+
## Rule Details
8+
9+
This rule enforces using static strings directly instead of wrapping them in mustache syntax.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
<div class={{"static-class"}}>Content</div>
18+
</template>
19+
```
20+
21+
Examples of **correct** code for this rule:
22+
23+
```gjs
24+
<template>
25+
<div class="static-class">Content</div>
26+
</template>
27+
28+
<template>
29+
<div class={{this.dynamicClass}}>Content</div>
30+
</template>
31+
```
32+
33+
## Config
34+
35+
<!-- begin auto-generated rule meta list -->
36+
- strictGjs: true
37+
- strictGts: true
38+
<!-- end auto-generated rule meta list -->
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# template-require-each-key
2+
3+
✅ The `extends: 'plugin:ember/strict-gjs'` or `extends: 'plugin:ember/strict-gts'` property in a configuration file enables this rule.
4+
5+
Require a `key` attribute in `{{#each}}` loops for better rendering performance and to avoid rendering issues.
6+
7+
## Rule Details
8+
9+
This rule enforces using a `key` attribute in `{{#each}}` blocks to help Ember track items efficiently.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
{{#each items as |item|}}
18+
<div>{{item.name}}</div>
19+
{{/each}}
20+
</template>
21+
```
22+
23+
Examples of **correct** code for this rule:
24+
25+
```gjs
26+
<template>
27+
{{#each items key="id" as |item|}}
28+
<div>{{item.name}}</div>
29+
{{/each}}
30+
</template>
31+
32+
<template>
33+
{{#each items key="@index" as |item|}}
34+
<div>{{item.name}}</div>
35+
{{/each}}
36+
</template>
37+
```
38+
39+
## Config
40+
41+
<!-- begin auto-generated rule meta list -->
42+
- strictGjs: true
43+
- strictGts: true
44+
<!-- end auto-generated rule meta list -->

0 commit comments

Comments
 (0)