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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
|
---
title: KumaScript
slug: MDN/Tools/KumaScript
tags:
- Guide
- Kuma
- KumaScript
- MDN Meta
- NeedsContent
- Site-wide
- ガイド
- ツール
translation_of: MDN/Tools/KumaScript
---
<div>{{MDNSidebar}}</div>
<p><span class="seoSummary">MDN を動かしている <a href="/ja/docs/MDN/Yari">Yari</a> プラットフォームでは、コンテンツの特定の側面を自動化するために、 <a href="https://github.com/mdn/yari/tree/master/kumascript">KumaScript</a> と呼ばれる古くからのテンプレート/マクロシステムがまだ利用可能です。</span>このシステムの使用をいつか中止したいと考えていますが、それまでは MDN はこのシステムに依存しています。この記事では、 KumaScript の使用に関する基本的な情報を提供します。</p>
<h3 id="What_is_KumaScript">KumaScript とは</h3>
<ul>
<li>文書間で繰り返し現れるコンテンツの再利用やローカライズを行う手段 (互換性のラベル、セクションナビゲーション、警告バナーなど)。</li>
<li>他の文書からコンテンツを引用して文書を構築する手段。</li>
<li>他のウェブサイトやサービス (Bugzilla など) からコンテンツを取得して含める手段。</li>
</ul>
<h3 id="What_KumaScript_is_not">KumaScript が持たないもの</h3>
<p>KumaScript は次のことは行いません。</p>
<ul>
<li>フォーム送信を受け付けるような対話型スクリプトには対応していません。</li>
<li>データベースやファイルにアクセスしたり、情報を永続的に格納したりする仕組みはありません。</li>
<li>ログイン中のユーザー情報に基づくサイトのパーソナライズには対応していません。</li>
<li>ユーザー情報にアクセスすることはできず、コンテンツとページのメタデータにのみアクセス可能です。</li>
</ul>
<h2 id="Basics">基本</h2>
<p>KumaScript は MDN で<a href="https://github.com/mde/ejs">埋め込み JavaScript テンプレート</a>に利用されています。これらのテンプレートは MDN の筆者ならば誰でも文書内で、マクロを使用して呼び出すことができます。</p>
<p>KumaScript のスクリプトは<em>テンプレート</em>であり、それぞれのテンプレートは Github のKumaScript リポジトリーの <a href="https://github.com/mdn/yari/tree/master/kumascript/macros">macros ディレクトリー</a>に格納されているファイルです。テンプレートは以下のようなものです。</p>
<pre class="brush: js no-line-numbers"><% for (let i = 0; i < $0; i++) { %>
Hello #<%= i %>
<% } %></pre>
<p>テンプレートの呼び出しには<em>マクロ</em>を使用します。上記のテンプレートを呼び出すと、次のようになります (macros ディレクトリに <code>hello.ejs</code> というファイル名で保存されている場合)。</p>
<pre class="brush: none no-line-numbers">\{{hello(3)}}</pre>
<p>マクロの出力は以下のようなものです。</p>
<pre class="brush: html no-line-numbers">Hello #0
Hello #1
Hello #2</pre>
<h3 id="Macro_syntax">マクロの構文</h3>
<p>マクロの呼び出しは、次のような一般的な形を取ります。</p>
<pre class="brush: none no-line-numbers">\{{templateName("arg0", "arg1", ..., "argN")}}</pre>
<p>マクロの構文は、以下の規則に基づいて構成されます。</p>
<ul>
<li>マクロの先頭と末尾は <code>\{{</code> と <code>\}}</code> の文字です。</li>
<li>このマクロの最初の部分は、テンプレートの名前です。この名前の小文字の値は、 macros ディレクトリの下にあるファイル名のいずれかの小文字の値と一致する必要があります。</li>
<li>テンプレートは引数を受け付けます。括弧内にカンマ区切りで複数の引数を記述することができます。</li>
<li>数値以外の引数は引用符で囲む必要があります。数値は囲む必要はありません。</li>
</ul>
<h4 id="Using_JSON_as_a_macro_parameter">マクロの引数に JSON を用いる</h4>
<p>半実験的な機能 (動作保証なし) として、以下のように引数が一つだけの場合は、引数に JSON オブジェクトを指定できます。</p>
<pre class="brush: none no-line-numbers">\{{templateName({ "Alpha": "one", "Beta": ["a", "b", "c"], "Foo": "https:\/\/mozilla.org\/" })}}</pre>
<p>このマクロからのデータは、テンプレートコード内で <code class="language-javascript">$0</code> 引数のオブジェクトとして利用できます (例えば、 <code>$0.Alpha</code>, <code>$0.Beta</code>, <code>$0.Foo</code>)。これにより、引数の単純なリストで実現することが難しい又は不可能な複雑なデータ構造を、マクロ引数で表すことができます。</p>
<p>なお、この引数の形はとても繊細です。 — 正確に <a href="http://json.org/">JSON の構文</a>に従っていなければならず、間違いを犯しやすいエスケープ文字の要件が求められます (例えば、すべてのスラッシュをエスケープするなど)。疑わしい場合は、 <a href="http://jsonlint.com/">JSON をバリデーターに掛けてみてください</a>。</p>
<h4 id="How_to_write_in_text">"\{{"を記述する方法</h4>
<p>"<code>\{{</code>" という文字の並びはマクロの開始を示すため、実際にページ内で "<code>\{{</code>" および "<code>}}</code>" を使用したい場合は問題になります。おそらく <code>DocumentParsingError</code> メッセージが発生するでしょう。</p>
<p>この場合、 <code>\\{</code> のように最初の中括弧をバックスラッシュでエスケープすることができます。</p>
<h3 id="Template_Syntax">テンプレートの構文</h3>
<p>それぞれの KumaScript テンプレートは、 <a href="https://github.com/mdn/yari/tree/master/kumascript/macros">KumaScript の macros ディレクトリ</a>に格納されているファイルです。これらのファイルは GitHub 上の何らかのオープンソースプロジェクトのファイルとして作成したり編集したりします。</p>
<p>KumaScript テンプレートは、いくつかの簡単な規則で、<a href="https://ejs.co">組み込み JavaScript テンプレートエンジン</a>によって処理されます。</p>
<ul>
<li>テンプレート内では、マクロから渡された引数は <code>$0</code>, <code>$1</code>, <code>$2</code>, などのような変数として利用できます。引数のリスト全体は、テンプレート内で変数 <code>arguments</code> として利用できます。</li>
<li>多くのテキストは出力として扱われ、出力ストリームに入ります。</li>
<li>JavaScript の変数や式は、以下のブロックを用いて出力ストリームに挿入可能です。
<ul>
<li><code class="language-ejs"><%= expr %></code> — 出力される前に HTML エスケープされた JavaScript の式の値 (<code><</code> および <code>></code> は <code>&lt;</code> および <code>&gt;</code> となる)</li>
<li><code class="language-ejs"><%- expr %></code> — エスケープされない JavaScript の式の値 (マークアップを動的に構築したり、マークアップを含むことができる他のテンプレートの結果に使用してください)</li>
<li>このブロック直下にセミコロンを含めるとエラーとなる。</li>
</ul>
</li>
<li><code class="language-ejs"><%</code> と <code>%></code> の間は JavaScript として解釈される。すなわち、ループ、条件文、関数などを含めることが可能。</li>
<li><code class="language-ejs"><% %></code> ブロック内は出力ストリームに含まれない。ブロック内の変数などをブロック外で使用する場合は、以下のように <code><%= %></code> を用いる。
<pre class="brush: js"><% for (var i = 0; i < $0; i++) { %>
Hello #<%= i %>
<% } %></pre>
<p>JavaScriptのコードは <code class="language-ejs"><% ... %></code> に含まれており、 <code class="language-ejs">%> ... <%</code> の間に現れるものは出力されることに注意してください。 JS の <code>for</code> ループは、1つ目の <code class="language-ejs"><% %></code> ブロックで始まり、出力モードに移行して、2つ目の <code class="language-ejs"><% %></code> の JS ブロックで終わらせることができます。</p>
</li>
<li>EJS の構文の詳細については、<a href="https://ejs.co">上流モジュールのドキュメント</a>でご確認ください。</li>
</ul>
<h2 id="Advanced_Features">高度な機能</h2>
<p>KumaScript には前章までに紹介したもの以外に、高度な機能もあります。</p>
<h3 id="Environment_variables">環境変数</h3>
<p>Wiki が KumaScript サービスを呼び出す際には、KumaScript がテンプレートに変数として利用できるようにする、現在の文書に関するいくつかのコンテキストを渡します。</p>
<dl>
<dt><code>env.path</code></dt>
<dd>現在の MDN 文書へのパス</dd>
<dt><code>env.url</code></dt>
<dd>現在の MDN 文書への絶対 URL</dd>
<dt><code>env.id</code></dt>
<dd>現在の MDN 文書のユニーク ID</dd>
<dt><code>env.files</code></dt>
<dd>現在の MDN 文書に添付されているファイルの配列で、配列内の各オブジェクトは、下記の {{ anch("File objects", "File オブジェクト") }}で説明されています。</dd>
<dt><code>env.review_tags</code></dt>
<dd>記事のレビュータグ配列 ("technical"、 "editorial"など。)</dd>
<dt><code>env.locale</code></dt>
<dd>現在の MDN 文書のロケール</dd>
<dt><code>env.title</code></dt>
<dd>現在の MDN 文書のタイトル</dd>
<dt><code>env.slug</code></dt>
<dd>現在の MDN 文書の URL スラッグ</dd>
<dt><code>env.tags</code></dt>
<dd>現在の MDN 文書に付与されたタグの名称のリスト</dd>
<dt><code>env.modified</code></dt>
<dd>現在の MDN 文書の最終更新日を示すタイムスタンプ</dd>
<dt><code>env.cache_control</code></dt>
<dd><code>Cache-Control</code> ヘッダーで、現在の MDN 文書がリクエストされた際に送信されたものであり、キャッシュを無効にするかどうかの判断をするのに便利です</dd>
</dl>
<h4 id="File_objects">File オブジェクト</h4>
<p>個々の file オブジェクトは以下の様なフィールドを持ちます。</p>
<dl>
<dt><code>title</code></dt>
<dd>添付ファイルのタイトル</dd>
<dt><code>description</code></dt>
<dd>現行版の添付ファイルに関する説明</dd>
<dt><code>filename</code></dt>
<dd>添付ファイルのファイル名</dd>
<dt><code>size</code></dt>
<dd>添付ファイルのサイズ(※単位 = bytes )</dd>
<dt><code>author</code></dt>
<dd>添付ファイルをアップロードした人のユーザ名</dd>
<dt><code>mime</code></dt>
<dd>添付ファイルの MIME type</dd>
<dt><code>url</code></dt>
<dd>添付ファイルの URL</dd>
</dl>
<h4 id="Working_with_tag_lists">タグリストでの作業</h4>
<p>変数 <code>env.tags</code> および <code>env.review_tags</code> がタグの配列を返します。これらを使って作業するには、もちろんたくさんの方法がありますが、ここではいくつかを提案します。</p>
<h5 id="Looking_to_see_if_a_specific_tag_is_set">特定のタグが設定されているかどうかの確認</h5>
<p>ページに特定のタグが存在するかどうかを調べるには、このようにします。</p>
<pre class="brush: js">if (env.tags.indexOf("tag") !== −1) {
// The page has the tag "tag"
}
</pre>
<h5 id="Iterating_over_all_the_tags_on_a_page">ページのすべてのタグを反復処理</h5>
<p>次のようにして、ページのすべてのタグを反復処理するようにすることもできます。</p>
<pre class="brush: js">env.tag.forEach(function(tag) {
// do whatever you need to do, such as:
if (tag.indexOf("a") === 0) {
// this tag starts with "a" - woohoo!
}
});</pre>
<h3 id="APIs_and_Modules">API とモジュール</h3>
<p>KumaScript は、 KumaScript マクロ用にいくつかの組み込みメソッドと API を提供します。マクロは、 <code>module.exports</code> を使用して新しい API メソッドをエクスポートすることもできます。</p>
<h4 id="Built-in_methods">組み込みメソッド</h4>
<p>この文書は手動で管理されているので、コードとともに古くなってしまう可能性があります。この点を考慮して、<a class="link-https" href="https://github.com/mdn/yari/tree/master/kumascript/src/api">KumaScript のソースにある組み込み API の最新状態を常にチェックしましょう</a>。しかし、ここではテンプレートに公開されている便利なメソッドの一部を紹介します。</p>
<dl>
<dt><code class="language-javascript">md5(string)</code></dt>
<dd>与えられた文字列の MD5 ダイジェストを16 進で返します。</dd>
<dt><code class="language-javascript">template("name", ["arg0", "arg1", ..., "argN"])</code></dt>
<dd>
<p>指定されたテンプレートを、指定された引数のリストを使って実行し、その結果を返します。</p>
<p>例: <code class="language-javascript"><%- template("warning", ["foo", "bar", "baz"]) %></code>.</p>
<p><code>DOMxRef</code> マクロを使用した例: <code class="language-javascript"><%- template("DOMxRef", ["Event.bubbles", "bubbles"]) %></code>.</p>
<p>これは JavaScript の関数です。ですから、引数が $2 のような引数の変数である場合は、引用符で囲まないでください。 <code class="language-javascript"><%- template("warning", [$1, $2, "baz"]) %></code> のようにします。コードのブロック内から他のテンプレートを呼び出す必要がある場合は、 <code><%</code> ... <code>%></code> を使用しないでください。例えば <code class="language-javascript">myvar = "<li>" + template("LXRSearch", ["ident", "i", $1]) + "</li>";</code> のようにします。</p>
</dd>
<dt><code class="language-javascript">require(name)</code></dt>
<dd>別なテンプレートをモジュールとして読み込みます。すべての出力は無視されます。テンプレート内で <code class="language-javascript">module.exports</code> に代入されたものをすべて返します。</dd>
<dd>テンプレート内で、 <code class="language-javascript"><% const my_module = require('MyModule'); %></code> のように使用されます。</dd>
<dt><code class="language-javascript">cacheFn(key, timeout, function_to_cache)</code></dt>
<dd>指定されたキーとキャッシュ生存時間を使用して、指定された関数の結果をキャッシュします。 <code>env.cache_control</code> の値を尊重し、ログイン中のユーザーが Shift を押しながら更新を押すことで送信される <code>no-cache</code> でキャッシュを無効化します。</dd>
<dt><code class="language-javascript">request</code></dt>
<dd>HTTP リクエストを作成するためのライブラリーである <a class="link-https" href="https://github.com/request/request"><code>request/request</code></a> にアクセスします。 KumaScript テンプレート内でこのモジュールを使用するにはあまり使い勝手が良くないので、簡単にするためにモジュール API の中でラップすると良いでしょう。</dd>
<dt><code class="language-javascript">log.debug(string)</code></dt>
<dd>ページ上のスクリプトログにデバッグメッセージを出力します (通常はエラーを表示する大きな赤いボックスです)。</dd>
</dl>
<h4 id="Built-in_API_modules">組込み API モジュール</h4>
<p>環境スクリプトによって自動的に読み込まれ、すべてのテンプレートで利用可能になる一連の組み込み API があます。 MDN が何年も前に依存していた古い DekiScript システムからいくつかの機能を提供しています。</p>
<p>これらは、テンプレート間で共通の変数やメソッドを共有するために使用されます。</p>
<ul>
<li><code>kuma.*</code> - <a href="https://github.com/mdn/kumascript/blob/master/src/api/kuma.js">Kuma</a></li>
<li><code>MDN.*</code> - <a href="https://github.com/mdn/kumascript/blob/master/src/api/mdn.js">MDN:Common</a></li>
<li><code>page.*</code> - <a href="https://github.com/mdn/kumascript/blob/master/src/api/page.js">DekiScript:Page</a></li>
<li><code>string.*</code> - <a href="https://github.com/mdn/kumascript/blob/master/src/api/string.js">DekiScript:String</a></li>
<li><code>uri.*</code> - <a class="link-https" href="https://github.com/mdn/kumascript/blob/master/src/api/uri.js">DekiScript:Uri</a></li>
<li><code>web.*</code> - <a class="link-https" href="https://github.com/mdn/kumascript/blob/master/src/api/web.js">DekiScript:Web</a></li>
<li><code>wiki.*</code> - <a class="link-https" href="https://github.com/mdn/kumascript/blob/master/src/api/wiki.js">DekiScript:Wiki</a></li>
</ul>
<p>他に利用可能な API には以下のようなものがあります。</p>
<dl>
<dt><code class="language-javascript">kuma.inspect(object)</code></dt>
<dd>任意の JS オブジェクトを文字列として出力します。 <code>log.debug()</code> と共に良く使用します。 <a href="https://nodejs.org/api/util.html#util_util_inspect_object_options">node.js の <code class="language-javascript">util.inspect()</code></a> も参照してください。</dd>
<dt><code class="language-javascript">kuma.htmlEscape(string)</code></dt>
<dd><code>&, <, >, "</code> の文字を <code>&amp, &lt;, &gt;, &quot;</code> にそれぞれエスケープします。</dd>
<dt><code class="language-javascript">kuma.url</code></dt>
<dd><a href="https://nodejs.org/api/url.html">node.js の <code>url</code> モジュール</a>も参照してください。</dd>
<dt><code class="language-javascript">kuma.fetchFeed(url)</code></dt>
<dd>RSS フィードを読み取り JS オブジェクトに解釈します。 <a href="https://github.com/mdn/kumascript/blob/master/macros/InsertFeedLinkList.ejs"><code>InsertFeedLinkList</code></a> も参照してください。</dd>
</dl>
<h4 id="Creating_modules">モジュールの作成</h4>
<p>組み込みの <code>require()</code> メソッドを使って、テンプレートをモジュールとして読み込み、テンプレート間で共通の変数やメソッドを共有することができます。モジュールはテンプレートの中で次のように定義できます。</p>
<pre class="brush: js"><%
module.exports = {
add: function (a, b) {
return a + b;
}
}
%></pre>
<p>このテンプレートが macros ディレクトリーに <code>MathLib.ejs</code> として保存されていたとすると、次のように別のテンプレートで使用することができます。</p>
<pre class="brush: js"><%
var math_lib = require("MathLib");
%>
The result of 2 + 2 = <%= math_lib.add(2, 2) %></pre>
<p>このテンプレートの出力は以下の様になるでしょう。</p>
<pre class="brush: html no-line-numbers">The result of 2 + 2 = 4</pre>
<h2 id="Tips_and_caveats">ヒントと注意点</h2>
<h3 id="Debugging">デバッグ</h3>
<p>デバッグ時に役立つヒントです。 <code>log.debug()</code> メソッドを使うと、テンプレートを実行しているページの上部にあるスクリプトメッセージ領域にテキストを出力することができます。ただし、これらのメッセージはすべてのユーザーが見ることができるため、デバッグが終わったら確実に削除する必要があります。これを使うには、次のようにしてください。</p>
<pre class="brush: js no-line-numbers"><%- log.debug("テキストはこちら"); %></pre>
<p>もちろん、役立つのであれば、スクリプトコードを使ってより複雑な出力を作ることもできます。</p>
<h3 id="Caching">キャッシュ</h3>
<p>KumaScript テンプレートは、パフォーマンスを向上させるために深くキャッシュされます。ほとんどの場合、これは頻繁に変更されないコンテンツを提供するのに適しています。しかし、ログインしたユーザーがスクリプトの問題に気づいたときに、ページを強制的に再生成するための 2 つのオプションがあります。</p>
<ul>
<li>ブラウザーで再読み込みしてください。これにより、 KumaScript は <code>Cache-Control: max-age=0</code> ヘッダーのリクエストを発行することで、現在のページのコンテンツのキャッシュを無効にします。</li>
<li>ブラウザーで Shift を押しながら再読み込みを実行してください。これにより <code>Cache-Control: no-cache</code> ヘッダー付きのリクエストを発行することで、 KumaScript は、現在のページ、および現在のページで使用されているテンプレートやコンテンツのキャッシュを無効にします。</li>
</ul>
<h2 id="Cookbook">クックブック</h2>
<p>このセクションでは、MDN で使用されるテンプレートの一般的なパターンの例をリストアップします。これには、古い DekiScript テンプレートと新しい KumaScript の同等品のサンプルがあります。</p>
<h3 id="Force_templates_used_on_a_page_to_be_reloaded">ページ上で使用されているテンプレートを強制的に再読み込みさせる</h3>
<p>繰り返しになりますが、ページで使用されているテンプレートを編集後に強制的に再読み込みさせるには、Shift を押しながら再読み込みします。再読み込みを使用するだけで、ページのコンテンツが再生成されますが、キャッシュされたテンプレートやインクルードされたコンテンツが使用されます。ページ自体のコンテンツ以外のキャッシュを無効にするには、 Shift を押しながらの再読み込みが必要です。</p>
<h3 id="Recovering_from_Unknown_Error">"Unknown Error" からの回復</h3>
<p>時々、ページ読込時に、次のようなスクリプティングメッセージが表示されることがあります。</p>
<pre class="brush: none no-line-numbers">Kumascript service failed unexpectedly: <class 'httplib.BadStatusLine'></pre>
<p>これはおそらく、 KumaScript サービスの一時的な障害です。ページを更新すると、このエラーは消えるかもしれません。それがうまくいかない場合は、Shift を押しながら再読み込みを試してみてください。何度か試してみてもエラーが消えない場合は、 Mozilla Developer Network に <a class="link-https" href="https://bugzilla.mozilla.org/enter_bug.cgi?product=mozilla.org&format=itrequest">IT バグを提出</a>して調査を依頼してください。</p>
<h3 id="Broken_wiki.languages_macros">Broken wiki.languages() マクロ</h3>
<p>いくつかのページで、以下の様なスクリプトエラーメッセージを見かける場合があるでしょう。</p>
<pre class="brush: none; no-line-numbers">Syntax error at line 436, column 461: Expected valid JSON object as the parameter of the preceding macro but...</pre>
<p>その様なページを編集状態にした場合、ページ下部に以下の様なマクロが見つかるかもしれません。</p>
<pre class="brush: none no-line-numbers">\{{ wiki.languages({ "zh-tw": "zh_tw/Core_JavaScript_1.5_教學/JavaScript_概要", ... }) }}</pre>
<p>この問題を解決するには、マクロを削除してください。または、情報を温存するために次のように両側の中括弧を HTML コメント <code><!-- --></code> で置き換えてください。</p>
<pre class="brush: html no-line-numbers"><!-- wiki.languages({ "zh-tw": "zh_tw/Core_JavaScript_1.5_教學/JavaScript_概要", ... }) --></pre>
<p>Kuma は様々な方法でローカライズに対応しているため、これらのマクロは実際にはもう必要ありません。しかし、ローカライズされたページ間の関係を再検討する必要がある場合に備えて、これらのマクロはそのまま残されています。残念ながら、マイグレーションではいくつかのマクロを正しく変換できなかったようです。</p>
<h3 id="Finding_the_Current_Pages_Language">ページの言語の取得</h3>
<p>KumaScript では、現在の文書のロケールは環境変数から取得することができます。</p>
<pre class="brush: js no-line-numbers">const lang = env.locale;</pre>
<p>変数 <code>env.locale</code> は信頼すべきものであり、すべての文書で定義されています。</p>
<h3 id="Reading_the_contents_of_a_page_attachment">ページの添付ファイルの内容の読み取り</h3>
<p>以下のように <code>mdn.getFileContent()</code> 関数を用いることで、添付ファイルの内容を読み取ることができます。</p>
<pre class="brush: js"><%
let contents = mdn.getFileContent(fileUrl);
// ... do stuff with the contents ...
%>
</pre>
<p>または</p>
<pre class="brush: js no-line-numbers"><%- mdn.getFileContent(fileObject); %>
</pre>
<p>つまり、読み込むファイルのURLを指定する場合と、ファイルオブジェクトとして指定する場合があります。あるページのファイルオブジェクトは、配列 <code>env.files</code> を通じてアクセスできます。ですから、例えば、記事に添付された最初のファイルの内容を埋め込むには、次のようにします。</p>
<pre class="brush: js no-line-numbers"><%- mdn.getFileContent(env.files[0]); %>
</pre>
<div class="notecard note">
<p><strong>注:</strong> テキスト以外のファイルのコンテンツをこの方法で埋め込もうとすると、生のコンテンツがテキストとして注入されてしまうので、おそらく避けた方がいいでしょう。これは、テキストの添付ファイルの内容にアクセスするためのものです。</p>
</div>
<p>ファイルが見つからない場合は、空の文字列が返されます。現在のところ、空のファイルと存在しないファイルの違いを見分ける方法はありません。しかし、もし空のファイルを wiki に置いているのであれば、それは間違っています。</p>
<h3 id="Localizing_template_content">テンプレートのローカライズ</h3>
<p>テンプレートは wiki ページのように翻訳されるわけではなく、 1 つのテンプレートをいくつものロケールで使用することになります。</p>
<p>そのため、現在の文書のロケールに合わせてコンテンツを出力する主な方法は、 <code>env.locale</code> の値に基づいています。これには様々な方法がありますが、従来の DekiScript テンプレートの変換にはいくつかのパターンがあります。</p>
<h4 id="Ifelse_blocks_in_KumaScript">If/else ブロックを用いる例</h4>
<p>これに相当する KumaScript では、以下のような単純な if/else ブロックで実現できます。</p>
<pre class="brush: js"><% if ("fr" == env.locale) { %>
<%- template("CSSRef") %> « <a href="/fr/docs/Référence_CSS/Extensions_Mozilla">Référence CSS: Extensions Mozilla</a>
<% } else if ("ja" == env.locale) { %>
<%- template("CSSRef") %> « <a href="/ja/docs/CSS_Reference/Mozilla_Extensions">CSS リファレンス: Mozilla 拡張仕様</a>
<% } else if ("pl" == env.locale) { %>
<%- template("CSSRef") %> « <a href="/pl/docs/Dokumentacja_CSS/Rozszerzenia_Mozilli">Dokumentacja CSS: Rozszerzenia Mozilli</a>
<% } else if ("de" == env.locale) { %>
<%- template("CSSRef") %> « <a href="/de/docs/CSS_Referenz/Mozilla_CSS_Erweiterungen">CSS Referenz: Mozilla Erweiterungen</a>
<% } else { %>
<%- template("CSSRef") %> « <a href="/en-US/docs/CSS_Reference/Mozilla_Extensions">CSS Reference: Mozilla Extensions</a>
<% } %></pre>
<p>どのテキストエディターがお気に入りであるかによりますが、ブラウザーベースのエディターからコピー&貼り付けして、一連の検索/置換正規表現を使ってこのパターンを攻略すれば、大体のことは解決できるでしょう。</p>
<p>私が愛用しているエディターは MacVim ですが、次の一連の正規表現を使えば、後は手動でちょっとしたクリーンアップをするだけで、大部分の作業が完了します。</p>
<pre class="brush: none">%s#<span#^M<span#g
%s#<span lang="\(.*\)" .*>#<% } else if ("\1" == env.locale) { %>#g
%s#<span class="script">template.CSSxRef(#<%- template("CSSxRef", [#
%s#)</span> </span>#]) %>
</pre>
<p>また、テンプレートごとにパターンが微妙に変わることもあります。そのため、移行スクリプトで自動的に処理することができなかったのだと思います。</p>
<h4 id="String_variables_and_switch">文字列値と switch</h4>
<p><code class="language-javascript">mdn.localString()</code> を使用すると、次のようにロケールに応じて異なる文字列が定義されます。</p>
<pre class="brush: js"><%
var s_title = mdn.localString({
"en-US": "Firefox for Developers",
"de": "Firefox für Entwickler",
"es": "Firefox para desarrolladores"
});
%>
<span class="title"><%= s_title %></span></pre>
<p>オブジェクトに適切なロケールが無い場合、 "en-US" の値が初期値として使用されます。</p>
|