From 51c419bdf10b8a4cd4ceebaa0a03469986a87935 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Fri, 4 Oct 2024 12:50:12 -0400 Subject: [PATCH 1/4] Template Tag In Routes --- text/1046-template-tag-in-routes.md | 184 ++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 text/1046-template-tag-in-routes.md diff --git a/text/1046-template-tag-in-routes.md b/text/1046-template-tag-in-routes.md new file mode 100644 index 0000000000..7ea43f0fba --- /dev/null +++ b/text/1046-template-tag-in-routes.md @@ -0,0 +1,184 @@ +--- +stage: accepted +start-date: 2024-10-04T00:00:00.000Z +release-date: # In format YYYY-MM-DDT00:00:00.000Z +release-versions: +teams: # delete teams that aren't relevant + - framework + - learning + - typescript +prs: + accepted: https://github.com/emberjs/rfcs/pull/1046 +project-link: +suite: +--- + + + +# Use Template Tag in Routes + +## Summary + +Allow `app/templates/*.hbs` to convert to `app/temlates/*.gjs`. + +## Motivation + +We are rapidly approaching the point where Template Tag is the recommended way to author components. This means using `.gjs` (or `.gts`) files that combine your template and Javascript into one file. But you cannot currently use Template Tag to author the top-level templates invokes by the router (`app/templates/*.hbs`). + +This inconsistency is especially apparent when working on teaching materials for new users. Making people learn both `.hbs` with global component resolution and `.gjs` with strict template resolution before they can even make their first component is unreasonable. + +This RFC proposes allowing consistent use of `.gjs` everywhere. It doesn't remove any support for `.hbs`, but recommends that the guides default to all `.gjs`. + +## Detailed design + +The [implementation is small and already done](https://github.com/emberjs/ember.js/pull/20768). + +### Illustration By Example + +If you currently have this: + +```hbs +{{! app/templates/example.hbs }} +
+ +
+``` + +You can convert it to this: + +```gjs +// app/templates/example.gjs +import MainContent from 'my-app/components/main-content'; + +``` + +Key differences: + + - this is [strict handlebars](https://github.com/emberjs/rfcs/blob/master/text/0496-handlebars-strict-mode.md), so components are imported explicitly + - the controller is no longer `this`, it is `@controller`. + +Many things that you might have been forced to put on a controller can now be done directly. For example, if your controller has a `doSomething` event handler: + +```hbs +{{! app/templates/example.hbs }} +
+``` + +You now have options to implement it in-place in the same file. If it's stateless it can just be a function: + +```gjs +// app/templates/example.gjs + +// This import will be unnecessary after https://github.com/emberjs/rfcs/pull/1033 +import { on } from '@ember/modifier'; + +function doSomething() { + alert("It worked"); +} + + +``` + +If it's stateful, you can upgrade from a template-only component to a Glimmer component: + +```gjs +// app/templates/example.gjs +import { on } from '@ember/modifier'; +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; + +export default class extends Component { + @tracked activated = false; + + doSomething = () => { + this.activated = !this.activated; + } + + +} +``` + +### Implementation + +When Ember resolves a route template: + +1. Check whether the resulting value has a component manager. + - If no, do exactly what happens today. + - If yes, continue to step 2. +2. Synthesize a route template that invokes your component with these arguments: + - @model: which means exactly the same as always. + - @controller: makes the controller available. + +Keen observers will notice that this says nothing about only supporting gjs files. Any component is eligible, no matter how it's authored or what Component Manager it uses. This is by design, because there's no reason for the router to violate the component abstraction and care about how that component was implemented. + +However, in our learning materials we should present this as a feature designed for GJS files. Using it with components authored in .hbs would be needlessly confusing, because automatic template co-location **does not work in app/templates**, because it would collide with traditional route templates. + +### ember-route-template addon + +This RFC replaces the [ember-route-template](https://github.com/discourse/ember-route-template) addon. If you're already using it, it would continue to work without breaking, but you can simply delete all the calls to its `RouteTemplate` function and remove it. The popularity of that addon among teams who are already adopting Template Tag is an argument in favor of this RFC. + +### Codemod + +Because Embroider already generates imports for components, helpers, and modifiers in non-strict templates, there is [ongoing work](https://github.com/embroider-build/embroider/pull/2134) to offer Embroider's existing functionality as a Template Tag codemod. + +For route templates, the only extra feature required would be replacing `this` with `@controller`. + +### TypeScript + +No new typescript-specific features are required. If you're authoring route templates in GTS, Glint should treat them just like any other component. You will need to manually declare the signature for `@model` and `@controller`, but that is the same as now. + +## How we teach this + +This RFC was directly inspired by a first attempt at updating the Guides for Template Tag. It became immediately apparent that we can write *much* clearer guides if we can teach all GJS, instead of a mix of GJS and HBS. + +Starting at https://guides.emberjs.com/release/components/ when the first `application.hbs` file is introduced, we would use `.gjs` instead. In those opening examples that are empahsizing HTML, the only change to the content would be wrapping `` around the HTML. + +Progressing to https://guides.emberjs.com/release/components/introducing-components/, learners extract their first component. It now becomes possible to do that within the same file. This allows teaching fewer things in a single step. First, people can learn what a component is. Second, it can be refactored into a separate file. We can avoid teaching anything about "pascal case" and naming rules, because everything just follows javascript naming rules. + +When starting to teach routing in https://guides.emberjs.com/release/routing/defining-your-routes/, the file extensions change and `` wrappers are added, but nothing else on that page necessarily changes. + +In https://guides.emberjs.com/release/routing/query-params/, it's appropriate to first introduce the `@controller` argument. + +In https://guides.emberjs.com/release/routing/controllers/, the list of reasons to use a controller gets shortened to only queryParams, since now you can manage state directly in your route's component. + + +## Drawbacks + +There is appetite for a more ambitious RFC that changes more things about routing. Eliminating controllers, making routes play nice with the newer `@ember/destroyable` system, allowing parallel model hooks, etc, are all good goals. There is a risk that if we do those things soon, this would be seen as two steps of churn instead of one. + +I think we can mitigate that risk because + - we won't deprecate `.hbs` routes yet, so no churn is forced immediately. + - we can ship the Template Tag codemod so that even big apps can adopt at low cost + - it's extremely unlikely that a future routing design would use anything other than `.gjs` to define route entrypoints. By converting now, you are already moving in the right direction by eliminating all the non-strict behaviors. + + +## Alternatives + +The main alternative here is to do a bigger change to the routing system. A "Route Manager" RFC would allow the creation of new Route implementations that could have their own opinions about how to route to GJS files. This RFC does not preclude that other work from also happening. + +The main benefit of this RFC is that the [implementation is small and already done](https://github.com/emberjs/ember.js/pull/20768) so we could have it immediately. + + From 8523a0fd6cfe2eaadadd0d96ea933a4c15861994 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Fri, 4 Oct 2024 13:06:31 -0400 Subject: [PATCH 2/4] Update text/1046-template-tag-in-routes.md Co-authored-by: MrChocolatine <47531779+MrChocolatine@users.noreply.github.com> --- text/1046-template-tag-in-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/1046-template-tag-in-routes.md b/text/1046-template-tag-in-routes.md index 7ea43f0fba..09e9d30103 100644 --- a/text/1046-template-tag-in-routes.md +++ b/text/1046-template-tag-in-routes.md @@ -35,7 +35,7 @@ Allow `app/templates/*.hbs` to convert to `app/temlates/*.gjs`. ## Motivation -We are rapidly approaching the point where Template Tag is the recommended way to author components. This means using `.gjs` (or `.gts`) files that combine your template and Javascript into one file. But you cannot currently use Template Tag to author the top-level templates invokes by the router (`app/templates/*.hbs`). +We are rapidly approaching the point where Template Tag is the recommended way to author components. This means using `.gjs` (or `.gts`) files that combine your template and Javascript into one file. But you cannot currently use Template Tag to author the top-level templates invoked by the router (`app/templates/*.hbs`). This inconsistency is especially apparent when working on teaching materials for new users. Making people learn both `.hbs` with global component resolution and `.gjs` with strict template resolution before they can even make their first component is unreasonable. From 8cfb0b15f24f4bf38888fd63248ae6e0e3fdb2cb Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Fri, 4 Oct 2024 15:01:58 -0400 Subject: [PATCH 3/4] Update text/1046-template-tag-in-routes.md Co-authored-by: Ignace Maes <10243652+IgnaceMaes@users.noreply.github.com> --- text/1046-template-tag-in-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/1046-template-tag-in-routes.md b/text/1046-template-tag-in-routes.md index 09e9d30103..505216d002 100644 --- a/text/1046-template-tag-in-routes.md +++ b/text/1046-template-tag-in-routes.md @@ -93,7 +93,7 @@ function doSomething() { } ``` From 16c993c69cbe30b860a3bf2b0948a9dab35ab707 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Fri, 22 Nov 2024 14:48:12 -0500 Subject: [PATCH 4/4] updating alternatives and hbs teaching --- text/1046-template-tag-in-routes.md | 53 ++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/text/1046-template-tag-in-routes.md b/text/1046-template-tag-in-routes.md index 505216d002..023108d48f 100644 --- a/text/1046-template-tag-in-routes.md +++ b/text/1046-template-tag-in-routes.md @@ -10,11 +10,11 @@ teams: # delete teams that aren't relevant prs: accepted: https://github.com/emberjs/rfcs/pull/1046 project-link: -suite: +suite: --- -