Using the help center templating language

<div class="article-banners">
<div id="docs-wmp-link"><a href="https://support.zendesk.com/hc/en-us/articles/5411234991258-plan" target="_blank" rel="noopener noreferrer">What's my plan?</a></div>
<div class="article-banner" id="suite_gpee"><figure class="wysiwyg-table wysiwyg-table-align-left"><table><tbody><tr>
<td><strong>All Suites</strong></td>
<td>Growth, Professional, Enterprise, or Enterprise Plus</td>
</tr></tbody></table></figure></div>
<div class="article-banner" id="support_with_guide_all"><figure class="wysiwyg-table wysiwyg-table-align-left"><table><tbody><tr>
<td><strong>Support with</strong></td>
<td>Knowledge Professional or Enterprise</td>
</tr></tbody></table></figure></div>
</div><p>This article covers the following topics:</p><ul>
<li id="toc_1" data-list-item-id="eb26b26d30b5c594958bcf3bd5da2d302"><a href="#toc_1">Introduction</a></li>
<li data-list-item-id="e1b7581f7946b9f2867c6c6e14754b3db"><a href="#toc_2">Templating basics</a></li>
<li data-list-item-id="e6abc3bf6ebeb430330716d4eab6b1ebe"><a href="#toc_3">Comments</a></li>
<li data-list-item-id="e66e6502934151195e7343370a3adb8b5"><a href="#toc_4">Block Comments</a></li>
<li data-list-item-id="e6a5c1a3213e05687e4b5589102dd6bc4"><a href="#toc_5">Literals</a></li>
<li data-list-item-id="e5652f4889546ddd66ca7a5abe1c50344"><a href="#toc_6">Properties</a></li>
<li data-list-item-id="e8dcbbe77987b866021107e6e6d65a3d9"><a href="#toc_7">Conditionals</a></li>
<li data-list-item-id="e7363474b8bb5f83fabdfbce647db73d8"><a href="#toc_8">How conditions are evaluated</a></li>
<li data-list-item-id="ed0a9246639b4d81e0f7706c36596fbef"><a href="#toc_9">Trimming white space</a></li>
<li data-list-item-id="eddd968cf85e0b283d53263af4f970ac6"><a href="#toc_10">Helpers</a></li>
<li data-list-item-id="e4eff06d783058aa6c637641505ec621f"><a href="#toc_11">Changing scope</a></li>
<li data-list-item-id="e43d4fb7dcbff2546689c7e3bab545c4d"><a href="#toc_12">Passing the root context to a helper</a></li>
<li data-list-item-id="e132a32df71da6d5cc06b015af03cc79b"><a href="#toc_13">Accessing items in an array</a></li>
<li data-list-item-id="e2419aa8efe94964f38d26d36cd29850f"><a href="#toc_14">Length</a></li>
<li data-list-item-id="e6119acc892600c293d6d5938617ac044"><a href="#toc_15" target="_self">Subexpressions</a></li>
</ul><h3 id="h_01KR4R5HDMP14NZMMFEY5T5VH0">Introduction</h3><p>Each help center theme consists of a collection of <a href="https://support.zendesk.com/hc/en-us/articles/4408839332250-Customizing-Help-Center#topic_h5c_k4w_n3">editable page templates</a> that define the layout of different types of pages in help center. For example, there's a template for knowledge base articles, a template for the list of requests, and so on.</p><p>Each template consists of a mix of HTML markup and Handlebars-like expressions, identifiable in the template by double curly brackets. <a href="http://handlebarsjs.com">Handlebars</a> is a simple templating engine that lets you insert or manipulate content on a page at render-time rather than at design-time.</p><p>The templating language in help center is called <em>Curlybars</em> and implements a large subset of the Handlebars language. This guide shows you how use the language to customize your pages in help center.</p><p>help center provides you with helpers and named properties to customize your content. Some are shared and available on all help center pages. The rest are page-specific.</p><p><strong>Example</strong></p><pre class="wysiwyg-code-block"><code class="language-auto html">{{#each comments}}
&lt;li class="comment" id="{{comment_id}}"&gt;
&lt;div class="comment-avatar {{#if author.agent}} comment-avatar-agent {{/if}}"&gt;
&lt;img src="{{author.avatar_url}}" alt="Avatar" /&gt;
&lt;/div&gt;

&lt;div class="comment-container"&gt;
&lt;header class="comment-header"&gt;
&lt;strong class="comment-author"&gt;
{{author.name}}
&lt;/strong&gt;
&lt;/header&gt;
&lt;/div&gt;
&lt;/li&gt;
{{/each}}
</code></pre><p>The example generates a list of users who left comments on the page. The <code>each</code> helper iterates through each value in the page's <code>comments</code> property. For each comment, the values of the <code>author.avatar_url</code> and <code>author.name</code> properties are inserted in the HTML.</p><!--
title: Using the Help Center templating language
filename: using_curlybars.md
kb: https://support.zendesk.com/hc/en-us/articles/205753348
--><h3 id="toc_2">Templating basics</h3><p>This section introduces the building blocks you need to write any template. For more information, see <a href="https://developer.zendesk.com/apps/docs/help-center-templates/introduction">Help Center Templates</a> on developer.zendesk.com.</p><p>A Curlybars template is made up of two things: verbatim text to be rendered as is, and Curlybars expressions. This implies that an empty template is also a valid template, and a template that contains only text is also a valid one. For instance, the following is a valid template:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Some details on the article&lt;/p&gt;
</code></pre><p>Of course, if help center templates only supported verbatim text, you couldn't really customize them at render-time. To add templating logic, you need Curlybars expressions, which are enclosed double curly brackets(<code>{{</code> and <code>}}</code>).</p><p>To add templating logic to the previous example, you might modify the template as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Some details on the article&lt;/p&gt;

{{article.author.name}}
</code></pre><p>The following sections explain how to write valid expressions to make meaningful changes to the template.</p><p>Note that nesting a pair of curlies within other pair of curlies is not valid syntax. For example, the following isn't allowed:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Some details on the article&lt;/p&gt;

{{ {{ ... }} }}
</code></pre><h3 id="toc_3">Comments</h3><p>There are situations where having some notes in the template that do not leak into the rendered page might come in handy. For this purpose, Curlybars allows to make comments putting an exclamation mark right after the opening curlies, without any space: <code>{{! ... }}</code>. You can use this syntax to add a code comment in the example:</p><pre class="wysiwyg-code-block"><code class="language-auto html">{{!
This template aims to
show details of an article
}}

&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Some details on the article&lt;/p&gt;
</code></pre><p>Here's what's sent to the browser after the page is rendered:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Some details on the article&lt;/p&gt;
</code></pre><p>This effect of discarding anything within the comments can actually come in handy while developing a template. You might want to comment out some code to do some checks, debug, and more.</p><h4 id="toc_4">Block Comments</h4><p>Unfortunately, the comment syntax described so far isn't suitable for commenting out Curlybars code. To comment out Curlybars code, use the following syntax: <code>{{!-- ... ---}}</code>. This kind of comment can span several lines and effectively comment out code. Example:</p><pre class="wysiwyg-code-block"><code class="language-auto html">{{!
This template aims to
show details of an article
}}

&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Some details on the article&lt;/p&gt;

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

{{ ... some Curlybars expressions }}

--}}
</code></pre><p>The template above is rendered as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Some details on the article&lt;/p&gt;
</code></pre><h3 id="toc_5">Literals</h3><p>To include values that you want Curlybars to interpret exactly as they're written, Curlybars supports the concept of <em>literals</em>. A literal can represent 3 types of values: a <strong>string</strong>, a <strong>boolean</strong>, or a <strong>number</strong>.</p><p>To express a string, you can use both single and double quotes, but you can't mix them. For example, <code>'this is a valid string'</code>, <code>"this is valid as well"</code>, but <code>"this is not valid'</code>.</p><p>A number can be any positive or negative integer. <code>123</code> is a valid positive number, <code>+123</code> represents the same value, <code>00123</code> is still valid, and <code>-123</code> is valid as well.</p><p>A boolean is represented by <code>true</code> and <code>false</code>. No other variation is allowed. For example, <code>TRUE</code> and <code>FALSE</code> aren't intepreted as booleans in Curlybars.</p><p>You can render literals. Example:</p><pre class="wysiwyg-code-block"><code class="language-auto html">A string: {{ 'hello world' }}
A boolean: {{ true }}
A number: {{ 42 }}
</code></pre><p>The page is rendered as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">A string: 'hello world'
A boolean: true
A number: 42
</code></pre><h3 id="toc_6">Properties</h3><p>Every template in the help center has access to a <em>context</em> that represents data about your help center. For instance, the Article Page template has an object named <code>article</code> that exposes the structure of the article requested by the users. For all the properties you can use in your templates, see <a href="https://developer.zendesk.com/apps/docs/help-center-templates/introduction">Help Center Templates</a> on developer.zendesk.com.</p><p>Use dot notation to pluck a specific information from these objects. A simple example is <code>article.title</code>.</p><p>The fully qualified name of a property is sometimes called a <em>path</em>. For example, <code>name</code> is a property in the <code>author</code> object, but <code>article.author.name</code> is its path.</p><p>You can display the value of a property by enclosing it within double curly brackets. Getting back to the example, you might want to print out the name of the author in a separate paragraph:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Author: {{article.author.name}}&lt;/p&gt;
</code></pre><p>Let's say a user wants to see an article written by an agent named John Venturini. The template will be rendered as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Author: John Venturini&lt;/p&gt;
</code></pre><p>You might also want to render the article itself. The <code>article</code> object has a <code>body</code> property that contains the content of the article. You'd modify the template as follows to render the body of the article:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Author: {{article.author.name}}&lt;/p&gt;

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><h3 id="toc_7">Conditionals</h3><p>In addition to rendering property values, the templating language lets you add conditional rendering logic to your templates.</p><p>For instance, you might want to render a snippet of HTML in case the requested article is internal. The Article Page context has an <code>article.internal</code> property that returns <code>true</code> if the article is internal and <code>false</code> otherwise.</p><p>You can create an <code>if</code> block with this information. The <code>if</code> expression must specify a condition that's true or false. The result determines whether the content in the block is rendered or not. Here's the basic syntax:</p><pre class="wysiwyg-code-block"><code class="language-auto html">{{#if condition}}
This is rendered if the condition is true.
{{/if}}
</code></pre><p>You can modify the example template as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

{{#if article.internal}}
&lt;p&gt;This article is internal.&lt;/p&gt;
{{/if}}

&lt;p&gt;Author: {{article.author.name}}&lt;/p&gt;

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>You might want to render a block when the condition is false. In that case, use an <code>unless</code> block. The syntax is similar to the <code>if</code> block:</p><pre class="wysiwyg-code-block"><code class="language-auto html">{{#unless condition}}
This is rendered if the condition is false.
{{/unless}}
</code></pre><p>Back to the example, suppose you also want to render a message when an article is not internal. You can modify the template as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

{{#if article.internal}}
&lt;p&gt;This article is internal.&lt;/p&gt;
{{/if}}

{{#unless article.internal}}
&lt;p&gt;This is a publicly visible article!&lt;/p&gt;
{{/unless}}

&lt;p&gt;Author: {{article.author.name}}&lt;/p&gt;

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>This kind of conditional logic -- "if true do this or else do this" -- is usually handled by an <code>if-else</code> block. The syntax is as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">{{#if condition}}
This is rendered if the condition is true.
{{else}}
This is rendered if the condition is false.
{{/if}}
</code></pre><p>You can modify the example as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

{{#if article.internal}}
&lt;p&gt;This article is internal.&lt;/p&gt;
{{else}}
&lt;p&gt;This is a publicly visible article!&lt;/p&gt;
{{/if}}

&lt;p&gt;Author: {{article.author.name}}&lt;/p&gt;

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>The <code>unless</code> block also has an <code>unless-else</code> variant. You could use it to achieve the same result as an <code>if-else</code> block:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

{{#unless article.internal}}
&lt;p&gt;This is a publicly visible article!&lt;/p&gt;
{{else}}
&lt;p&gt;This article is internal.&lt;/p&gt;
{{/unless}}

&lt;p&gt;Author: {{article.author.name}}&lt;/p&gt;

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><h4 id="toc_8">How conditions are evaluated</h4><p>A condition is usually a help center property such as <code>article.internal</code>, which has a boolean value of <strong>true</strong> or <strong>false</strong>. Some properties don't have boolean values. These properties are evaluated as follows:</p><ul>
<li data-list-item-id="ea9401eb3d8817739721b0f3e456804b9">If the value is a number, then 0 is false and any other number is true</li>
<li data-list-item-id="e5fad1cee5b9eda45dca21857975f2396">If the value is a string, an empty string is false and any other string is true</li>
<li data-list-item-id="e7d52304c91a044784b66a2e393bf2e9e">If the value is a collection of objects, an empty collection is false and any other collection is true</li>
<li data-list-item-id="e63b7937db5a2e2e82d10681ec42d0b7b">If the value is null, the expression is false</li>
</ul><p>Suppose you want to set up some conditional logic that checks numbers. The Article Page has an <code>article.comment_count</code> property that contains the total number of comments in an article. You can use the <code>if</code> condition to test if the count is not <code>0</code> and display some cheerful message. Example:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;Article&lt;/h1&gt;

&lt;p&gt;Author: {{article.author.name}}&lt;/p&gt;

&lt;article&gt;{{article.body}}&lt;/article&gt;

{{#if article.comment_count}}
&lt;p&gt;Yahoo! This article has got some comments!&lt;/p&gt;
{{/if}}
</code></pre><h3 id="toc_9">Trimming white space</h3><p>When Curlybars processes a template, it displays any verbatim text as is. That's good and works well most of the time. However, sometimes you need to have more control on the blank characters next to an expression. Take the following code for example:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;a href="..." class="{{#if highlighted}} highlight {{/if}}"&gt;Click me!&lt;/a&gt;
</code></pre><p>It renders the following HTML when <code>highlighted</code> is true:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;a href="..." class=" highlight "&gt;Click me!&lt;/a&gt;
</code></pre><p>There's a leading and a trailing space around the word <em>highlight</em>. This of course works fine, but suppose you want to keep the spaces in the template without rendering them. You can use the tilde character (~).</p><p>Adding a tilde character in your opening or closing curly brackets trims white space from the enclosed text. Example:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;a href="..." class="{{#if highlighted~}} highlight {{~/if}}"&gt;Click me!&lt;/a&gt;
</code></pre><p>The tilde characters trim the leading and a trailing spaces around the word <em>highlight</em>:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;a href="..." class="highlight"&gt;Click me!&lt;/a&gt;
</code></pre><p>The tilde character trims any blank character that doesn't have a graphical representation but affects spacing or split lines, such as newlines, tabs, carriage returns, line feeds, simple spaces, or tabs. This means you can take the example to an extreme and express the previous <code>if</code> block on more lines to make it more readable. Example:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;a href="..." class="
{{~#if highlighted~}}
highlight
{{~/if~}}
"&gt;Click me!&lt;/a&gt;
</code></pre><p>This still renders as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;a href="..." class="highlight"&gt;Click me!&lt;/a&gt;
</code></pre><p>These examples don't make much sense in real life, but the effectiveness of using the tilde character can vary from case to case.</p><h3 id="toc_10">Helpers</h3><p>Accessing data, displaying it, and adding some conditional logic can be all you need in some templates. Still, you might like some added functionality. For example, you might want to display a localized string that changes according to the locale of the page requester. Or you might want to truncate a long passage of text.</p><p>You can get this kind of functionality in templates with <em>helpers</em>. For all the helpers you can use in your templates, see <a href="https://developer.zendesk.com/apps/docs/help-center-templates/introduction">Help Center Templates</a> on developer.zendesk.com.</p><p>For example, you can use a helper named <code>excerpt</code> in the Article page template to truncate strings. In the article example, suppose you need to show a truncated version of the article title. You can do this by modifying the template as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

&lt;p&gt;Author: {{article.author.name}}&lt;/p&gt;

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>The example above shows that curly brackets are used to invoke a helper. The <code>excerpt</code> helper accepts a parameter that consists of an expression that resolves to a string. The helper has a <code>characters</code> option to specify the number of characters to keep. The <code>characters</code> option isn't mandatory. If you don't specify it, a default value is used. See <a href="https://developer.zendesk.com/apps/docs/help-center-templates/helpers#excerpt-helper">excerpt</a> in Help Center Templates for further details.</p><p>The syntax to invoke a helper is <code>{{&lt;helper&gt; [&lt;param&gt; ...] [&lt;key=value&gt; ...]}}</code>. The only mandatory element is the name of the helper. Parameters and options vary depending on the helper.</p><p>Now, suppose you want to update the template to display a cheerful message when the author's name is John Venturini. Unfortunately, you can't use an <code>if</code> condition to check if <code>article.author.name</code> is equal to <code>"John Venturini"</code> because <code>if</code> only works on one expression. Comparison operators like <code>==</code> are not available.</p><p>How to add such a logic then? Fortunately, you can use the <code>is</code> helper. It takes two parameters and tests them for equality. Example:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

{{#is article.author.name 'John Venturini'}}
&lt;p&gt;Cool! John Venturini is the author of this article!&lt;/p&gt;
{{/is}}

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>The snippet above renders the cheerful message if the author is John Venturini. But what if you want to render a different message if it's not him? The good news is that <code>is</code> can also include an <code>else</code> block just like the <code>if-else</code> statement. To restore the old message if the author is not John Venturini, you can add an <code>else</code> block as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

{{#is article.author.name 'John Venturini'}}
&lt;p&gt;Cool! John Venturini is the author of this article!&lt;/p&gt;
{{else}}
&lt;p&gt;Author: {{article.author.name}}&lt;/p&gt;
{{/is}}

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><h3 id="toc_11">Changing scope</h3><p>Accessing data is pretty straightforward using dot notation, especially when the path to the information we need is not too long. Example: <code>article.title</code>. In some circumstances, though, you might want to access a property with a longer path. Example: <code>article.author.name</code>. You can use longer paths in templates if you want. For example, you can add the author's name and avator in the example as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

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

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>The snippet above works just fine, but the long property paths make the code look a little cluttered. One way around the problem is to use the special <code>with</code> construct. <code>with</code> accepts one parameter that represents the base context to use in the code block associated with it. The syntax is as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">{{#with &lt;context&gt;}}
...
{{/with}}
</code></pre><p>You can improve the example as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

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

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>The <code>article.author</code> parameter eliminates the need to include <code>article.author</code> in any paths in the block. So <code>{{name}}</code> inside the block is equivalent to <code>article.author.name</code> outside the block.</p><p>You can't use <code>article.author.name</code> in the block because it would be evaluated as <code>article.author.article.author.name</code>. Similarly, you can't access the title of the article in the block with <code>article.title</code> because the article object is accessible only in the root context, which is outside the block.</p><p>To escape from the context set by <code>with</code> and access the outer context, use the <code>../</code> notation in the path. You can render the title of the article inside the <code>with</code> block as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

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

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

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>You can use the <code>../</code> notation repeatedly in the same path. It'll jump back the same number of contexts. For instance, the following example will still work as expected:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

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

...

{{/with}}

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>You might want to be defensive and render a specific message whenever the author is not specified. You might decide to use an <code>if</code> block to do this, as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

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

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>Note that in Help Center, <code>article.author</code> is actually never null. We assumed so here only for the sake of the example.</p><p>The snippet above works just fine, but you can achieve the same result with an <code>else</code> block in the <code>with</code> construct. The else block is executed if the parameter is falsy. You can modify the example as follow:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

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

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p>Using an <code>else</code> block also makes the code more readable.</p><h4 id="toc_12">Passing the root context to a helper</h4><p>Use the <code>this</code> keyword to pass the current root context to a helper. Suppose you have a <code>render_author</code> helper that accepts an <code>article</code> object as a parameter in order to display details about its author. You can use the <code>this</code> keyword as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

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

&lt;article&gt;{{article.body}}&lt;/article&gt;
</code></pre><p><code>this</code> will be resolved as <code>article</code>.</p><h3 id="toc_13">Accessing items in an array</h3><p>Some help center properties consist of arrays of objects. For example, the <code>attachments</code> property consists of an array of attachments.</p><p>To access the items in an array, you need to iterate over each one. The <code>each</code> helper does exactly that. Example:</p><pre class="wysiwyg-code-block"><code class="language-auto html">&lt;h1&gt;{{excerpt article.title characters=50}}&lt;/h1&gt;

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

&lt;article&gt;{{article.body}}&lt;/article&gt;

{{#each attachments}}
&lt;a href="{{url}}" target="_blank"&gt;{{name}}&lt;/a&gt;
&lt;span&gt;({{size}})&lt;/span&gt;
{{/each}}
</code></pre><p>The snippet above lists all the attachments. Each list item displays data specific to one attachment, such as its <code>url</code>, <code>name</code>, and <code>size</code>.</p><p>Like <code>with</code>, <code>each</code> changes the context in its block. This means that if you want to access the outer context, you can use the <code>../</code> notation.</p><p>You might want to render a message when an array is empty. You can easily achieve this by using an <code>if</code> block, as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">...

{{#if attachments}}
{{#each attachments}}
&lt;a href="{{url}}" target="_blank"&gt;{{name}}&lt;/a&gt;
&lt;span&gt;({{size}})&lt;/span&gt;
{{/each}}
{{else}}
Sorry, no attachments available!
{{/if}}
</code></pre><p>This works just fine, but you could also use an <code>else</code> block to make the code easier to read:</p><pre class="wysiwyg-code-block"><code class="language-auto html">...

{{#each attachments}}
&lt;a href="{{url}}" target="_blank"&gt;{{name}}&lt;/a&gt;
&lt;span&gt;({{size}})&lt;/span&gt;
{{else}}
Sorry, no attachments available!
{{/each}}
</code></pre><h3 id="toc_14">Length</h3><p>Every array has an implicit <code>length</code> property that gives the number of elements in the array. For example, if you want to display the number of attachments, use the <code>length</code> property as follows:</p><pre class="wysiwyg-code-block"><code class="language-auto html">...

There are {{attachments.length}}.

{{#each attachments}}
&lt;a href="{{url}}" target="_blank"&gt;{{name}}&lt;/a&gt;
&lt;span&gt;({{size}})&lt;/span&gt;
{{/each}}</code></pre><h3 id="toc_15">Subexpressions</h3><p>Subexpressions allow you to invoke multiple helpers within a single expression, and pass the results of inner helper invocations as arguments to outer helpers. Subexpressions are delimited by parentheses.</p><p class="sc-bXexck bnjTSw" data-garden-id="typography.paragraph" data-garden-version="8.39.0">The following example shows a subexpression in an expression:</p><pre class="sc-bXexck bnjTSw wysiwyg-code-block" data-garden-id="typography.paragraph" data-garden-version="8.39.0"><code class="language-auto">{{search placeholder=(dc "search_text")}}</code></pre><p>Subexpressions can be nested:</p><pre class="wysiwyg-code-block"><code class="language-auto">{{search placeholder=(excerpt (dc "search_text"))}}</code></pre><p>Subexpressions can be used in conditional helpers:</p><pre class="wysiwyg-code-block"><code class="language-auto">{{#if (compare collection.length "==" 0)}}
&lt;div&gt;Empty collection.&lt;/div&gt;
{{else}}
&lt;div&gt;Your collection has {{collection.length}} items&lt;/div&gt;
{{/if}}</code></pre><p>Subexpressions can be used in array iterator helpers:</p><pre class="wysiwyg-code-block"><code class="language-auto">{{#each (slice (filter user.badges on="category_slug" equals="achievements")
0 4)}}

&lt;section&gt;
&lt;h3&gt;{{name}}&lt;/h3&gt;
&lt;div&gt;{{description}}&lt;/div&gt;
&lt;/section&gt;
{{/each}}
</code></pre><p> </p><script id="docs-schema-markup" type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"@id": "https://support.zendesk.com/hc/en-us/articles/4408824571674",
"url": "https://support.zendesk.com/hc/en-us/articles/4408824571674-Using-the-help-center-templating-language",
"headline": "Using the help center templating language",
"description": "You can use the Curlybars templating language to customize help center page templates by inserting dynamic content, applying conditional logic, and manipulating data structures within the HTML layout.",
"articleSection": "Using themes and customizing your help center",
"datePublished": "2021-10-16T03:47:15+00:00",
"dateModified": "2026-01-21T19:43:52+00:00",
"inLanguage": "en-US",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://support.zendesk.com/hc/en-us/articles/4408824571674"
},
"author": {
"@type": "Organization",
"name": "Zendesk",
"@id": "https://www.zendesk.com"
},
"publisher": {
"@type": "Organization",
"name": "Zendesk",
"@id": "https://www.zendesk.com"
},
"isPartOf": {
"@type": "WebSite",
"name": "Zendesk Help",
"@id": "https://support.zendesk.com/hc/"
},
"about": {
"@type": "SoftwareApplication",
"name": "Zendesk",
"@id": "https://www.zendesk.com",
"softwareAddOn": {
"@type": "SoftwareApplication",
"name": "Knowledge",
"@id": "https://support.zendesk.com/hc/en-us/sections/4405298860954"
}
}
}
</script>