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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
tvOS Tutorial: Using TVML Templates
35 mins
- Getting Started
- Loading Scripts
- TVML Templates
- The Product Template
- Data Injection
- Reading JSON From the App Bundle
- Injecting Data Into the Document String
- Resolving Image URLs
- Using the Mustache.js Templates
- Template Sections
- Filling out the TVML Template
- Adding Shelves
- Handling Text Overflow
- Event Handling
- Viewer Ratings
- Collecting Ratings
- Where to Go From Here?
The Product Template
The first document you’ll create uses
, which is designed to display all information relating to a specific product — in this case, a video.
Open video.tvml and add the following code between the
tags:
<banner>
<infoList>
<info>
<header>
<title>Presenter</title>
</header>
<text>Ray Wenderlich</text>
</info>
<info>
<header>
<title>Tags</title>
</header>
<text>development</text>
<text>teams</text>
<text>business</text>
</info>
</infoList>
</banner>
This code snippet introduces a lot of new element types. Taking them one-by-one:
-
<banner>
: Displays content across the top of a page. -
<infoList>
: Displays a list of
elements, arranged in a vertical list. -
<info>
: Acts as a container forthis s the content to appear as an item in an
or an
. -
<header>
: Serves as a description of the content of the section in which it resides. -
<title>
: Contains the text of a short title. -
<text>
: Displays text.
Build and run the app to see what your new TVML looks like:
This page represents a video, but it currently lacks a title. Time to change that.
Add the following inside the <banner>
tags, just after the closing tag:
<stack>
<title>Teamwork</title>
<row>
<text>17m 54s</text>
<text>Inspiration</text>
<text>2015</text>
<badge src="resource://nr" />is
<badge src="resource://cc" />
<badge src="resource://hd" />
</row>
</stack>
This section introduces more TVML elements:
-
<stack>
: Stacks lay out their content vertically down the screen in a manner similar to
. There’s a wider range of tags that can be in a Stack. -
<row>
: A row is like a stack, but with a horizontal orientation instead of vertical. -
<badge>
: Badges display a small inline image. The URL is provided by thesrc
attribute.
Notice that the URL of the two badge images begin with resource://
. This is a special URL scheme that points to images that exist within tvOS itself. These images include common action icons, such as “play”, rating images for different countries and video information such as HD.
Build and run again to see how the page is shaping up:
It’s starting to look good, but there’s still a long way to go. Before continuing with the template coding, you first need to consider the separation of the data and the view.
Data Injection
As your video document currently stands, all the data is hard-coded. To show information about a different video, you’d have to create a whole new page. If you wanted to reformat the video page once you’ve created all the pages, you’d have to go back through and edit every single one of them.
A much better approach is to use a templating engine, where you build the video page as a template and specify where the data should be injected. At runtime, the template engine takes the page template along with the data and generates the TVML page for tvOS to display.
Mustache.js is a popular simple templating engine for JavaScript. You might recognize the templating syntax which is based around curly-braces:
{{property-name}}
The Mustache.js library is already part of wenderTV, but you need to build the mechanisms to use it. This presents you with several tasks to accomplish:
- The data is stored as JSON files in the app bundle. The JavaScript app needs the ability to request them.
- When a document is loaded, it now requires data, and this should be combined with the document string using Mustache.js.
- Images that are present in the app bundle need their complete URL substituted.
- The video document should be updated to turn it into a templated document.
You’ll address each of these in order.
However, prototyping is only available at the <section>
level, while you’re using it in this tutorial for much more, such as in the <header>
section of your TVML. You’ll continue to use Mustache.js as a templating engine for this section of the book, but if you end up having to handle large content sets in your tvOS apps, read up on prototyping and data binding at apple.co/2utDXXm.
However, prototyping is only available at the <section>
level, while you’re using it in this tutorial for much more, such as in the <header>
section of your TVML. You’ll continue to use Mustache.js as a templating engine for this section of the book, but if you end up having to handle large content sets in your tvOS apps, read up on prototyping and data binding at apple.co/2utDXXm.
Reading JSON From the App Bundle
Open ResourceLoader.js and add the following method to ResourceLoaderJS
:
getJSON(name) {
var jsonString = this.nativeResourceLoader
.loadBundleResource(name);
var json = JSON.parse(jsonString);
return json;
}
This function uses the native resource loader to pull the JSON file from the app bundle before parsing it into a JavaScript object.
Injecting Data Into the Document String
Now that you can obtain the data for a given page, you need to combine it with the document template itself. Update getDocument()
in ResourceLoaderJS
to match the following:
getDocument(name, data) {
data = data || {};
var docString = this.nativeResourceLoader
.loadBundleResource(name);
var rendered = Mustache.render(docString, data);
return this.domParser.parseFromString(rendered,
"application/xml");
}
Here you’ve added an additional data
argument to the method and used render
on Mustache
to convert the template and data to a completed document. As before, you use a DOMParser
to convert the document string to a DOM object.