Template Basics
Templates in Ember are JavaScript files with a <template> tag for regular HTML with a handful of instructions (based on Handlebars). File extensions are:
.gjs(Glimmer + JavaScript).gts(Glimmer + TypeScript)
INFO
Glimmer is Ember's rendering engine.
Here is a sample template:
<template>
...
</template>Many times a <template> is all the file needs, then it behaves like a superset of HTML.
INFO
When there is only a <template> tag present in a file, it is the default export:
export default <template>...</template>Tags
Tags work as they do in HTML and same white-space rules apply. Non-void elements can use self-closing tags.
<template>
<main>
Here be dragons
</main>
</template>Restrictions
There are a few restrictions on the HTML that you can put in an Ember template:
- Only valid HTML elements in a
<body>tag can be used - No
<script>tags
Variable Interpolation
To show the value of a variable in the template use the "Mustache" syntax (double curly braces).
const name = "world";
<template>
<h1>Hello {{name}}</h1>
</template>Element Attributes
Attributes in Ember templates work as they do in HTML.
<template>
<img
src="https://media.tenor.com/GAMYf3psisEAAAAd/hamster-spinning.gif"
alt="A hamster is spinning within a fallen wheel"
>
</template>Dynamic Attributes
Also you can use variables as attributes to make them dynamic.
const gifURL = 'https://media.tenor.com/GAMYf3psisEAAAAd/hamster-spinning.gif';
const description = 'A hamster is spinning within a fallen wheel';
<template>
<img src={{gifURL}} alt={{description}}>
</template>Special treatment is made for truthy/falsy values. They will make the attribute appear or not in the rendered template.
const welcomeHidden = false;
<template>
<div hidden={{welcomeHidden}}>
Weclome
</div>
</template>Functions
A template can call functions.
const name = "world";
const shout = (text) => text.toUpperCase();
<template>
<h1>Hello {{(shout name)}}</h1>
</template>We use wrapping ( ) to signify that that we are invoking a function with arguments. The ( ) are needed to disambiguate between rendering values, , and invoking functions: . However, when there are arguments passed, there is no longer an ambiguity, and the ( ) are no longer needed.
So you could write the above call to the function, shout, like this:
<h1>Hello {{shout name}}</h1>Nested Functions
Functions can be chained together, just like in other languages
const name = "world";
const shout = (text) => text.toUpperCase();
const reverse = (text) => text.split('').reverse().join('');
<template>
<h1>Hello {{reverse (shout name)}}</h1>
</template>Unlike JavaScript, Ember templates use Polish Notation or Prefix Notation which means that functions precede their arguments. This simple language allows templates to be transformed into lightweight JSON objects to save bytes during network transfer and time during the browser's parse and evaluation phases. For more information, see this announcement video.
Comments
You can use HTML comments, they will be rendered in the final output. Using Mustache comments suppresses them.
<template>
<!-- I am an HTML comment, I will be rendered -->
{{! I am a Handlebars comment, I will not be shown }}
</template>