tvOS Tutorial: Using TVML Templates

In this tvOS tutorial, you’ll learn how to use TVML templates and templating engines to make great-looking user interfaces. By Chris Belanger.

Leave a rating/review
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Handling Text Overflow

The descriptive alert template provides space for an extended area of text and buttons. It sounds ideal for this purpose. You’ll use this template and a spot of JavaScript to wire it up.

In the Xcode project, right-click on the layouts group and select New File…. Choose tvOS\Other\Empty and name the file expandedDetailText.tvml.

Open the new file and add the following:

<?xml version="1.0" encoding="UTF-8" ?>
<document>
  <descriptiveAlertTemplate>
    <title>{{title}}</title>
    <description>{{text}}</description>
    <button action="dismiss">
      <text>Dismiss</text>
    </button>
  </descriptiveAlertTemplate>
</document>

This should be quite straightforward to understand. There’s the usual XML prologue, the tag and some elements you’ve used before. Notice that the button tag has an action attribute; this is a user-defined attribute that’s not part of the TVML specification.

You can define any attributes that you want (provided they don’t clash with existing attributes) and then read them from your JavaScript app. You’ll write some code to handle this dismiss action in just a bit.

Open video.tvml and find the tag. Update the element to match the following:

<description allowsZooming="true"
  moreLabel="more"
  action="showOverflow"
  title="{{title}}">{{description}}</description>

You’ve added two new attributes: action and title. You’ll use both of these in the event handler to create the expanded detail text document.

Event Handling

Now that the document templates are ready to go you can turn your attention to the JavaScript that wires everything up.

Open main.js and add the following function:

function _handleEvent(event) {
  // 1:
  var sender = event.target;
  var action = sender.getAttribute("action");
  // 2:
  switch(action) {
    case "showOverflow":
      // 3:
      var data = {
        text: sender.textContent,
        title: sender.getAttribute("title")
      };
      // 4:
      var expandedText = resourceLoader
        .getDocument("expandedDetailText.tvml", data);
      expandedText.addEventListener("select", _handleEvent);
      navigationDocument.presentModal(expandedText);
      break;
    case "dismiss":
      // 5:
      navigationDocument.dismissModal();
      break;
  }
}

Taking this piece-by-piece:

  1. The target property of the event argument represents the DOM object that fired the event. getAttribute() of a DOM object will return the value for the specified attribute. Here you’re using it to find the value of the action attribute you added above.
  2. Switch on the action attribute to invoke the appropriate code.
  3. If the action is showOverflow, then you have a description field with too much content. Construct an object with the data required by the expanded detail text document. Once again you’re using getAttribute() along with textContent, which returns the content of the tag itself.
  4. Load the expandedDetailText.tvml document in the usual way, add an event listener and use presentModal() on NavigationDocument to display the new document on top of the current document.
  1. If the action is set to dismiss, use dismissModal() on NavigationDocument to perform the dismissal.

Now that you’ve created this event handler, you need to wire it up to the initial document. Add the following line to App.onLaunch, just after you call loadInitialDocument():

initialDoc.addEventListener("select", _handleEvent);

This registers _handleEvent as a listener for the select event, and uses event bubbling to handle all events triggered within the document.

Build and run the app, navigate down to the over-full description and hit the select button. You’ll see your new expanded detail text page:

You can use the dismiss button to return to the video screen.

Viewer Ratings

In the final part of this tutorial, you’ll add a new ratings section to the video page and let the user select a rating using a new template.

Open video.tvml and add the following new shelf underneath the Production shelf:

<shelf>
  <header>
    <title>What other people thought</title>
  </header>
  <section>
    {{#ratings-reviews}}
      <ratingCard action="addRating">
        {{#rw-ratings}}
          <title>{{out-of-five}} / 5</title>
          <ratingBadge value="{{badge-value}}"></ratingBadge>
          <description>Mean of {{count}} ratings.</description>
        {{/rw-ratings}}
      </ratingCard>
      {{#reviews}}
        <reviewCard>
          <title>{{title}}</title>
          <description>{{description}}</description>
          <text>{{name}} {{date}}</text>
        </reviewCard>
      {{/reviews}}
    {{/ratings-reviews}}
  </section>
</shelf>

By now, you’ll recognize most of the TVML elements, but there are still a few new ones:

  • <ratingCard>: Displays a small card suitable for showing the ratings of a product.
  • <ratingBadge>: A specialized badge for showing a star-rating. The value attribute should be a value between 0 and 1, which will be converted to a proportion of five stars.
  • <reviewCard>: A card for displaying user or critic reviews.

Notice that the element has the custom action attribute again. You’ll use this later to display the rating page.

Build and run to see what the new shelf looks like:

When the user selects the rating card, you want to let them choose a rating for the current video. This is exactly what the ratings TVML template is for.

Collecting Ratings

In Xcode, right-click on the layouts group and select New File…. Choose tvOS\Other\Empty and name the file videoRating.tvml.

Open the new file and add the following:

<?xml version="1.0" encoding="UTF-8" ?>
<document>
  <ratingTemplate>
    <title>{{title}}</title>
    <ratingBadge />
  </ratingTemplate>
</document>

This new file uses the which simply displays and collects ratings. It contains a <title> and a <ratingBadge>, both of which you’ve already seen.

The template is ready; you just need to display it. Open main.js and add the following case to the switch statement in _handleEvent():

case "addRating":
  var ratingDoc = resourceLoader.getDocument("videoRating.tvml",
    {title: "Rate Video"});
  navigationDocument.presentModal(ratingDoc);
  break;

These few lines load the new document you created and provide the title to the templating engine. It then displays the document modally.

Build and run, navigate to the rating card and hit select to see the new ratings page:

Now that is one swell-looking – and extensible – interface.

Where to Go From Here?

You can download the final project from this tutorial here.

In this tutorial you’ve created a great-looking TVML app and used three of the built-in templates along with a vast array of TVML-specific elements. You also integrated a JavaScript templating engine to separate the UI from the data. Adopting great development techniques right from the start is a win in anyone’s book.

You can check out Apple’s documentation (apple.co/1PJuOAV) for specifics about the templates and elements covered in this tutorial.

If you enjoyed what you learned in this tutorial, why not check out the complete tvOS Apprentice book, available in our store?

Here’s a taste of what’s in the book:

Section I: Architecture

This section is designed to give you a birds-eye view of how tvOS works and help you decide what to read next.

Section II: TVML Apps

This section covers the basics for creating an app via the TVML approach. From the basics of Hello World through a real world example, by the end of this section you’ll know everything you need to create client / server apps for Apple TV.

Section III: Traditional Apps

This section covers the basics for creating apps via the traditional approach. You’ll learn the new libraries created for Apple TV, and how the ported libraries from iOS can be used.

Section IV: Advanced Frameworks

This section covers some of the more advanced frameworks you’ll need for many TV app use cases. Whether you took the TVML approach or the Traditional approach, these frameworks will be important to understand to make your app stand out.

Section V: Design

This section covers design concepts important for tvOS. For your app to stand apart from the rest, you’ll need to understand these design concepts well.

Bonus Chapter

And that’s not all — on top of the above, we have a bonus chapter for you that gives you a crash course in JavaScript!

By the end of this book, you’ll have some great hands-on experience with building exciting, good-looking apps for the Apple TV!

And to help sweeten the deal, the digital edition of the book is on sale for $49.99! But don’t wait — this sale price is only available for a limited time.

Speaking of sweet deals, be sure to check out the great prizes we’re giving away this year with the iOS 11 Launch Party, including over $9,000 in giveaways!

To enter, simply retweet this post using the #ios11launchparty hashtag by using the button below:


We hope you enjoy this update, and stay tuned for more book releases and updates!

Chris Belanger

Contributors

Chris Belanger

Author

Over 300 content creators. Join our team.