In the previous tutorials in the series, you created the starter files for an app named Requester X-ray and modified the HTML file to be iframed into Zendesk Support. The HTML file displays only the header and footer of your app. In this tutorial, you'll create a template to display the information you'll retrieve about the requester, as well as a template to display an error message in case there's a problem retrieving the data. You'll also learn how to insert templates into the app.

Templates are typically the building blocks of an app's user interface. They define different states, or views, for an application. For example, one template can contains an HTML form for entering search terms, and another template can dynamically list the search results.

You can use any templating engine you like for your apps. For this project, you decide to use Handlebars.js.

This tutorial covers the following tasks:

  1. Choosing a templating engine
  2. Creating a template for requester information
  3. Inserting the template in your app
  4. Creating a template for error messages

This tutorial is part of a series on building a Zendesk app:

Choosing a templating engine

You can use any templating engine -- and whatever version -- you like with your apps. For this project, you decide to use Handlebars.js, one of the most popular templating libraries.

  • Import the Handlebars library in your app by inserting the following <script> tag in iframe.html before the <script> tag that references your main.js file:

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/handlebars.min.js"></script>

Creating a template for requester information

After reviewing the design requirements at Planning the app, you conclude that the app requires a single template to display the information about the requester. The mockup suggests you need a 2-column by 4-row table to show the information.

In Handlebars, you can define templates by including them in <script> tags.

Create the requester template

  1. Open your iframe.html file and add the following <script> tag before all the other <script> tags:

    <script id="requester-template" type="text/x-handlebars-template">    <table>    <tr>      <td>Customer:</td>      <td>{{name}}</td>    </tr>    <tr>      <td>Tags:</td>      <td>{{#each tags}}{{this}} {{/each}}</td>    </tr>    <tr>      <td>Added:</td>      <td>{{created_at}}</td>    </tr>    <tr>      <td>Last signed in:</td>      <td>{{last_login_at}}</td>    </tr>    </table></script>

    The tag defines a template consisting of a 2x4 HTML table for displaying the requester information. The template contains several Handlebars highlighted expressions. A Handlebars expression typically consists of a variable inside double curly braces. Example: {{name}}. When the app runs in Zendesk Support, the expressions are replaced by values supplied by a JavaScript data object, which is sometime referred to as a context.

    The template uses the {{#each}} helper to display each tag in the array of tags received from the API.

  2. Enclose the table row that displays tags with the {{#if}} helper (highlighted):

    ...{{#if tags}}<tr>  <td>Tags:</td>  <td>{{#each tags}}{{this}} {{/each}}</td></tr>{{/if}}

    If the requester doesn't have any tags, the field in the UI will be blank. To create a better UI experience, you can hide the entire line with the Handlebars {{#if}} helper. The line will only appear if the requester has tags. The {{#if ...}} helper displays the enclosed content if the specified value is truthy. Any array with a length that's anything but zero is truthy. An empty array is falsy so the table row would never get rendered.

  3. In the mockup, the data text is green so apply a CSS class called data to each one. (You'll create the style in the next step.)

    <script id="requester-template" type="text/x-handlebars-template">  <table>  <tr>    <td>Customer:</td>    <td class="data">{{name}}</td>  </tr>  {{#if tags}}  <tr>    <td>Tags:</td>    <td class="data">{{#each tags}}{{this}} {{/each}}</td>  </tr>  {{/if}}  <tr>    <td>Added:</td>    <td class="data">{{created_at}}</td>  </tr>  <tr>    <td>Last signed in:</td>    <td class="data">{{last_login_at}}</td>  </tr>  </table></script>
  4. Open the main.css file and add the following style:

    .data {  color: #363;  padding-left: 6px;}

    The style makes the text green and adds a little padding on the left to separate the text from the labels.

  5. Save the iframe.html and main.css files.

If you reload the app, nothing happens because you haven't inserted the template in the HTML yet. The next step is to insert the template and then confirm that the insert works.

Inserting the template in your app

You insert templates into an element of your choice in the document. You decide to add a <div> tag in your HTML file for inserting templates at runtime. Only one template at a time can be inserted, but you can switch to a different template. For example, you can start by displaying the splash page and then switch to another page after the user clicks a button.

  1. In iframe.html file, add the following <div> tag after the opening <body> tag but before the footer:

    <div id="content"></div>
  2. In main.js, add the following function call (highlighted) after the resize statement in your self-invoking function:

    (function () {  var client = ZAFClient.init();  client.invoke('resize', { width: '100%', height: '120px' });  showInfo();})();
  3. Add your new showInfo() function after the self-invoking function:

    ...
    function showInfo() {  var requester_data = {    'name': 'Jane Doe',    'tags': ['tag1', 'tag2'],    'created_at': 'November 20, 2014',    'last_login_at': 'June 27, 2016'  };
      var source = document.getElementById("requester-template").innerHTML;  var template = Handlebars.compile(source);  var html = template(requester_data);  document.getElementById("content").innerHTML = html;}

    In the first part of the function, the requester_data object defines the values, or context, to the Handlebars template. You'll replace the hard-coded values later with real-time data.

    The second part passes the data to the template and renders the HTML. The first line references the <script> tag that contains the template in iframe.html. The second line compiles the template. The third line adds the data to the template and generates the final HTML. The final line sets the HTML content of your <div> tag from step 1.

  4. Save both files.

  5. On your test ticket in the agent interface, click the Refresh icon in the Apps panel. If your ZCLI server is not already started, see Testing the app for instructions.

    If nothing appears when you reload apps, try a hard refresh of the ticket interface by pressing Shift and the reload button on your browser.

    Handlebars inserts the values of your requester_data object in the template and spits out the final HTML, which the app then sets as the HTML content of the <div id="content"> tag in the iframe.html file.

    The app has a few cosmetic issues. The text is a little too big and the line spacing is a little too tight.

  6. To fix the issues, add the following style in main.css:

    #content td {  font-size: 12px;  padding-top: 2px;}
  7. Save all the files and click Reload All Apps in Zendesk Support.

Creating a template for error messages

If the app encounters a problem retrieving the user data, you want the user to see an error message about what went wrong.

  1. In iframe.html, add the following error template after your requester template:

    <script id="error-template" type="text/x-handlebars-template">  <p>{{status}} - {{statusText}} error. Please report a bug at the link below.</p></script>

    The template is designed to display HTTP status error messages such as "404 - Not found".

  2. In main.js, add the following function to compile and insert the template the iframe.html file:

    function showError() {  var error_data = {    'status': 404,    'statusText': 'Not found'  };
      var source = document.getElementById("error-template").innerHTML;  var template = Handlebars.compile(source);  var html = template(error_data);  document.getElementById("content").innerHTML = html;}
  3. Call the function (highlighted) from your self-invoking function:

    (function () {  var client = ZAFClient.init();  client.invoke('resize', { width: '100%', height: '120px' });  showInfo();  showError();})();
  4. To test it, comment out showInfo(); with double forward-slashes, save both files, and reload the app in Zendesk Support.

    As with the requester template, Handlebars inserts the values of your error_data object in the template and generates the final HTML, which the app then sets as the HTML content of the <div id="content"> tag in the iframe.html file.

  5. After you're satisfied both templates work as intended, delete both the showInfo(); and showError(); function calls in the self-invoking function. You'll call these functions from a different place in the next tutorial.

If you're moving to the next tutorial, you can leave the ZCLI server running. If you're done for this session, you can shut down the server by switching to your command-line interface and pressing Control+C.

In this tutorial, you created templates to display requester information and an error message. You also learned how to insert the templates into your app. In the next tutorial, you learn how to get the requester's information from the Zendesk API. Continue to Part 4 - Getting data.