-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy path03-templates.md.erb
executable file
·230 lines (157 loc) · 15.2 KB
/
03-templates.md.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
---
title: Шаблони
slug: templates
date: 0003/01/01
number: 3
contents: Ознайомитесь з мовою шаблонів Meteor, Spacebars.|Створите ваших перших трьох шаблонів.|Вивчите роботу менеджерів Meteor.|Ознайомитесь із статичним прототипуванням.
paragraphs: 44
---
Щоб полегшити розробку в Meteor, ми будемо використовувати outside-in підхід. Інакше кажучи, ми створимо звичайний HTML/JavaScript шаблон, а потім підключимо його до нашого додатку.
Це означає, що у цьому розділі ми розглянемо лише те, що відбувається в директорії `/client`.
Ми створюємо новий файл з назвою `main.html` у директорії `/client` з додаванням наступного коду:
~~~html
<head>
<title>Microscope</title>
</head>
<body>
<div class="container">
<header class="navbar">
<div class="navbar-inner">
<a class="brand" href="/">Microscope</a>
</div>
</header>
<div id="main" class="row-fluid">
{{> postsList}}
</div>
</div>
</body>
~~~
<%= caption "client/main.html" %>
Це буде наш головний шаблон для додатка. Як ви помітили, це звичайний HTML, за винятком тегу `{{> postsList}}`, який є точкою входу шаблону `postsList` , який ми скоро побачимо. Тепер давайте створимо ще пару шаблонів.
### Шаблони в Meteor
По суті, соціально-новинний сайт складається з повідомлень, організованих у вигляді списку. Там само і ми організуємо наші шаблони.
Давайте створимо директорію `/views` всередині `/client`. Туди ми викладемо усі наші шаблони. Для підтримання порядку ми також створимо директорію `/posts` всередині `/views` для зберігання постів.
<% note do %>
### Пошук файлів
Meteor чудово шукає. Немає значення куди ви поклали свій код в директорії `/client`, Meteor його знайде та опрацює. Це означає, що вам ніколи не буде потрібно прописувати шляхи до JavaScript або CSS файлів вручну.
Також це означає, що ви можете покласти всі ваші файли в одну директорію або ж увесь код в одному файлі. Але оскільки у будь-якому випадку Meteor збере усі файли в один, то було б краще тримати файли у порядку та структурувати їх.
<% end %>
Отож, створимо наш другий шаблон. В директорії `client/views/posts` створимо файл `posts_list.html`:
~~~html
<template name="postsList">
<div class="posts">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
</template>
~~~
<%= caption "client/views/posts/posts_list.html" %>
І файл `post_item.html`:
~~~html
<template name="postItem">
<div class="post">
<div class="post-content">
<h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
</div>
</div>
</template>
~~~
<%= caption "client/views/posts/post_item.html" %>
Зауважте, що `name="postsList"` – атрибут елемента шаблону. Це використовується для того, щоб Meteor стежив за тим, який шаблон використовується.
Настав час познайомитись з шаблонізатором, який використовується у фреймворку – Spacebars. Spacebars це простий HTML з додаванням трьох речей: *partials*, *expressions* і *block helpers*.
*Partials* – використовує `{{> templateName}}` синтаксис і просто повідомляє Meteor, щоб він замінив цей тег шаблоном з тим же ім'ям (у нашому випадку це `postItem`).
*Expressions* такі як `{{title}}` викликають властивість поточного об'єкта або ж повертають значення, яке визначено в поточному менеджері шаблонів (докладніше про це пізніше).
І нарешті *block helpers* – це спеціальні теги, такі як: `{{#each}}…{{/each}}` або `{{#if}}…{{/if}}`, які контролюють стан шаблону.
<% note do %>
### Йдемо далі
Ви можете перейти на [документацію Spacebars](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md), якщо хочете дізнатися більше про Spacebars.
<% end %>
Озброївшись цими знаннями, ми можемо легко зрозуміти, що тут відбувається.
По-перше, у шаблоні `postsList` ми виводимо об’єкт `posts` за допомогою `{{#each}}…{{/each}}`. Для кожної ітерації ми включаємо шаблон `postItem`.
Звідки береться цей об’єкт `posts`? Хороше питання. Насправді це шаблон-помічник (template helper), ми визначимо його пізніше, після того, як розглянемо менеджери шаблону.
Шаблон `postItem` доволі простий. Він використовує лише три теги: `{{url}}` і `{{title}}`, які повертають властивості документа, і `{{domain}}`, який викликає шаблона-помічника.
У цьому розділі ми вже не раз зверталися до виразу "template helper", не пояснюючи його функцій. Але для того, щоб виправити це, ми повинні спочатку поговорити про менеджерів.
### Template Managers (менеджери шаблонів)
До цього часу ми мали справу з Spacebars, який є звичайним HTML-кодом з додатковими тегами. На відміну від інших мов, таких як PHP (або навіть звичайних HTML-сторінок, які можуть містити JavaScript), Meteor розділяє шаблони від їхньої логіки, і ці шаблони не роблять нічого самі по собі.
Для того, щоб вдихнути життя в шаблон, нам потрібен **manager**. Ви можете думати про нього як про кухаря, який отримує сировину (ваші дані) і готує їх, перш ніж передати готову страву офіціантові (шаблону), який принесе його вам.
Іншими словами, у той час як роль шаблону обмежується відображенням або циклом з змінними, менеджер робить важку роботу з присвоєння значення кожної змінної.
<% note do %>
### Менеджери?
Коли ми запитали у розробників Meteor, що вони мають на увазі під словосполученням "template managers", одна половина з них відповіла "контролери", а інша – "це ті файли, куди я поклав свій JavaScript код".
Насправді ж менеджери не є контролерами (принаймні не в сенсі MVC контролерів), проте "це ті файли, куди я поклав свій JavaScript код" також не дуже переконливе визначення, тож ми відкинули обидва варіанти.
Оскільки нам потрібно було якось це назвати, ми придумали термін "менеджер" - підходяще слово, у якого немає безлічі інших значень у веб-розробці.
<% end %>
Для спрощення ми будемо використовувати найменування менеджерів після шаблону за винятком файлів з розширенням **.js** Тож давайте створимо прямо зараз файл `posts_list.js` у директорії `/client/views/posts` і почнемо створення нашого першого менеджера:
~~~js
var postsData = [
{
title: 'Introducing Telescope',
author: 'Sacha Greif',
url: 'http://sachagreif.com/introducing-telescope/'
},
{
title: 'Meteor',
author: 'Tom Coleman',
url: 'http://meteor.com'
},
{
title: 'The Meteor Book',
author: 'Tom Coleman',
url: 'http://themeteorbook.com'
}
];
Template.postsList.helpers({
posts: postsData
});
~~~
<%= caption "client/views/posts/posts_list.js" %>
Якщо ви все зробили правильно, тепер ви повинні бачити щось схоже у вашому браузері:
<%= screenshot "3-1", "Our first templates with static data" %>
<%= commit "3-1", "Added basic posts list template and static data." %>
Тут ми робимо дві речі. По-перше, встановлюємо макет прототипу даних у масиві `postsData`. Ці дані, як правило, беруться з бази даних, але так як ми поки не знаємо, як працювати з базою (потерпіть до наступного розділу), то ми поки будемо казати що використовуємо звичайні статичні дані.
По-друге, ми використовуємо Meteor-функцію `Template.myTemplate.helpers()`, щоб визначити шаблона-помічника `posts`, який просто лише повертає наш масив `postsData`.
Визначення шаблона-помічника `posts означає, що тепер від є доступним у нашому шаблоні:
~~~html
<template name="postsList">
<div class="posts">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
</template>
~~~
<%= caption "client/views/posts/posts_list.html" %>
Тож наш шаблон тепер може перебирати масив `postsData` і надсилати кожен його об’єкт замість тегу в шаблоні `postItem`.
### Значення "this"
Тепер створимо менеджер `post_item.js`:
~~~js
Template.postItem.helpers({
domain: function() {
var a = document.createElement('a');
a.href = this.url;
return a.hostname;
}
});
~~~
<%= caption "client/views/posts/post_item.js" %>
<%= commit "3-2", "Setup a `domain` helper on the `postItem`." %>
Цього разу наш шаблон-помічник `domain` є не масивом, а анонімною функцією. Ця модель є більш поширеною (кориснішою) у порівнянні з нашим попереднім прикладом, де ми використовували масив замість бази даних.
<%= screenshot "3-2", "Displaying domains for each links." %>
Шаблон-помічник `domain` бере URL і повертає домен, використовуючи твори магії JavaScript. Але де ж нам спочатку взяти url
Для відповіді на це запитання нам потрібно повернутись до нашого шаблону `posts_list.html`. Блок-помічник `{{#each}}` не лише перебирає наш масив, але також **встановлює значення `this` всередині блоку** до повторного блоку.
Це означає, що між тегами `{{#each}}` кожен пост позначається як `this` і це успішно поширюється на усі шляхи, які підключені всередині менеджера (`post_item.js`).
Тепер ми розуміємо, чому `this.url` повертає поточний пост URL. Більше того, якщо ми використовуємо `{{title}}` та `{{url}}` всередині шаблону `post_item.html`l, Meteor знає, що ми маємо на увазі `this.title` та `this.url` і повертає нам коректні значення.
<% note do %>
### Магія JavaScript
Хоча це не є специфікою Meteor, тут швидке пояснення вищесказаної "магії JavaScript". По-перше, ми створюємо порожній елемент HTML (`a`) і зберігаємо його в пам'яті.
Потім ми установлюємо його `href` атрибут, щоб він був рівним поточного поста URL (як ви тільки що помітили, він є об'єктом шаблону-помічника і викликається через `this`).
Насамкінець, ми скористаємося властивістю `hostname` елемента `a`, щоб отримати посилання тільки на домен, без решти частини URL.
<% end %>
Якщо ви зробили вірно, то ви повинні побачити в браузері список повідомлень. Цей список є всього лише статичними даними, тож ми поки не можемо використовувати усі прекрасні можливості в режимі реального часу, які надає нам Meteor. Ми покажемо вам, як це виправити у наступному розділі!
<% note do %>
### Гаряче Оновлення Коду
Ви могли помітити, що вам навіть не треба власноруч оновлювати сторінку у браузері після кожного внесення правок у код.
Це тому що Meteor відстежує всі зміни у файлах в каталозі вашого проекту і автоматично оновлює сторінку, якщо виявить зміни хоч в одному з них.
Гаряче оновлення коду в Метеор влаштовано досить розумно, навіть зберігаючи стан вашого застосування між двома оновленнями!
<% end %>