Skip to content

Commit 66463f2

Browse files
author
Jen Weber
authored
New Templates intro (ember-learn#477)
* Rough draft of new Templates intro * update helper to buildHelper * lowercase Template --> template * the compiler is your friend * one template to one hundred templates * correct route lifecycle to components, add ember generate command * apply feedback * fix links, more linting, code block spacing
1 parent b384c91 commit 66463f2

File tree

1 file changed

+173
-43
lines changed

1 file changed

+173
-43
lines changed
Lines changed: 173 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,215 @@
1-
Ember uses a templating language based on [Handlebars templating library](http://www.handlebarsjs.com) to power your app's user interface.
2-
Ember templates contain static HTML and dynamic content inside Handlebars expressions, which are invoked with double curly braces: `{{}}`.
1+
Templates are the home for what the user sees, like forms, buttons, links, and headings.
32

3+
In this section of the Guides, you will learn about where to write HTML markup, plus how to add interaction, dynamically changing content, styling, and more.
4+
If you want to learn in a step-by-step way, you should begin your journey in the [Tutorial](../../tutorial/ember-cli/) instead.
45

5-
### Displaying Properties
6+
## Writing plain HTML
67

7-
Templates are backed with a context. A context is an object from which
8-
Handlebars expressions read their properties. In Ember this is often a component. For templates rendered by a route (like `application.hbs`), the context is a controller.
8+
Ember templates have some superpowers, but let's start with regular HTML.
9+
For any file in an Ember app that has an extension ending in `.hbs`, you can write HTML markup in it as if it was an `.html` file.
10+
HTML is the language that browsers understand for laying out content on a web page.
11+
`.hbs` stands for Handlebars, the name of a tool that lets you write more than just HTML in your templates.
912

10-
For example, this `application.hbs` template will render a first and last name:
13+
For example, every Ember app has a file called `application.hbs`.
14+
You can write regular HTML markup there or in any other `hbs` file:
1115

12-
```handlebars {data-filename=app/templates/application.hbs}
13-
Hello, <strong>{{this.firstName}} {{this.lastName}}</strong>!
16+
```handlebars {data-filename=app/templates/application.hbs data-update=false}
17+
<h1>Starting simple</h1>
18+
<p>
19+
This is regular html markup inside an hbs file
20+
</p>
1421
```
1522

16-
The `firstName` and `lastName` properties are read from the
17-
context (the application controller in this case), and rendered inside the
18-
`<strong>` HTML tag.
23+
When you start an app with `ember serve`, the compiler may help you catch some errors, such as forgetting to close a tag or missing a quotation mark.
24+
Reading the error message on the page or in your browser's developer console will get you back on track.
25+
26+
## Types of templates
27+
28+
There are two main types of templates: Route templates and Component templates.
29+
30+
A Route template determines what is shown when someone visits a particular URL, like `https://guides.emberjs.com/some-route`.
31+
A Component template has bits of content that can be reused in multiple places throughout the app, like buttons or forms.
32+
33+
If you look at an existing app, you will see templates in many different places in the app folder structure!
34+
This is to help the app stay organized as it grows from one template to _one hundred_ templates.
35+
The best way to tell if a template is part of a Route or Component is to look at the file path.
36+
37+
## Making new templates
38+
39+
New templates should be made using [Ember CLI](https://cli.emberjs.com) commands.
40+
The CLI helps ensure that the new files go in the right place in the app folder structure, and that they follow the essential file naming conventions.
41+
42+
For example, either of these commands will generate `.hbs` template files (and other things!) in your app:
43+
44+
```sh
45+
ember generate component my-component-name
46+
ember generate route my-route-name
47+
```
1948

20-
To provide a `firstName` and `lastName` to the above template, properties
21-
must be added to the application controller. If you are following along with
22-
an Ember CLI application, you may need to create this file:
49+
## Template restrictions
50+
51+
A typical, modern web app is made of dozens of files that have to all be combined together into something the browser can understand.
52+
Ember does this work for you with zero configuration, but as a result, there are some rules to follow when it comes to adding assets into your HTML.
53+
54+
You cannot use script tags directly within a template, and should use [actions](../actions/) or [Component Lifecycle Hooks](../../components/the-component-lifecycle/) to make your app responsive to user interactions and new data.
55+
If you are working with a non-Ember JavaScript library and need to use a `js` file from it, see the Guide section [Addons and Dependencies](../../addons-and-dependencies/managing-dependencies/).
56+
57+
You should not add links to your own local CSS files within the `hbs` file.
58+
Style rules should go in the `app/styles` directory instead.
59+
`app/styles/app.css` is included in your app's build by default.
60+
For CSS files within the styles directory, you can create multiple stylesheets and use regular CSS APIs like `import` to link them together.
61+
If you want to incorporate CSS from an npm package or similar, see [Addons and Dependencies](../../addons-and-dependencies/managing-dependencies/) for instructions.
62+
To load styles through a CDN, read the next section below.
63+
64+
## What is `index.html` for?
65+
66+
If HTML markup goes in `hbs` templates, what is `index.html` for?
67+
68+
The `index.html` file is the entry point for an app.
69+
It is not a template, but rather it is where all the templates, stylesheets, and JavaScript come together into something the browser can understand.
70+
71+
When you are first getting started in Ember, you will not need to make any changes to `index.html`.
72+
There's no need to add any links to other Ember app pages, stylesheets, or scripts in here by hand, since Ember's built-in tools do the work for you.
73+
74+
A common customization developers make to `index.html` is adding a link to a CDN that loads assets like fonts and stylesheets.
75+
Here's an example:
76+
77+
```html {data-filename=app/index.html}
78+
<link integrity="" rel="stylesheet" href="https://my-font-cdn/something.css">
79+
```
2380

24-
```javascript {data-filename=app/controllers/application.js}
25-
import Controller from '@ember/controller';
81+
## Understanding a Template's context
2682

27-
export default Controller.extend({
83+
A template only has access to the data it has been given.
84+
This is referred to as the template's "context."
85+
For example, to display a property inside a Component's template, it should be defined in the Component's JavaScript file:
86+
87+
```javascript {data-filename=app/components/my-component.js}
88+
import Component from '@ember/component';
89+
90+
export default Component.extend({
2891
firstName: 'Trek',
29-
lastName: 'Glowacki'
92+
lastName: 'Glowacki',
93+
favoriteFramework: 'Ember'
3094
});
3195
```
3296

33-
The above template and controller render as the following HTML:
97+
Properties like `firstName` can be used in the template
98+
by putting them inside of curly braces, plus the word
99+
`this`:
100+
101+
```handlebars {data-filename=app/templates/application.hbs}
102+
Hello, <strong>{{this.firstName}} {{this.lastName}}</strong>!
103+
```
104+
105+
Together, these render with the following HTML:
34106

35107
```html
36108
Hello, <strong>Trek Glowacki</strong>!
37109
```
38110

39-
Remember that `{{this.firstName}}` and `{{this.lastName}}` are bound data. That means
40-
if the value of one of those properties changes, the DOM will be updated
41-
automatically.
111+
## Things you might see in a template
112+
113+
A lot more than just HTML markup can go in templates.
114+
In the other pages of this guide, we will cover the features one at a time.
115+
In general, special Ember functionality will appear inside curly braces, like this: `{{example}}`.
116+
Here are a few examples of Ember Handlebars in action:
117+
118+
Route example:
119+
```handlebars {data-filename=app/templates/application.hbs data-update=true}
120+
121+
<!-- outlet determines where a child route's content
122+
should render. Don't delete it until you know more
123+
about it! -->
124+
<div>
125+
{{outlet}}
126+
</div>
127+
128+
<!-- One way to use a component within a template -->
129+
<MyComponent />
130+
131+
{{! Example of a comment that will be invisible, even
132+
if it contains things in {{curlyBraces}} }}
133+
134+
```
135+
136+
Component example:
137+
138+
```handlebars {data-filename=app/components/templates/my-component.hbs data-update=true}
139+
<!-- A property that is defined in a component's
140+
JavaScript file -->
141+
{{this.numberOfSquirrels}}
142+
143+
<!-- Some data passed down from a parent component
144+
or controller -->
145+
{{weatherStatus}}
146+
147+
<!-- This button uses Ember Actions to make it interactive.
148+
A method named `plantATree` is called when the button is
149+
clicked. `plantATree` comes from the JavaScript file
150+
associated with the template, like a Component or
151+
Controller -->
152+
<button onclick={{action 'plantATree'}}>
153+
More trees!
154+
<button>
155+
156+
<!-- Here's an example of template logic in action.
157+
If the `this.skyIsBlue` property is `true`, the text
158+
inside will be shown -->
159+
{{#if this.skyIsBlue}}
160+
If the skyIsBlue property is true, show this message
161+
{{/if}}
162+
163+
<!-- You can pass a whole block of markup and handlebars
164+
content from one component to another. yield is where
165+
the block shows up when the page is rendered -->
166+
{{yield}}
167+
```
168+
169+
Lastly, it's important to know that arguments can be passed from one Component to another through templates:
42170

43-
As an application grows in size, it will have many templates backed by
44-
controllers and components.
171+
```handlebars {data-filename=app/templates/some-other-component.hbs}
172+
<MyComponent @favoriteFramework=this.favoriteFramework />
173+
```
45174

46-
### Helpers
175+
To pass in arguments associated with a Route, define the property from within a Controller. Learn more about passing data between templates [here](../../components/passing-properties-to-a-component).
47176

48-
Ember Helpers are functions that can compute values and can be used in any template.
177+
## Helper functions
49178

50-
Ember gives you the ability to [write your own helpers](../writing-helpers/), to bring a minimum of logic into Ember templating.
179+
Ember Helpers are a way to use JavaScript logic in your templates.
180+
For example, you could write a Helper function that capitalizes a word, does some math, converts a currency, or more.
181+
A Helper takes in `parameters`, which is an array of the values passed into the function, and should return a value.
182+
Ember gives you the ability to [write your own helpers](../writing-helpers/), and comes with some [helpers built-in](../built-in-helpers).
51183

52-
For example, let's say you would like the ability to add a few numbers together, without needing to define a computed property everywhere you would like to do so.
184+
For example, let's say you would like the ability to add two numbers together.
185+
Define a function in `app/helpers/sum.js` to create a `sum` helper:
53186

54187
```javascript {data-filename=app/helpers/sum.js}
55-
import { helper } from '@ember/component/helper';
188+
import { helper as buildHelper } from '@ember/component/helper';
56189

57190
export function sum(params) {
58-
return params.reduce((a, b) => {
59-
return a + b;
60-
});
191+
return params[0] + params[1]
61192
};
62193

63-
export default helper(sum);
194+
export const helper = buildHelper(sum);
64195
```
65196

66-
The above code will allow you invoke the `sum()` function as a `{{sum}}` handlebars "helper" in your templates:
197+
Now you can use the `sum()` function as `{{sum}}` in your templates:
67198

68199
```handlebars {data-filename=app/templates/application.hbs}
69-
<p>Total: {{sum 1 2 3}}</p>
200+
<p>Total: {{sum 1 2}}</p>
70201
```
71202

72-
This helper will output a value of `6`.
203+
The user will see a value of `3` rendered in the template!
73204

74205
Ember ships with several built-in helpers, which you will learn more about in the following guides.
75206

76-
#### Nested Helpers
77-
78-
Helpers have the ability to be nested within other helper invocations and also component invocations.
79-
80-
This gives you the flexibility to compute a value _before_ it is passed in as an argument or an attribute of another.
207+
### Nested Helpers
81208

82-
It is not possible to nest curly braces `{{}}`, so the correct way to nest a helper is by using parentheses `()`:
209+
Sometimes, you might see helpers used inside of some parentheses, `()`.
210+
It means that a Helper is being used inside of another Helper or Component.
211+
This is referred to as a "nested" Helper.
212+
Parentheses must be used because curly braces `{{}}` cannot be nested.
83213

84214
```handlebars {data-filename=app/templates/application.hbs}
85215
{{sum (multiply 2 4) 2}}
@@ -91,4 +221,4 @@ Thus, the output of these combined helpers is `10`.
91221

92222
As you move forward with these template guides, keep in mind that a helper can be used anywhere a normal value can be used.
93223

94-
Thus, many of Ember's built-in helpers (as well as your custom helpers) can be used in nested form.
224+
Many of Ember's built-in helpers (as well as your custom helpers) can be used in nested form.

0 commit comments

Comments
 (0)