From c340132e56c3007c5e80db14644e437f4f3e9aa0 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 10 Mar 2026 18:23:32 -0400 Subject: [PATCH 1/2] Extract rule: template-deprecated-render-helper --- README.md | 1 + .../template-deprecated-render-helper.md | 25 ++++++ .../template-deprecated-render-helper.js | 49 +++++++++++ .../template-deprecated-render-helper.js | 85 +++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 docs/rules/template-deprecated-render-helper.md create mode 100644 lib/rules/template-deprecated-render-helper.js create mode 100644 tests/lib/rules/template-deprecated-render-helper.js diff --git a/README.md b/README.md index d63131fbd2..2abdf640df 100644 --- a/README.md +++ b/README.md @@ -292,6 +292,7 @@ rules in templates can be disabled with eslint directives with mustache or html | [no-old-shims](docs/rules/no-old-shims.md) | disallow usage of old shims for modules | ✅ | 🔧 | | | [no-string-prototype-extensions](docs/rules/no-string-prototype-extensions.md) | disallow usage of `String` prototype extensions | ✅ | | | | [template-deprecated-inline-view-helper](docs/rules/template-deprecated-inline-view-helper.md) | disallow inline {{view}} helper | | 🔧 | | +| [template-deprecated-render-helper](docs/rules/template-deprecated-render-helper.md) | disallow {{render}} helper | | | | | [template-no-action](docs/rules/template-no-action.md) | disallow {{action}} helper | | | | | [template-no-attrs-in-components](docs/rules/template-no-attrs-in-components.md) | disallow attrs in component templates | | | | | [template-no-link-to-positional-params](docs/rules/template-no-link-to-positional-params.md) | disallow positional params in LinkTo component | | | | diff --git a/docs/rules/template-deprecated-render-helper.md b/docs/rules/template-deprecated-render-helper.md new file mode 100644 index 0000000000..c0fb7dbcc8 --- /dev/null +++ b/docs/rules/template-deprecated-render-helper.md @@ -0,0 +1,25 @@ +# ember/template-deprecated-render-helper + +> **HBS Only**: This rule applies to classic `.hbs` template files only (loose mode). It is not relevant for `gjs`/`gts` files (strict mode), where these patterns cannot occur. + + + +Disallows the {{render}} helper which is deprecated. + +## Examples + +Incorrect: + +```hbs +{{render 'user'}} +``` + +Correct: + +```hbs + +``` + +## References + +- [eslint-plugin-ember template-deprecated-render-helper](https://github.com/ember-cli/eslint-plugin-ember/blob/master/docs/rules/template-deprecated-render-helper.md) diff --git a/lib/rules/template-deprecated-render-helper.js b/lib/rules/template-deprecated-render-helper.js new file mode 100644 index 0000000000..6874ae80b9 --- /dev/null +++ b/lib/rules/template-deprecated-render-helper.js @@ -0,0 +1,49 @@ +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + meta: { + type: 'suggestion', + docs: { + description: 'disallow {{render}} helper', + category: 'Deprecations', + url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-deprecated-render-helper.md', + templateMode: 'loose', + }, + fixable: null, + schema: [], + messages: { + deprecated: + 'The render helper is deprecated in favor of using components. See https://emberjs.com/deprecations/v2.x/#toc_code-render-code-helper', + }, + originallyFrom: { + name: 'ember-template-lint', + rule: 'lib/rules/deprecated-render-helper.js', + docs: 'docs/rule/deprecated-render-helper.md', + tests: 'test/unit/rules/deprecated-render-helper-test.js', + }, + }, + + create(context) { + function checkForRender(node) { + if ( + node.path && + node.path.type === 'GlimmerPathExpression' && + node.path.original === 'render' + ) { + context.report({ + node, + messageId: 'deprecated', + }); + } + } + + return { + GlimmerMustacheStatement(node) { + checkForRender(node); + }, + + GlimmerBlockStatement(node) { + checkForRender(node); + }, + }; + }, +}; diff --git a/tests/lib/rules/template-deprecated-render-helper.js b/tests/lib/rules/template-deprecated-render-helper.js new file mode 100644 index 0000000000..8bbec129d0 --- /dev/null +++ b/tests/lib/rules/template-deprecated-render-helper.js @@ -0,0 +1,85 @@ +const rule = require('../../../lib/rules/template-deprecated-render-helper'); +const RuleTester = require('eslint').RuleTester; + +const ruleTester = new RuleTester({ + parser: require.resolve('ember-eslint-parser'), + parserOptions: { ecmaVersion: 2022, sourceType: 'module' }, +}); + +ruleTester.run('template-deprecated-render-helper', rule, { + valid: [ + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + ], + invalid: [ + { + code: '', + output: null, + errors: [{ messageId: 'deprecated' }], + }, + + { + code: "", + output: null, + errors: [{ messageId: 'deprecated' }], + }, + { + code: "", + output: null, + errors: [{ messageId: 'deprecated' }], + }, + ], +}); + +const hbsRuleTester = new RuleTester({ + parser: require.resolve('ember-eslint-parser/hbs'), + parserOptions: { + ecmaVersion: 2022, + sourceType: 'module', + }, +}); + +hbsRuleTester.run('template-deprecated-render-helper', rule, { + valid: [ + '{{valid-compoennt}}', + '{{input placeholder=(t "email") value=email}}', + '{{title "CrossCheck Web" prepent=true separator=" | "}}', + '{{hockey-player teamName="Boston Bruins"}}', + '{{false}}', + '{{"foo"}}', + '{{42}}', + '{{null}}', + '{{undefined}}', + ], + invalid: [ + { + code: "{{render 'ken-griffey'}}", + output: null, + errors: [ + { + message: + 'The render helper is deprecated in favor of using components. See https://emberjs.com/deprecations/v2.x/#toc_code-render-code-helper', + }, + ], + }, + { + code: "{{render 'baseball-player' pitcher}}", + output: null, + errors: [ + { + message: + 'The render helper is deprecated in favor of using components. See https://emberjs.com/deprecations/v2.x/#toc_code-render-code-helper', + }, + ], + }, + ], +}); From 38db42b9520016e0d0693ba01a9e7a20f891e0a7 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 13 Mar 2026 13:34:15 -0400 Subject: [PATCH 2/2] Update with fixer --- README.md | 2 +- .../template-deprecated-render-helper.md | 2 ++ .../template-deprecated-render-helper.js | 26 ++++++++++++++++++- .../template-deprecated-render-helper.js | 25 +++++------------- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 2abdf640df..b695f7a52e 100644 --- a/README.md +++ b/README.md @@ -292,7 +292,7 @@ rules in templates can be disabled with eslint directives with mustache or html | [no-old-shims](docs/rules/no-old-shims.md) | disallow usage of old shims for modules | ✅ | 🔧 | | | [no-string-prototype-extensions](docs/rules/no-string-prototype-extensions.md) | disallow usage of `String` prototype extensions | ✅ | | | | [template-deprecated-inline-view-helper](docs/rules/template-deprecated-inline-view-helper.md) | disallow inline {{view}} helper | | 🔧 | | -| [template-deprecated-render-helper](docs/rules/template-deprecated-render-helper.md) | disallow {{render}} helper | | | | +| [template-deprecated-render-helper](docs/rules/template-deprecated-render-helper.md) | disallow {{render}} helper | | 🔧 | | | [template-no-action](docs/rules/template-no-action.md) | disallow {{action}} helper | | | | | [template-no-attrs-in-components](docs/rules/template-no-attrs-in-components.md) | disallow attrs in component templates | | | | | [template-no-link-to-positional-params](docs/rules/template-no-link-to-positional-params.md) | disallow positional params in LinkTo component | | | | diff --git a/docs/rules/template-deprecated-render-helper.md b/docs/rules/template-deprecated-render-helper.md index c0fb7dbcc8..b4ea69d017 100644 --- a/docs/rules/template-deprecated-render-helper.md +++ b/docs/rules/template-deprecated-render-helper.md @@ -1,5 +1,7 @@ # ember/template-deprecated-render-helper +🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix). + > **HBS Only**: This rule applies to classic `.hbs` template files only (loose mode). It is not relevant for `gjs`/`gts` files (strict mode), where these patterns cannot occur. diff --git a/lib/rules/template-deprecated-render-helper.js b/lib/rules/template-deprecated-render-helper.js index 6874ae80b9..2bd35690d2 100644 --- a/lib/rules/template-deprecated-render-helper.js +++ b/lib/rules/template-deprecated-render-helper.js @@ -8,7 +8,7 @@ module.exports = { url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-deprecated-render-helper.md', templateMode: 'loose', }, - fixable: null, + fixable: 'code', schema: [], messages: { deprecated: @@ -23,6 +23,29 @@ module.exports = { }, create(context) { + const sourceCode = context.sourceCode; + + function buildFix(node) { + const first = node.params[0]; + if (!first || first.type !== 'GlimmerStringLiteral') { + return null; + } + const templateName = first.value; + + if (node.params.length === 1) { + // {{render 'name'}} → {{name}} + return (fixer) => fixer.replaceText(node, `{{${templateName}}}`); + } + + if (node.params.length === 2) { + // {{render 'name' model}} → {{name model=model}} + const model = sourceCode.getText(node.params[1]); + return (fixer) => fixer.replaceText(node, `{{${templateName} model=${model}}}`); + } + + return null; + } + function checkForRender(node) { if ( node.path && @@ -32,6 +55,7 @@ module.exports = { context.report({ node, messageId: 'deprecated', + fix: buildFix(node), }); } } diff --git a/tests/lib/rules/template-deprecated-render-helper.js b/tests/lib/rules/template-deprecated-render-helper.js index 8bbec129d0..135f63a2b3 100644 --- a/tests/lib/rules/template-deprecated-render-helper.js +++ b/tests/lib/rules/template-deprecated-render-helper.js @@ -23,18 +23,17 @@ ruleTester.run('template-deprecated-render-helper', rule, { invalid: [ { code: '', - output: null, + output: '', errors: [{ messageId: 'deprecated' }], }, - { code: "", - output: null, + output: '', errors: [{ messageId: 'deprecated' }], }, { code: "", - output: null, + output: '', errors: [{ messageId: 'deprecated' }], }, ], @@ -63,23 +62,13 @@ hbsRuleTester.run('template-deprecated-render-helper', rule, { invalid: [ { code: "{{render 'ken-griffey'}}", - output: null, - errors: [ - { - message: - 'The render helper is deprecated in favor of using components. See https://emberjs.com/deprecations/v2.x/#toc_code-render-code-helper', - }, - ], + output: '{{ken-griffey}}', + errors: [{ messageId: 'deprecated' }], }, { code: "{{render 'baseball-player' pitcher}}", - output: null, - errors: [ - { - message: - 'The render helper is deprecated in favor of using components. See https://emberjs.com/deprecations/v2.x/#toc_code-render-code-helper', - }, - ], + output: '{{baseball-player model=pitcher}}', + errors: [{ messageId: 'deprecated' }], }, ], });