Skip to content

Commit 11072ba

Browse files
committed
Sync with template-lint
1 parent aefa396 commit 11072ba

4 files changed

Lines changed: 143 additions & 95 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ rules in templates can be disabled with eslint directives with mustache or html
245245
| [template-no-obsolete-elements](docs/rules/template-no-obsolete-elements.md) | disallow obsolete HTML elements | | | |
246246
| [template-no-outlet-outside-routes](docs/rules/template-no-outlet-outside-routes.md) | disallow {{outlet}} outside of route templates | | | |
247247
| [template-no-page-title-component](docs/rules/template-no-page-title-component.md) | disallow usage of ember-page-title component | | | |
248-
| [template-require-valid-named-block-naming-format](docs/rules/template-require-valid-named-block-naming-format.md) | require valid named block naming format | | | |
248+
| [template-require-valid-named-block-naming-format](docs/rules/template-require-valid-named-block-naming-format.md) | require valid named block naming format | | 🔧 | |
249249
| [template-self-closing-void-elements](docs/rules/template-self-closing-void-elements.md) | require self-closing on void elements | | 🔧 | |
250250
| [template-simple-modifiers](docs/rules/template-simple-modifiers.md) | require simple modifier syntax | | | |
251251
| [template-simple-unless](docs/rules/template-simple-unless.md) | require simple conditions in unless blocks | | | |
Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,70 @@
11
# ember/template-require-valid-named-block-naming-format
22

3+
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
4+
35
<!-- end auto-generated rule header -->
46

5-
Require valid named block naming format.
7+
Require named blocks to use a valid naming format (`camelCase` or `kebab-case`).
68

7-
Named blocks in `yield` and `has-block` helpers should follow a consistent naming format.
9+
The default naming format used is `camelCase`.
810

911
## Examples
1012

11-
This rule **forbids** the following (with default camelCase):
13+
This rule **forbids** the following when the `camelCase` naming format is enabled:
1214

1315
```gjs
1416
<template>
15-
{{yield to='foo-bar'}}
17+
{{yield to="foo-bar"}}
18+
{{has-block "foo-bar"}}
19+
{{if (has-block "foo-bar")}}
20+
{{has-block-params "foo-bar"}}
21+
{{if (has-block-params "foo-bar")}}
1622
</template>
1723
```
1824

25+
This rule **allows** the following when the `camelCase` naming format is enabled:
26+
1927
```gjs
2028
<template>
21-
{{has-block 'foo-bar'}}
29+
{{yield to="fooBar"}}
30+
{{has-block "fooBar"}}
31+
{{if (has-block "fooBar")}}
32+
{{has-block-params "fooBar"}}
33+
{{if (has-block-params "fooBar")}}
2234
</template>
2335
```
2436

25-
This rule **allows** the following (with default camelCase):
37+
This rule **forbids** the following when the `kebab-case` naming format is enabled:
2638

2739
```gjs
2840
<template>
29-
{{yield to='fooBar'}}
41+
{{yield to="fooBar"}}
42+
{{has-block "fooBar"}}
43+
{{if (has-block "fooBar")}}
44+
{{has-block-params "fooBar"}}
45+
{{if (has-block-params "fooBar")}}
3046
</template>
3147
```
3248

49+
This rule **allows** the following when the `kebab-case` naming format is enabled:
50+
3351
```gjs
3452
<template>
35-
{{has-block 'fooBar'}}
53+
{{yield to="foo-bar"}}
54+
{{has-block "foo-bar"}}
55+
{{if (has-block "foo-bar")}}
56+
{{has-block-params "foo-bar"}}
57+
{{if (has-block-params "foo-bar")}}
3658
</template>
3759
```
3860

3961
## Configuration
4062

41-
- `camelCase` (default) - Named blocks should use camelCase format
42-
- `kebab-case` - Named blocks should use kebab-case format
43-
44-
```js
45-
// .eslintrc.js
46-
module.exports = {
47-
rules: {
48-
'ember/template-require-valid-named-block-naming-format': ['error', 'camelCase'],
49-
},
50-
};
51-
```
63+
- boolean -- `true` enables the rule with the default `camelCase` format and `false`
64+
disables it
65+
- string -- `"camelCase"` requires the use of the `camelCase` naming format, and
66+
`"kebab-case"` requires the use of the `kebab-case` naming format
5267

5368
## References
5469

55-
- [Ember.js Guides - Named Blocks](https://guides.emberjs.com/release/components/template-syntax/#toc_named-blocks)
70+
- [Naming convention (programming)](<https://en.wikipedia.org/wiki/Naming_convention_(programming)>)

lib/rules/template-require-valid-named-block-naming-format.js

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,16 @@ function parseConfig(config) {
4343
return DEFAULT_FORMAT;
4444
}
4545

46-
function createErrorMessage(format, actual, expected) {
47-
return `Named block should be in ${format} format. Change "${actual}" to "${expected}".`;
46+
function getStringQuote(text) {
47+
return text.startsWith("'") ? "'" : '"';
48+
}
49+
50+
function isHasBlockNode(node) {
51+
return node.path?.original === 'has-block' || node.path?.original === 'has-block-params';
52+
}
53+
54+
function isYieldNode(node) {
55+
return node.path?.original === 'yield';
4856
}
4957

5058
/** @type {import('eslint').Rule.RuleModule} */
@@ -58,18 +66,16 @@ module.exports = {
5866
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-require-valid-named-block-naming-format.md',
5967
templateMode: 'both',
6068
},
61-
fixable: null,
69+
fixable: 'code',
6270
schema: [
6371
{
64-
oneOf: [
65-
{
66-
type: 'string',
67-
enum: ['camelCase', 'kebab-case'],
68-
},
69-
],
72+
oneOf: [{ type: 'boolean' }, { type: 'string', enum: ['camelCase', 'kebab-case'] }],
7073
},
7174
],
72-
messages: {},
75+
messages: {
76+
invalidFormat:
77+
'Named blocks are required to use the "{{format}}" naming format. Please change "{{actual}}" to "{{expected}}".',
78+
},
7379
originallyFrom: {
7480
name: 'ember-template-lint',
7581
rule: 'lib/rules/require-valid-named-block-naming-format.js',
@@ -79,8 +85,8 @@ module.exports = {
7985
},
8086

8187
create(context) {
82-
let config = context.options[0];
83-
config = parseConfig(config);
88+
const sourceCode = context.sourceCode;
89+
const config = parseConfig(context.options[0]);
8490

8591
if (config === false) {
8692
return {};
@@ -92,46 +98,41 @@ module.exports = {
9298
const expectedName = formatMethod(name);
9399

94100
if (name !== expectedName) {
101+
const quote = getStringQuote(sourceCode.getText(node));
102+
95103
context.report({
96104
node,
97-
message: createErrorMessage(config, name, expectedName),
105+
messageId: 'invalidFormat',
106+
data: {
107+
format: config,
108+
actual: name,
109+
expected: expectedName,
110+
},
111+
fix(fixer) {
112+
return fixer.replaceText(node, `${quote}${expectedName}${quote}`);
113+
},
98114
});
99115
}
100116
}
101117

102118
return {
103119
GlimmerMustacheStatement(node) {
104-
const path = node.path.original;
105-
106-
// Check yield with 'to' hash
107-
if (path === 'yield' && node.hash && node.hash.pairs) {
120+
if (isYieldNode(node) && node.hash?.pairs) {
108121
const toPair = node.hash.pairs.find((pair) => pair.key === 'to');
109-
if (toPair && toPair.value && toPair.value.type === 'GlimmerStringLiteral') {
122+
if (toPair?.value?.type === 'GlimmerStringLiteral') {
110123
checkNamedBlockName(toPair.value.value, toPair.value);
111124
}
112125
}
113126

114-
// Check has-block with first param as string
115-
if (
116-
(path === 'has-block' || path === 'has-block-params') &&
117-
node.params &&
118-
node.params[0]
119-
) {
127+
if (isHasBlockNode(node) && node.params?.[0]) {
120128
if (node.params[0].type === 'GlimmerStringLiteral') {
121129
checkNamedBlockName(node.params[0].value, node.params[0]);
122130
}
123131
}
124132
},
125133

126134
GlimmerSubExpression(node) {
127-
const path = node.path.original;
128-
129-
// Check has-block in subexpressions
130-
if (
131-
(path === 'has-block' || path === 'has-block-params') &&
132-
node.params &&
133-
node.params[0]
134-
) {
135+
if (isHasBlockNode(node) && node.params?.[0]) {
135136
if (node.params[0].type === 'GlimmerStringLiteral') {
136137
checkNamedBlockName(node.params[0].value, node.params[0]);
137138
}

0 commit comments

Comments
 (0)