Template View
This desktop-only view allows Presto developers to create custom views for specific mashable information sources or mashups. You can also create global view templates that users can select as the starting point for a custom view for other mashables or mashups.
![]() | This view is available for version 3.1 and later. It is a beta feature. |
Custom views and templates combine HTML code with template syntax to map result fields to the appropriate locations within the HTML markup. This uses some aspects of the jQuery templating syntax. You can loop through repeating structures, handle conditional logic to generate appropriate HTML, display results that contain HTML markup and merge result data to produce the custom view.
![]() | Custom views created with the Template view have two limitations:
|
Users should be familiar with HTML and optionally CSS and JavaScript to use the Template view to create a custom view for an artifact. See the following sections for instructions and examples:
Create a Custom View for This Artifact Only
You can create a template directly, by adding HTML tags, mapping result fields and adding other template syntax until you have the custom view you want. Or you can select a global view template as a starting point and tweak the HTML and template syntax as needed.
In the Configure Data step, type HTML tags directly in the Template Code pane. The template code should be well-formed, wrapped entirely in one tag, such as <div>.

Or find a global template. You can search by name
or click the Down Arrow to see a list of global templates and select the template you want. Then update the code for the template as needed:
Map Result Fields to the Template or Map Results Fields That Contain HTML Markup to define where result data should appear.
If needed, Iterate Through Repeating Results,
Use JavaScript in Template Code to define the final output.
Use Preview at any time to preview the results of your code.
Once you are satisfied, click Save as.
Enter a name and optional description for this custom view. To make this a view only for the current mashable or mashup, leave the Template Scope set to Specific.
Click Save.
Save a Custom View as a Global View Template
The steps to create a global view template are the same as creating a unique custom view for one artifact. When you save the template, change the Template Scope to Global. Presto administrators can also register global view templates in the Admin Console.
Map Result Fields to the Template
Mapping result fields defines where data will appear within the HTML code for this view or template. You use the jQuery syntax for variable substitution to map fields:
${path.to.datanode}
See jQuery Template Syntax for Variable Substitution for more details on this syntax.
You should only map fields that contain data. If you map a complex node (an object) by mistake, Preview shows [object Object] as the value.
Rather than entering mapping syntax directly, you can automatically generate this syntax using the Data pane in the Configure Data step:
Data Field Not in a Repeating Item
In the Template pane, type ${} inside the HTML element or attribute that should contain the data for the field.
Place the cursor inside the braces.
Expand the results tree in the Data pane.
Click the field in the Data pane that you want to map to the current position in the template.
The template code is updated with the full path to this field (${full. path.to.field}):

Data Field in a Repeating Item
Place the cursor inside the HTML element or attribute where you want the data to appear.
Expand the results tree in the Data pane.
Click the field from one repeating item in the Data pane that you want to map to the template.
The template code is updated with the mapping syntax and the relative path to this field, starting from the repeating item node. For example: ${description} for one field inside rss.channel.item.
This syntax assumes that you are mapping data fields for repeating items within a loop, where the path to the repeating item node is already defined. See Iterate Through Repeating Results or Example: Examples for examples.
Data Field in a Specific Repeating Item Instance:
Place the cursor inside the HTML element or attribute where you want the data to appear.
Expand the results tree in the Data pane.
Click the field from one repeating item in the Data pane that you want to map to the template.
This adds the mapping syntax using a relative path to this field, such as ${title}.
Add the full path to this field, including the specific index number for the repeating instance that you want. For example: ${rss.channel.item[0].title} to map the title of the first item in an RSS feed.
Map Results Fields That Contain HTML Markup
Some result fields contain HTML markup along with data. Common examples include fields in RSS or Atom web feeds. If you map these result fields using the basic mapping syntax, ${path.to.fieldname}, the view shows the HTML tags for this field such as this example:

To handle result fields that contain HTML, use the {{html path.to.fieldname}} syntax instead.
![]() | See jQuery Template Syntax for HTML Evaluation for more details on this syntax. |
Enter {{html }} within the HTML tags where this field should appear.
Place the cursor after the space in the html statement and before the end braces (}}).
Expand the results tree in the Data pane.
Click the field in the Data pane that has HTML markup that you want to map to the current position in the template.
The mapping syntax that this generates depends on whether this is a single field or a field inside repeating items. For single fields, the syntax is generated correctly with a full path to that field, such as {{html rss.channel.title}}.
For fields in repeating items, the syntax that is generated has a relative path, which is correct, but the path uses the standard mapping syntax such as {{html ${description}}}. Preview will show an error invalid property id rather than rendering the view.
If needed, remove the ${ and} symbols that were generated around the path to this field.
With the correct syntax, the view now renders the HTML code from this field:

Iterate Through Repeating Results
In many cases, the results contain a repeating structure with data that the view should iterate through, generating HTML and data for each instance. Use the {{each structure.path}} template syntax to performs loops in a template:
Enter the start- and end-loop statements where you want to begin looping in the view:
{{each }} {{/each}}
See jQuery Template Syntax for Loops for more details on looping syntax.
Place the cursor after the space in the start-loop statement.
Click in the Data pane on the repeating node that should be used as the iterator for the loop:

This adds the full path to the repeating node for the loop.
Within the start- and end-loop statements, add the HTML that should be generated for each loop iteration. Map individual fields from the repeating items as needed (see Map Result Fields to the Template).

Mapping uses relative paths to fields within each repeating item, as shown above. See also Example: Examples for a more detailed example.
Add Conditional Logic
You may also need templates or custom views to have conditional logic or handle different cases in the results. To add conditions, use these template statements:
{{if condition}}...{{/if}}: where the condition is any valid JavaScript condition. To check for the presence of a field in the results, use the path to that field as the condition.
{{else condition}}...{{/else}}: can be used within an if-statement. The condition is any valid JavaScript condition. To check for the presence of a field in the results, use the path to that field as the condition.
{{else}}...{{/else}}: can be used within an if-statement to provide a default behavior if none of the conditions are true.
To generate the path to a field as part of a condition:
Place the cursor inside the if or else start-statement
Add a space after if or else.
Click on the field you want in the Data pane.
Insert the appropriate HTML and other template syntax within the start- and end-statements.
This example change the background color and text color based on the value of a field:
{{if PercentChange > 0}}
<div style="width: 90px;padding: 5px; border: 1px solid #ccc; margin: 5px;float: left;background-color: #5ab000;color:#fff;">
{{else PercentChange < -3}}
<div style="width: 90px;padding: 5px; border: 1px solid #ccc; margin: 5px;float: left;background-color: #c11;color:#fff;">
{{else}}
<div style="width: 90px;padding: 5px; border: 1px solid #ccc; margin: 5px;float: left;background-color: #ff9;color:#333;">
{{/if}}
See If Syntax and Else Syntax for more information on conditional statements in jQuery templates. See Example: Examples for a more detailed example.
Use CSS in Template Code
You can use CSS as local styles using the style attribute directly on any HTML element in a template. For example:

You can also use the class attribute to refer to CSS classes defined in external CSS stylesheets. You must include <link> elements in the template to link to any external CSS stylesheets.
External CSS stylesheets used in templates must either:
Have a fully-qualified URL where the stylesheet is hosted. For example:
<div> <link type="text/css" rel="stylesheet" href="http://www.jackbe.com/prestodocs/v3.0/prestodocs.css"/> <div class="topic"> <div class="jbtitle1">View Title</div> ... </div> </div>
Generally, you should use this option for external stylesheets hosted by third parties or custom stylesheets for your organization that are hosted outside of Presto. Hosting custom stylesheets for your organization in the Presto or Presto Hub web applications is not recommended as this complicates deployment and upgrade migrations.
Have been uploaded to Presto and use a Presto URL.
This option is recommended for custom stylesheets for your organization or from third-parties when they cannot be hosted outside of Presto or these resources should be available for use in any custom view.

External resources can only be uploaded to Presto by Presto administrators. See Add External Resources as Presto Files for more information.
This example links to a stylesheet that has been uploaded to Presto. The full path for this URL is defined when the resource is uploaded, but is generally in the form http:app-server:port/presto/files/filename:
<div> <link type="text/css" rel="stylesheet" href="http://localhost:8080/presto/files/myView.css"/> <div class="blueThemeGrid"> ... </div> </div>
Use Images in Template Code
To use images in a custom view or template, they must be hosted outside of Presto at a fully-qualified URL or a Presto administrator must upload the image file to Presto. See Add External Resources as Presto Files for more information. Image files may be in any commonly-used format for web pages, such as GIF, PNG or JPEG.
You can add images to a custom view or template using CSS styles or using an <img> tag in the view or template HTML code. This is an example using CSS and an external image:
...
<div style="height: 180px; width: 250px;
background:url('http://myOrg.com/images/logo.png"></div>
...
With images that have been uploaded to Presto you simply use the Presto URL. The full path for this URL is defined when the resource is uploaded, but is generally in the form http:app-server:port/presto/files/filename. This example uses an <img> tag and a Presto URL:
... <img src="http://localhost:8080/presto/files/myHeader.png"/> ...
Use JavaScript in Template Code
You can add JavaScript code directly to a custom view or template using the <script> tag. For example:
<div>
<div id="myMsg"></div>
<script>jQuery("myMsg").html("Welcome stranger!");</script>
</div>
You can also refer to external JavaScript libraries. External libraries must:
Have a fully-qualified URL where the library is hosted. For example:
<div> <script type="text/javascript" scr="http://some.example.com/libraries/commonView.js"/> ... </div>
Generally, you should use this option for external libraries hosted by third parties or libraries for your organization that are hosted outside of Presto. Hosting JavaScript libraries for your organization in the Presto or Presto Hub web applications is not recommended as this complicates deployment and upgrade migrations.
Have been uploaded to Presto and use a Presto URL.
This option is recommended when JavaScript libraries cannot be hosted outside of Presto or these resources should be available for use in many custom views.

External resources can only be uploaded to Presto by Presto administrators. See Add External Resources as Presto Files for more information.
This example uses a JavaScript library that has been uploaded to Presto. The full path for this URL is defined when the resource is uploaded, but is generally in the form http:app-server:port/presto/files/library-name:
<div> <script type="text/javascript" scr="http://localhost:8080/presto/files/commonView.js"/> ... </div>
Loading and Scope
Custom views become part of the user interface for Apps which in turn are published and run inside of other web pages or mobile devices. Thus scripts are loaded and run within the body of another page. Typically, the DOM for the page is fully loaded.
Scripts should also use a unique namespace to ensure there are no naming conflicts with other code running within that page.
Events and Event Handlers
Custom views support all of the standard DOM events. Developers can also use jQuery functions to register event handlers or to define and fire custom events. For example:
...
<button id="event1">Trigger an event</button>
<script type="text/javascript">
jQuery("#event1").click(function(){
jQuery(this).parent().trigger("myEvent", {
eventdata: { type: 'button', time: (new.Date()).toString() }
}
);
});
</script>
...
Examples
More detailed examples are included for: Repeating Items, Conditional Logic, No Repeating Items and Namespaces and Linked CSS and JavaScript.
Repeating Items
This example shows a simple layout for a set of repeating record nodes:
<div>
{{each records.record}}
<div style="padding: 5px;border-bottom: 1px solid #eee;">
<div style="float:left; width: 60%;">
<h4>${offense}</h4>
<em>${city}: Reported at ${lastmodifieddate}</em></p>
<p>${narrative}</p>
<p>District: ${district}</p>
<p>Address: ${siteaddress}</p>
</div>
</div>
{{/each}}
</div>
Conditional Logic, No Repeating Items and Namespaces
This next example uses the Yahoo Weather syndicated feed to produce a view similar to the standard weather displayed by Yahoo:

This example handles a result that has no repeating items. Even though it is an RSS web feed, Yahoo returns a single item with weather information for the selected zip code. Some of the interesting points in this example include:
Mapping to non-repeating nodes and nodes with namespaces:
<em>Current conditions at <strong>${rss.channel['yweather:location'].city}</strong> as of ${rss.channel.lastBuildDate} </em>Nodes with namespaces use array syntax, such as ['yweather:location']. The path to this non-repeating node uses the full path from the root node of the result.
A basic if/else example:
<dd style="position:relative;"> ${rss.channel['yweather:atmosphere'].pressure} in and {{if rss.channel['yweather:atmosphere'].rising > 0}} rising {{else}} falling {{/if}} </dd>Using mapping and conditional template syntax within the value of an HTML attribute:
<div style="height: 180px; width: 250px; background:url('http://l.yimg.com/a/i/us/nws/weather/gr/ ${rss.channel.item['yweather:condition'].code} {{if rss.channel.item['yweather:condition'].date.indexOf("pm") > 0}} d {{else}} n {{/if}} .png');"></div>
The full code for this template is shown below:
<div style="height:auto;background-color: #CCE1FF;font-size:smaller; padding: 10px;">
<em>Current conditions at
<strong>${rss.channel['yweather:location'].city}</strong> as of
${rss.channel.lastBuildDate}
</em>
<h4>${rss.channel.item['yweather:condition'].text},
${rss.channel.item['yweather:condition'].temp}
${rss.channel['yweather:units'].temperature}
</h4>
<div>
<div style="float:left; width: 30%;">
<dl>
<dt style="float: left; min-width: 100px;">Feels Like:</dt>
<dd>${rss.channel.item['yweather:condition'].temp}</dd>
<dt style="float: left; width: 100px;">Barometer:</dt>
<dd style="position:relative;">
${rss.channel['yweather:atmosphere'].pressure} in and
{{if rss.channel['yweather:atmosphere'].rising > 0}}
rising
{{else}}
falling
{{/if}}
</dd>
<dt style="float: left; width: 100px;">Humidity:</dt>
<dd>${rss.channel['yweather:atmosphere'].humidity} %</dd>
<dt style="float: left; width: 100px;">Visibility:</dt>
<dd>${rss.channel['yweather:atmosphere'].visibility} mi</dd>
<dt style="float: left; width: 100px;">Dewpoint:</dt>
<dd>${rss.channel['yweather:wind'].chill} 5°F</dd>
<dt style="float: left; width: 100px;">Wind:</dt>
<dd>${rss.channel['yweather:wind'].speed} mph, chilll:
${rss.channel['yweather:wind'].chill}</dd>
<dt style="float: left; width: 100px;">UV Index:</dt>
<dd>--</dd>
<dt style="float: left; width: 100px;"> UV Description:</dt>
<dd>Low</dd>
<dt style="float: left; width: 100px;">Sunrise:</dt>
<dd>${rss.channel['yweather:astronomy'].sunrise}</dd>
<dt style="float: left; width: 100px;">Sunset:</dt>
<dd>${rss.channel['yweather:astronomy'].sunset}</dd>
</dl>
</div>
<div style="float: left;">
<div style="height: 180px; width: 250px;background:url('http://l.yimg.com/a/i/us/nws/weather/gr/${rss.channel.item['yweather:condition'].code}{{if rss.channel.item['yweather:condition'].date.indexOf("pm") > 0}}d{{else}}n{{/if}}.png');">
</div>
</div>
<div class="spacer" />
</div>
</div>
Linked CSS and JavaScript
This example uses sample Yahoo Weather Given Zip Code mashables and these CSS and JavaScript files which have been uploaded to Presto using the default file names:
| weathersumdetail.css |
.weather {font-size: 11px; padding: 4px;}
.wtitle {font-size: 13px; font-weight: bold;}
.wsubtitle {font-weight: bold;}
.wsummary{ display: block;}
.wdetail{ display: none;]
button{ margin-top: 4px; margin-bottom: 4px;}
|
| weathersumdetail.js | jQuery("button").click(function(e){jQuery(".wdetail").show()}); |
The custom view code is:
<div class="weather">
<link type="text/css" rel="stylesheet"
href="http://localhost:8080/presto/files/weathersumdetail.css"/>
<script type="text/JavaScript"
src="http://localhost:8080/presto/files/weathersumdetail.js"/>
<div class="wtitle">${rss.channel.description}</div>
<div class="wsubtitle">on ${rss.channel.lastBuildDate}</div>
<img height="180px" width="250px" src="http://l.yimg.com/a/i/us/nws/weather/gr/${rss.channel.item['yweather:condition'].code}{{if rss.channel.item['yweather:condition'].date.indexOf("pm") > 0}}d{{else}}n{{/if}}.png"/>
<div class="wsummary">Currently: ${rss.channel.item['yweather:condition'].text}, ${rss.channel.item['yweather:condition'].temp} F</div>
<button>See Details</button>
<div class="wdetail">
<div>Barometer: ${rss.channel['yweather:atmosphere'].pressure} in and {{if rss.channel['yweather:atmosphere'].rising > 0}}rising{{else}}falling{{/if}}</div>
<div>Humidity: ${rss.channel['yweather:atmosphere'].humidity} %</div>
<div>Wind: ${rss.channel['yweather:wind'].speed} mph</div>
</div>
</div>
The JavaScript defines a handler for the button in the template that updates the CSS style for the <div> with wdetail as a class. This displays further stats for the weather. Both the initial view and the update from clicking More Details are shown below:
