From 3dff63ad84d7088fd852ea1dfafbe4187916327b Mon Sep 17 00:00:00 2001 From: Gavin Joyce Date: Wed, 13 Feb 2019 14:46:25 +0000 Subject: [PATCH] deprecate {{with}} --- text/0000-template.md | 148 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 text/0000-template.md diff --git a/text/0000-template.md b/text/0000-template.md new file mode 100644 index 0000000000..cb2d3e2d07 --- /dev/null +++ b/text/0000-template.md @@ -0,0 +1,148 @@ +- Start Date: 2019-02-13 +- Relevant Teams: Ember.js, Learning +- RFC PR: https://github.com/emberjs/rfcs/pull/445 +- Tracking: (leave this empty) + +# Deprecate `{{with}}` + +## Summary + +The `{{with}}` helper has always had slightly confusing conditional semantics, this was one of the motivators for [introducing](https://github.com/emberjs/rfcs/blob/master/text/0286-block-let-template-helper.md) the easier to understand `{{let}}` helper. Now that `{{let}}` exists, the remaining use case for using `{{with}}` is for its unique conditional semantics. These conditional semantics can be cleanly represented with a combination of `{{let}}` and `{{if}}` statements so we should deprecate `{{with}}`. + +## Motivation + +The difference between `{{let}}` and `{{with}}` is with how they handle conditional arguments. The `{{let}}` helper's block content is always rendered, regardless of its parameters. In contrast, `{{with}}` only renders its main block when the first position parameter is truthy. For example: + +```hbs +{{#with "Alex" as |value|}} + {{value}} is truthy +{{else}} + The first positional param was falsy +{{/with}} +``` + +Will render "[Alex] is truthy". + +```hbs +{{#with false as |value|}} + {{value}} is truthy +{{else}} + The first positional param was falsy +{{/with}} +``` + +Will render "The first positional param was falsy". + +The conditional arguments behavior of `{{with}}` can easily be replicated using a combination of `{{let}}` and `{{if}}` in a way that's easily readable: + +```hbs +{{#let "Alex" as |value|}} + {{#if value}} + {{value}} is truthy + {{else}} + The first positional param was falsy + {{/if}} +{{/let}} +``` + +## Detailed design + +We'll create an AST transform in [`packages/ember-template-compiler`](https://github.com/emberjs/ember.js/tree/master/packages/ember-template-compiler) which will emit a deprecation warning for all uses of `{{with}}`. The deprecation warning will be: + +``` +Using `{{with}}` is deprecated, please use `{{let}}` instead. +``` + +This message will link to the following deprecation details which aim to give clear guidance on how to migrate to using `{{let}}`, `{{if}}` and `{{else}}` in different combinations: + +---- + +The use of `{{with}}` has been deprecated, you should replace it with either `{{let}}` or a combination of `{{let}}`, `{{if}}` and `{{else}}`: + +**If you always want the block to render, replace `{{with}}` with `{{let}}` directly:** + +Before: + +```hbs +{{#with (hash name="Ben" age=4) as |person|}} + Hi {{person.name}}, you are {{person.age}} years old. +{{/with}} +``` + +After: + +```hbs +{{#let (hash name="Ben" age=4) as |person|}} + Hi {{person.name}}, you are {{person.age}} years old. +{{/let}} +``` + +**If you want to render a block conditionally, use a combination of `{{let}}` and `{{if}}`:** + +Before: + +```hbs +{{#with user.posts as |blogPosts|}} + There are {{blogPosts.length}} blog posts +{{/with}} +``` + +After: + +```hbs +{{#let user.posts as |blogPosts|}} + {{#if blogPosts}} + There are {{blogPosts.length}} blog posts + {{/if}} +{{/let}} +``` + +**If you want to render a block conditionally, and otherwise render an alternative block, use a combination of `{{let}}`, `{{if}}` and `{{else}}`:** + +Before: + +```hbs +{{#with user.posts as |blogPosts|}} + There are {{blogPosts.length}} blog posts +{{else}} + There are no blog posts +{{/with}} +``` + +After: + +```hbs +{{#let user.posts as |blogPosts|}} + {{#if blogPosts}} + There are {{blogPosts.length}} blog posts + {{else}} + There are no blog posts + {{/if}} +{{/let}} +``` + +--- + +For people on older versions of Ember that support `{{let}}`, we'll create an `ember-template-lint` rule that they can use to prevent the use of `{{with}}`. + +## How we teach this + +We'll mentiton the deprecation in an Ember point release blog post. + +As mentioned above, the deprecation message will contain a link to clear guidelines on how to migrate to using `{{let}}`. + +## Drawbacks + +This adds a little churn to Ember's API. + +## Alternatives + +We could leave `{{with}}` as is. I don't believe that this is a good option as the name `{{with}}` is confusing. + +We could deprecate `{{with}}` and introduce `{{if-let}}` in Ember core. This RFC originally made that exact proposal, I was strongly persuaded of the [lack of need for `{{if-let}}` by @tcjr](https://github.com/emberjs/rfcs/pull/445#issuecomment-463594185). + +We could deprecate `{{with}}` and introduce `{{if-let}}` in an addon instead of Ember core. + +## Unresolved questions + +(none)