Security News
NIST Misses 2024 Deadline to Clear NVD Backlog
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.
ember-template-imports
Advanced tools
This addon provides a number of different formats for using template imports within Ember!
import MyComponent from './my-component';
<template>
<MyComponent/>
</template>
Template imports are an upcoming feature in Ember. Like Glimmer components, the primitive APIs for supporting imports were built before we decided on a final format for their high level usage. There are a number of different ideas for how we can integrate imports with templates, and the idea behind this addon is that it can be a test bed for them all. This way, we can share common tooling between solutions, and work together as a community as we explore the design space.
So far, this addon supports two different potential formats:
Template tags, embedded in .gjs
files
import MyComponent from './my-component';
<template>
<MyComponent/>
</template>
Template literals, similar to the existing hbs
helper in tests:
import { hbs } from 'ember-template-imports';
import MyComponent from './my-component';
export default hbs`
<MyComponent/>
`;
For the previous version of this addon, see this repository. And huge thanks to @patricklx for his contributions here!
.gjs
FilesTemplate tags are a new syntax introduced in .gjs
, a new file format that is
a superset of standard JavaScript. In this syntax, templates are defined in
JavaScript files directly.
// components/hello.gjs
<template>
<span>Hello, {{@name}}!</span>
</template>
This example defines a template-only component, which is the default export of
hello.js
. You would be able to use this component in another component
like so:
// components/hello-world.gjs
import Hello from './hello';
<template>
<Hello @name="world" />
</template>
You can also export the component explicitly:
// components/hello.gjs
export default <template>
<span>Hello, {{@name}}!</span>
</template>
Omitting the export default
is just syntactic sugar. In addition, you can
define template-only components and assign them to variables, allowing you to
export components with named exports:
export const First = <template>First</template>
export const Second = <template>Second</template>
export const Third = <template>Third</template>
This also allows you to create components that are only used locally, in the same file:
const Option = <template>
<option selected={{@selected}} value={{@value}}>
{{or @title @value}}
</option>
</template>
export const CustomSelect = <template>
<select>
{{#each @options as |option|}}
<Option
@value={{option.value}}
@selected={{eq option @selectedOption}}
/>
{{/each}}
</select>
</template>
Helpers and modifiers can also be defined in the same file as your components, making them very flexible:
import { helper } from '@ember/component/helper';
import { modifier } from 'ember-modifier';
const plusOne = helper(([num]) => num + 1);
const setScrollPosition = modifier((element, [position]) => {
element.scrollTop = position
});
<template>
<div class="scroll-container" {{setScrollPosition @scrollPos}}>
{{#each @items as |item index|}}
Item #{{plusOne index}}: {{item}}
{{/each}}
</div>
</template>
Finally, to associate a template with a class-based component, you can use the template syntax directly in the class body:
// components/hello.gjs
export default class Hello {
name = 'world';
<template>
<span>Hello, {{this.name}}!</span>
</template>
}
hbs
Template literals are an existing JavaScript syntax that has been repurposed to define Ember templates. This syntax can be used in standard JavaScript files to define templates for Ember components.
// components/hello.js
import { hbs } from 'ember-template-imports';
export default hbs`
<span>Hello, {{@name}}!</span>
`;
This example defines a template-only component, which is the default export of
hello.js
. You would be able to use this component in another component
like so:
// components/hello-world.js
import { hbs } from 'ember-template-imports';
import Hello from './hello';
export default hbs`
<Hello @name="world" />
`;
In addition, you can define template-only components and assign them to variables, allowing you to export components with named exports:
import { hbs } from 'ember-template-imports';
export const First = hbs`First`;
export const Second = hbs`Second`;
export const Third = hbs`Third`;
This also allows you to create components that are only used locally, in the same file:
import { hbs } from 'ember-template-imports';
const Option = hbs`
<option selected={{@selected}} value={{@value}}>
{{or @title @value}}
</option>
`;
export const CustomSelect = hbs`
<select>
{{#each @options as |option|}}
<Option
@value={{option.value}}
@selected={{eq option @selectedOption}}
/>
{{/each}}
</select>
`;
Helpers and modifiers can also be defined in the same file as your components, making them very flexible:
import { hbs } from 'ember-template-imports';
import { helper } from '@ember/component/helper';
import { modifier } from 'ember-modifier';
const plusOne = helper(([num]) => num + 1);
const setScrollPosition = modifier((element, [position]) => {
element.scrollTop = position
});
hbs`
<div class="scroll-container" {{setScrollPosition @scrollPos}}>
{{#each @items as |item index|}}
Item #{{plusOne index}}: {{item}}
{{/each}}
</div>
`;
Finally, to associate a template with a class-based component, you can assign
the template to the static template
property of the class:
// components/hello.js
import Component from '@glimmer/component';
import { hbs } from 'ember-template-imports';
export default class Hello extends Component {
name = 'world';
static template = hbs`
<span>Hello, {{this.name}}!</span>
`;
}
This template literal syntax has a few key differences and restrictions from standard JS template literal syntax:
${}
) is disallowed. You cannot embed dynamic
values in templates, they must be statically analyzable and compilable.${}
to reference and use it.static template
property of class components does not exist directly on
the class. It is compiled away, and so it cannot be directly referenced or
dynamically modified/assigned.As implemented as part of the Strict Mode Templates RFC, the built in helpers, modifiers and components are available for import:
array
(import { array } from '@ember/helper';
)concat
(import { concat } from '@ember/helper';
)fn
(import { fn } from '@ember/helper';
)get
(import { get } from '@ember/helper';
)hash
(import { hash } from '@ember/helper';
)on
(import { on } from '@ember/modifier';
)Input
(import { Input } from '@ember/component';
)LinkTo
(import { LinkTo } from '@ember/routing';
)TextArea
(import { TextArea } from '@ember/component';
)ember-cli-htmlbars
6.0 or aboveember install ember-template-imports
To get syntax highlighting inside embedded templates and support for the GJS file extension, you may need to configure your editor.
The vscode-glimmer plugin handles syntax highlighting for both proposed formats.
Example Neovim Config with support for good highlighting of embedded templates in JS and TS, using:
See the Contributing guide for details.
This project is licensed under the MIT License.
FAQs
Tooling support for gjs and gts component authoring
The npm package ember-template-imports receives a total of 55,941 weekly downloads. As such, ember-template-imports popularity was classified as popular.
We found that ember-template-imports demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 9 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.
Security News
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
Security News
The Socket Research team breaks down a malicious npm package targeting the legitimate DOMPurify library. It uses obfuscated code to hide that it is exfiltrating browser and crypto wallet data.