現在のプランを確認
Suite Growth、Professional、Enterprise、またはEnterprise Plus
Support + Guide(すべてのプラン)

はじめに

ヘルプセンターのテーマは、編集可能なページテンプレートの集まりです。テンプレートとは、ヘルプセンター内の各種ページタイプのレイアウトを定義するものです。たとえば、ナレッジベースの記事用のテンプレートや、リクエストのリスト用のテンプレートなどがあります。

各テンプレートは、HTMLマークアップと、Handlebarsなどの式によって構成されます。これらは、テンプレート内で二重の波かっこで囲んで表されます。Handlebarsは、シンプルなテンプレート化エンジンです。これにより、設計時ではなく、レンダリング時にページ内にコンテンツを挿入したり、コンテンツを操作できるようになります。

ヘルプセンター内のテンプレート化言語はCurlybarsと呼ばれ、Handlebars言語の大部分を実装しています。このガイドでは、Curlybars言語を使用してヘルプセンターのページをカスタマイズする方法を説明します。

ヘルプセンターでは、ヘルパーと所定のプロパティを使用して、コンテンツをカスタマイズできます。プロパティには、すべてのヘルプセンターページ上で共有され使用されるものと、ページ固有のものがあります。

例

{{#each comments}}
  <li class="comment" id="{{comment_id}}">
    <div class="comment-avatar {{#if author.agent}} comment-avatar-agent {{/if}}">
      <img src="{{author.avatar_url}}" alt="Avatar" />
    </div>

    <div class="comment-container">
      <header class="comment-header">
        <strong class="comment-author">
          {{author.name}}
        </strong>
      </header>
    </div>
  </li>
{{/each}}

この例は、ページにコメントを残したユーザーのリストを生成します。eachヘルパーは、ページのcommentsプロパティ内のすべての値を反復処理します。各コメントについて、author.avatar_urlプロパティとauthor.nameプロパティの値がHTML内に挿入されます。

メモ:ヘルプセンターをカスタマイズする前に、Jake Bantzのサポートヒントの記事「Preventing poor Help Center load times by following templating best practices(テンプレートのベストプラクティスに従うことで、ヘルプセンターの読み込み時間を改善する)」をお読みください。

テンプレートの基本

このセクションでは、テンプレートの作成に必要な基本事項について説明します。詳細については、developer.zendesk.comで「Help Center Templates(ヘルプセンターのテンプレート)」を参照してください。

Curlybarsテンプレートは、そのままレンダリングされるverbatimテキストと、Curlybars式という2つの要素で構成されます。つまり、空のテンプレートも有効なテンプレートであり、テキストのみが含まれるテンプレートも有効なテンプレートです。以下は、有効なテンプレートの例です。

<h1>Article</h1>

<p>Some details on the article</p>

もちろん、ヘルプセンターテンプレートがverbatimテキストしかサポートしないとしたら、レンダリング時に十分なカスタマイズはできません。テンプレートのロジックを追加するには、Curlybars式が必要です。この式は、二重の波かっこ({{および}})で囲んで表します。

前述の例にテンプレートのロジックを追加するには、テンプレートを次のように編集します。

<h1>Article</h1>

<p>Some details on the article</p>

{{article.author.name}}

次のセクションでは、必要に応じてテンプレートに変更を加えるために、さまざまな式を記述する方法について説明します。

なお、波かっこのペアを別の波かっこのペアに入れ子にした場合、そのシンタックスは無効です。たとえば、以下のように記述することはできません。

<h1>Article</h1>

<p>Some details on the article</p>

{{ {{ ... }} }}

コメント

状況によって、レンダリングページに表示されないメモをテンプレート内に書いておくと便利な場合があります。Curlybarsでこれを行うには、{{! ... }}のように、開き波かっこの直後(スペース不要)に感嘆符を挿入してコメントを追加します。このシンタックスを使用して、以下の例のようにコードコメントを挿入できます。

{{!
  This template aims to
  show details of an article
}}

<h1>Article</h1>

<p>Some details on the article</p>

レンダリング時には、このページはブラウザに以下のように表示されます。

<h1>Article</h1>

<p>Some details on the article</p>

このように、コメントとして挿入したテキストはすべて無視されるため、テンプレート開発時にコメントを使用すると非常に便利です。たとえば、チェックやデバッグなどを行うときに、一部のコードをコメントアウトしたい場合があります。

コメントのブロック

残念ながら、上述のコメントシンタックスは、Curlybarsコードのコメントアウトには使用できません。Curlybarsコードをコメントアウトするには、{{!-- ... ---}}のように、開き波かっこの直後(スペース不要)に感嘆符を挿入してコメントを追加します。このシンタックスによるコメントは、複数行にわたって使用でき、コードを効果的にコメントアウトできます。例:

{{!
  This template aims to
  show details of an article
}}

<h1>Article</h1>

<p>Some details on the article</p>

{{!--
  I want to commend out the following code:

  {{ ... some Curlybars expressions }}

--}}

上記のテンプレートは、以下のようにレンダリングされます。

<h1>Article</h1>

<p>Some details on the article</p>

リテラル

Curlybarsはリテラルの概念をサポートしており、記述どおりに正確に値を解釈できます。リテラルは、文字列、ブール値、数値の3つのデータ型のいずれかの値をとります。

文字列を表現するには、引用符と二重引用符のどちらを使用してもかまいませんが、両方を混在させることはできません。たとえば、'this is a valid string'および"this is valid as well"のように記述できますが、"this is not valid'と記述することはできません。

数値は正数でも負数でもかまいません。123は有効な正数であり、+123も同じ値を表します。00123も有効な値であり、同様に-123も有効な値です。

ブール値は、trueとfalseで表されます。それ以外の記法はありません。たとえば、CurlybarsではTRUEおよびFALSEはブール値として解釈されません。

リテラルはレンダリングできます。例:

A string: {{ 'hello world' }}
A boolean: {{ true }}
A number: {{ 42 }}

このページは、以下のようにレンダリングされます。

A string: 'hello world'
A boolean: true
A number: 42

プロパティ

ヘルプセンター内のすべてのテンプレートは、ヘルプセンターに関するデータを表す「コンテキスト」にアクセスできます。たとえば、「記事ページ」のテンプレートには、articleというオブジェクトがあります。これは、ユーザーによってリクエストされた記事の構成を表します。テンプレート内で使用できるすべてのプロパティについては、developer.zendesk.comで「Help Center Templates(ヘルプセンターのテンプレート)」を参照してください。

ドット記法を使用して、オブジェクトから特定の情報を引き出します。シンプルな例としては、article.titleのように記述します。

プロパティの完全修飾名は、「パス」と呼ばれることもあります。たとえば、nameはauthorオブジェクトのプロパティですが、article.author.nameはそのパスです。

プロパティの値は、二重の波かっこで囲んで表すことができます。上の例に戻ると、記事の作成者の名前を別の段落に表示したいとします。

<h1>Article</h1>

<p>Author: {{article.author.name}}</p>

たとえば、ユーザーがJohn Venturiniというエージェントの書いた記事を表示したいとします。テンプレートは、以下のようにレンダリングされます。

<h1>Article</h1>

<p>Author: John Venturini</p>

また、記事そのものをレンダリングすることもできます。articleオブジェクトには、bodyプロパティがあり、記事のコンテンツが含まれています。テンプレートを次のように編集して、記事の本文をレンダリングします。

<h1>Article</h1>

<p>Author: {{article.author.name}}</p>

<article>{{article.body}}</article>

条件文

テンプレート言語を使用すると、プロパティ値のレンダリングだけでなく、テンプレートにレンダリングの条件式を追加できます。

たとえば、要求された記事が社内向けの場合に、HTMLのスピネットをレンダリングできます。記事ページのコンテンツに含まれるarticle.internalプロパティは、記事が社内向けのものである場合にtrueを返し、そうでない場合はfalseを返します。

この情報を使って、ifブロックを作成できます。if式は、trueかfalseになる条件を指定するものです。いずれかの結果によって、ブロック内のコンテンツがレンダリングされるかどうかが決まります。基本的なシンタックスは次のようになります。

{{#if condition}}
  This is rendered if the condition is true.
{{/if}}

このテンプレートの例は、次のように変更できます。

<h1>Article</h1>

{{#if article.internal}}
  <p>This article is internal.</p>
{{/if}}

<p>Author: {{article.author.name}}</p>

<article>{{article.body}}</article>

条件がfalseの場合に、ブロックがレンダリングされるようにもできます。その場合には、unlessブロックを使用します。シンタックスはifブロックと同じで、次のようになります。

{{#unless condition}}
  This is rendered if the condition is false.
{{/unless}}

元の例に戻り、記事が内部向けのものでない場合に、メッセージがレンダリングされるようにしたいとします。テンプレートを以下のように変更します。

<h1>Article</h1>

{{#if article.internal}}
  <p>This article is internal.</p>
{{/if}}

{{#unless article.internal}}
  <p>This is a publicly visible article!</p>
{{/unless}}

<p>Author: {{article.author.name}}</p>

<article>{{article.body}}</article>

「trueの場合はこれを実行し、それ以外の場合はこちらを実行する」のような条件ロジックは、通常、if-elseブロックで処理します。シンタックスは以下のようになります。

{{#if condition}}
  This is rendered if the condition is true.
{{else}}
  This is rendered if the condition is false.
{{/if}}

このプレースホルダの前後のメッセージは、必要に応じて変更できます。

<h1>Article</h1>

{{#if article.internal}}
  <p>This article is internal.</p>
{{else}}
  <p>This is a publicly visible article!</p>
{{/if}}

<p>Author: {{article.author.name}}</p>

<article>{{article.body}}</article>

unlessブロックには、unless-elseのバリアントもあります。これを以下のように使って、if-elseブロックと同じ結果を得ることができます。

<h1>Article</h1>

{{#unless article.internal}}
  <p>This is a publicly visible article!</p>
{{else}}
  <p>This article is internal.</p>
{{/unless}}

<p>Author: {{article.author.name}}</p>

<article>{{article.body}}</article>

条件式を評価する

条件は、主にarticle.internalなど、trueまたはfalseのブール値をとるヘルプセンタープロパティです。一部のプロパティはブール値をとりません。これらのプロパティは次のように評価されます。

  • 値が数値の場合、0はfalseで、それ以外の値はすべてtrue

  • 値が文字列の場合、空の文字列はfalseで、それ以外の値はすべてtrue

  • 値がオブジェクトの集合の場合、空の集合はfalseで、それ以外の集合はすべてtrue

  • 値がnullの場合、式はfalse

数値をチェックする条件式ロジックを設定すると仮定します。記事ページには、記事内のコメントの合計数を含むarticle.comment_countプロパティがあります。if条件を使用して、カウントが0でないことをテストし、ちょっとした愉快なメッセージを表示できます。例:

<h1>Article</h1>

<p>Author: {{article.author.name}}</p>

<article>{{article.body}}</article>

{{#if article.comment_count}}
  <p>Yahoo! This article has got some comments!</p>
{{/if}}

ホワイトスペースを削除する

Curlybarsがテンプレートを処理する場合、逐語的文字列はそのまま表示されます。この処理は、ほとんどの場合、正常に実行されます。ただし、場合によっては、式に隣接する空白文字に処理を加える必要があります。たとえば、次のコードがあります。

<a href="..." class="{{#if highlighted}} highlight {{/if}}">Click me!</a>

このコードは、highlightedがtrueの場合に、次のようにレンダリングされます。

<a href="..." class=" highlight ">Click me!</a>

highlightという単語の前後に空白文字が挿入されています。このままでも表示に問題はありませんが、空白文字をレンダリングせずにテンプレート内に挿入したままにしておく方法はないのでしょうか。チルド文字(~)を使用すればできます。

チルド文字を開き波かっこまたは閉じ波かっこに追加することで、かっこで囲んだ文字列からホワイトスペースを削除できます。例:

<a href="..." class="{{#if highlighted~}} highlight {{~/if}}">Click me!</a>

チルダ記号により、highlightという単語の前後の空白文字が次のように削除されます。

<a href="..." class="highlight">Click me!</a>

チルド文字は、空白文字の挿入や改行に影響する空白文字(画面に文字として現れないもの)を削除します。たとえば、新規行、タブ、改行、ラインフィード、シンプルな空白などを削除します。つまり、極端な例をとると、上述の複数行にわたるifブロックを、読みやすく表記できます。例:

<a href="..." class="
  {{~#if highlighted~}}
    highlight
  {{~/if~}}
">Click me!</a>

これは、次のようにレンダリングされます

<a href="..." class="highlight">Click me!</a>

このコード例は、実際には役に立ちませんが、チルド文字の使用は場合によって非常に有効です。

ヘルパー

一部のテンプレートで必要な操作は、データにアクセスして表示し、条件ロジックをいくつか追加するだけです。とはいえ、機能を追加したい場合もあります。たとえば、ローカライズした文字列を、ページのリクエスタのロケールごとに変更して表示したい場合や、長すぎる文字列を切り捨てたい場合などです。

このような機能は、テンプレートでヘルパーを使用して追加することができます。テンプレート内で使用できるすべてのヘルパーについては、developer.zendesk.comで「Help Center Templates(ヘルプセンターのテンプレート)」を参照してください。

記事ページテンプレート内で、excerptというヘルパーを使用して、文字列を切り捨てることができます。この記事の例は、記事のタイトルを短くして表示する必要がある場合を想定しています。これを行うには、テンプレートを以下のように変更します。

<h1>{{excerpt article.title characters=50}}</h1>

<p>Author: {{article.author.name}}</p>

<article>{{article.body}}</article>

上記の例では、波かっこを使用してヘルパーを呼び出しています。excerptヘルパーは、文字列に解決される式で構成されるパラメータを受け取ります。ヘルパーのcharactersオプションに、維持する文字数を指定します。charactersオプションは必須指定ではありません。指定しない場合、デフォルト値が使用されます。詳細については、ヘルプセンターのテンプレートで、excerptの項を参照してください。

ヘルパーを呼び出すシンタックスは{{<helper> [<param> ...] [<key=value> ...]}}です。必須要素はヘルパーの名前だけです。パラメータとオプションを指定する必要があるかどうかは、ヘルパーごとに異なります。

次に、テンプレートを更新して、作成者の名前がJohn Venturiniの場合に愉快なメッセージを表示したいとします。あいにく、article.author.nameが"John Venturini"と等しいかどうかを、if条件を使用して調べることはできません。ifは1つの式にしか有効にならないからです。==などの比較演算子は使用できません。

では、どのようにしてロジックを追加するのでしょうか。それには、isヘルパーを使用します。等価性を表し、テストするために、2つのパラメータをとります。例:

<h1>{{excerpt article.title characters=50}}</h1>

{{#is article.author.name 'John Venturini'}}
  <p>Cool! John Venturini is the author of this article!</p>
{{/is}}

<article>{{article.body}}</article>

上の例のスニペットは、作成者がJohn Venturiniであった場合に愉快なメッセージを表示します。では、作成者がJohn Venturiniでなかった場合に別のメッセージを表示する場合の記述はどのようになるでしょうか。実は、isにはelseブロックを含めることができ、if-elseステートメントと同じように使用できるのです。作成者がJohn Venturiniでなかった場合に元のメッセージを表示するには、elseブロックを追加します。

<h1>{{excerpt article.title characters=50}}</h1>

{{#is article.author.name 'John Venturini'}}
  <p>Cool! John Venturini is the author of this article!</p>
{{else}}
  <p>Author: {{article.author.name}}</p>
{{/is}}

<article>{{article.body}}</article>

スコープを変更する

ドット記法を使用するデータへのアクセスは、特に、必要な情報へのパスがあまり長くない場合には明快な方法です。例:article.title。ただし、状況によっては、長いパスを使用してプロパティにアクセスしたい場合があります。例:article.author.name。必要に応じて、テンプレート内で長いパスを使用することもできます。たとえば、以下の例では、作成者の名前とアバターを追加しています。

<h1>{{excerpt article.title characters=50}}</h1>

<img src="{{article.author.avatar_url}}" alt="Author's avatar" height="42" width="42">
{{#is article.author.name 'John Venturini'}}
  <p>Cool! John Venturini is the author of this article!</p>
{{else}}
  <p>Author: {{article.author.name}}</p>
{{/is}}

<article>{{article.body}}</article>

上記のスニペットは正しく動作しますが、プロパティのパスが長すぎて、コードが読みにくくなっています。この問題を回避するには、withコンストラクタを使用する方法があります。withは、関連付けられているコードブロック内で使用するために、基本のコンテキストを表すパラメータを1つとります。シンタックスは以下のようになります。

{{#with <context>}}
   ...
{{/with}}

先ほどの例を次のように改良できます。

<h1>{{excerpt article.title characters=50}}</h1>

{{#with article.author}}
  <img src="{{avatar_url}}" alt="Author's avatar" height="42" width="42">
  {{#is name 'John Venturini'}}
    <p>Cool! John Venturini is the author of this article!</p>
  {{else}}
    <p>Author: {{name}}</p>
  {{/is}}
{{/with}}

<article>{{article.body}}</article>

article.authorパラメータにより、ブロックのどのパスにもarticle.authorを含める必要がなくなりました。したがって、上記ブロック内の{{name}}は、ブロック外のarticle.author.nameと同じ意味を表します。

article.author.nameをブロック内で使用することはできません。ブロック内で使用すると、article.author.article.author.nameと評価されるからです。同様に、ブロック内からarticle.titleを使用して記事のタイトルにアクセスすることはできません。記事オブジェクトはルートコンテキスト内でのみアクセス可能で、それはブロック外だからです。

withが設定されたコンテキストをエスケープして、外部のコンテキストにアクセスするには、パス内で../記法を使用します。withブロック内の記事のタイトルは、次のように記述してレンダリングすることもできます。

<h1>{{excerpt article.title characters=50}}</h1>

{{#with article.author}}
  {{../article.title}}

  <img src="{{avatar_url}}" alt="Author's avatar" height="42" width="42">
  {{#is name 'John Venturini'}}
    <p>Cool! John Venturini is the author of this article!</p>
  {{else}}
    <p>Author: {{name}}</p>
  {{/is}}
{{/with}}

<article>{{article.body}}</article>

同じパス内で../記法を繰り返し使用できます。このように記述することで、コンテキストの数だけ繰り返します。たとえば、次の例も、期待どおりに動作します。

<h1>{{excerpt article.title characters=50}}</h1>

{{#with article}}
  {{#with author}}
    {{../../article.title}}

    ...

{{/with}}

<article>{{article.body}}</article>

万全の策として、作成者が指定されていない場合に、特定のメッセージが表示されるようにすることもできます。その場合は、次のようにifブロックを使用します。

<h1>{{excerpt article.title characters=50}}</h1>

{{#if article.author}}
  {{#with article.author}}
    ...
  {{/with}}
{{else}}
  No author is present for this article!
{{/if}}

<article>{{article.body}}</article>

なお、ヘルプセンターでは、article.authorは実際には決してnullになりません。ここでは、コードの記述法を示すために、nullになると仮定しているだけです。

上記のスニペットも正しく動作しますが、withコンストラクタでelseブロックを使用することで、同じ結果を得ることもできます。elseブロックは、パラメータが偽である場合に実行されます。上記の例は、以下のように変更できます。

<h1>{{excerpt article.title characters=50}}</h1>

{{#with article.author}}
  ...
{{else}}
  No author is present for this article!
{{/with}}

<article>{{article.body}}</article>

elseブロックを使用することで、コードが読みやすくなります。

ルートコンテキストをヘルパーに渡す

thisキーワードを使用して、現在のルートコンテキストをヘルパーに渡します。作成者に関する情報を表示するためにarticleオブジェクトをパラメータとして受け取るrender_authorヘルパーがあるとします。thisキーワードは、次のように使用できます。

<h1>{{excerpt article.title characters=50}}</h1>

{{#with article}}
  {{render_author this}}
{{/with}}

<article>{{article.body}}</article>

this articleとして解決されます。

配列内のアイテムにアクセスする

ヘルプセンターの一部のプロパティは、オブジェクトの配列から成ります。たとえば、attachmentsプロパティは、添付ファイルの配列で構成されます。

配列内のアイテムにアクセスするには、アイテムごとに反復処理を行う必要があります。eachヘルパーがこの処理を行います。例:

<h1>{{excerpt article.title characters=50}}</h1>

{{#with article.author}}
  ...
{{/with}}

<article>{{article.body}}</article>

{{#each attachments}}
  <a href="{{url}}" target="_blank">{{name}}</a>
  <span>({{size}})</span>
{{/each}}

上記のスニペットは、すべての添付ファイルを列挙します。各リストアイテムは、それぞれ添付ファイルの固有データを表示します。たとえば、url、name、sizeなどです。

withと同様、eachが変更するのはブロック内のコンテキストです。つまり、ブロック外のコンテキストにアクセスしたい場合は、../記法を使用できます。

配列が空の場合に、メッセージがレンダリングされるようにもできます。これは、ifブロックを次のように記述することで、簡単に実現できます。

...

{{#if attachments}}
  {#each attachments}}
    <a href="{{url}}" target="_blank">{{name}}</a>
    <span>({{size}})</span>
  {{/each}}
{{else}}
  Sorry, no attachments available!
{{/if}}

このままでも正しく動作しますが、elseブロックを使用すると、コードがより読みやすくなります。

...

{#each attachments}}
  <a href="{{url}}" target="_blank">{{name}}</a>
  <span>({{size}})</span>
{{else}}
  Sorry, no attachments available!
{{/each}}

length

すべての配列には、配列内の要素の数を示す暗黙的なlengthプロパティがあります。たとえば、添付ファイルの数を表示したい場合、lengthプロパティを次のように指定します。

...

There are {{attachments.length}}.

{#each attachments}}
  <a href="{{url}}" target="_blank">{{name}}</a>
  <span>({{size}})</span>
{{/each}}
Powered by Zendesk