In the settings section, click Custom apps in the column on the right hand side to access the list of own apps that you have created. You can add and edit your own apps and remove existing ones, provided that they are not currently in use.
The way it works is that you write your own Transformation logic in the Javascript programming language to transform the data from your source into one or more "articles". An "article" is much like a news article and can be shown either one at a time upon each new page transition or as a ticker of multiple consecutive articles.
You start by configuring a number of base properties. Some of these are core to the app and its structure, which means that they cannot be changed by the end user when he/she uses the app in the designer. Other base properties can be changed by the end user and the values you configure here will be the app's default values in the designer.
Property | Explanation | Can be changed by the end user |
---|---|---|
Web address of data source | The web address (URL) of the JSON or XML datasource. You can use app specific properties between double curly brackets as a variable in the address. XML data that is returned by the data source is converted to a JSON structure so that it can easily be used in the transformation logic. |
No |
Refresh icon | (Re)load the source and display the next article or start running the ticker. | N/A |
Source online accessible within my network | (Only if the request method is "GET") Indicates that the data source sits within you own network (intranet) and cannot be accessed over the public internet. If the playback devices are on the same internal network as the data source they should be able to retrieve the data this way. It's important that the source server has the right CORS configuration. You need one configuration for allowed origin http://*.tplusv.tv and one for https://*.tplusv.tv with:
|
No |
Request method | Select the HTTP request method. In almost all cases this will be GET. | No |
Request body | (Only for request method "POST" or "PUT") Configure the datastructure that is sent to the server with the HTTP POST or HTTP PUT request. | No |
Style | Sets the way you like your articles to be displayed:
|
No |
Base font type | Sets the base font type from which you can deviate using the fontType formatting function in the transformation logic. | Yes |
Base text size | Sets the base text size. You can use the relativeTextSize formatting function in the transformation logic to make parts of your text smaller or larger. | Yes |
Base Line spacing | (Only if the app is available as "Single article" or "Vertical ticker") Sets the space between you lines. | Yes |
Base text color | Sets the base text color which you can deviate using the textColor formatting function in the transformation logic. | Yes |
Alignment | Set the way you like the text within the element to be aligned: to the left, centered, to the right or justified. | Yes |
The advanced options section provides you with a couple of specific parameters that you might need to get your app to work correctly.
Property | Explanation | Can be changed by the end user |
---|---|---|
Refresh interval | This let's you specify the frequency with which the app needs to poll the data source for new data during playback. | No |
Content type | Some data sources require you to explicitly specify what format you like the content to be in. This let's you specify that. | No |
Authorization type | If your data source requires you to be authorized, this let's you specify the type of authorization that you want to use. The options are:
|
No |
Basic auth. username | When the source requires basic authentication, this enables you to set the username. | No |
Basic auth. password | When the source requires basic authentication, this enables you to set the password. | No |
Authorization header | When the source requires an authorization header or OAuth2, this enables you specify the contents of the header. | No |
Generic header | When the source requires a proprietary header for authentication, you can use this field to specify the value. The format is [header name1]: [header value1], [header name2]: [header value2], e.g. Subscription-Key: 34A55dd8fd8ad9a4345fb46d42, API-key: acme . |
No |
OAuth provider | When the source requires an OAuth2 connection to be made, you need to select the OAuth provider) that is configured for your data source. You can create/edit OAuth provider configurations by clicking on the gear/settings icon next to the select box. The test account that is associated with the selected OAuth provider is also the account that will be used when this app is used by the end user. Once you have selected an OAuth provider with an attached OAuth account, you need make sure that the access token that is associated with the test account, is passed along in the request to the data source. In general a provider requires you to pass it either as an URL parameter or as a header. Either way, you can use the predefined system-property called {{accessToken}} to have T+V Play insert the right access token in the right place. E.g. as URL: https://api.geonames.org/SearchJSON?placename={{locationName}}&accessToken={{accessToken}} or as authorization header: Bearer {{accessToken}} . |
No |
Transformation logic is written in the programming language Javascript. There are a number of basic objects and functions available that enable you to format data you get from the data source. Please read the transformation logic guide to learn how to write correct transformation logic.
Apart from the base properties, you can also create your own app-specific properties that you can use in the web address of the data source as well as your transformation logic. This allows the end user to customize the app's behavior when it's used on a specific page.
Each app-specific property is defined by its:
[value1,label1],[value2,label2],...(etc.)
, where the values are the only things you work with in the web address and transformation logic. The labels are only shown to the end-user when he configures the app. In general you want values and labels to be strings of letters (and optionally digits), in which case you need to enclose them between quotes. For example ["NY","New York"],["LA","Los Angeles"],["SF","San Francisco"]
shows the end user a list of three city names. The code of the selected city is available in your app. The default and test values must not be enclosed in quotes, so you can simply fill out (e.g.) NY
.NY,LA
.You can reference app-specific properties by their "camelized" name. This means the name is transformed as follows:
For example:
"Location name" => "locationName"
"CODE" => "cODE"
"App-specific property" => "appSpecificProperty"
In the web address of the data source, you can embed a property by enclosing it in double curly brackets: {{locationName}}
.
For example:
https://api.geonames.org/SearchJSON?placename={{locationName}}&username=demo
In case of a multi-select enumeration property, the value will be a comma separated list of selected options.
In the transformation logic you can reference the property through the app.props
object, like so: app.props.locationName
.
You can use the app-specific properties in the request body in a similar manner as in the web address: by enclosing the property in double curly brackets. But this goes even further: you can write your request body as a Mustache template, which gives you additional convenient options like conditional rendering of text.
In some cases a preset value is not sufficient and you have to pass a dynamic or calculated value along with a request. For this you can use bits of Javascript code (which is also the basis for transformation logic) in both the web address and the request body. The code should be placed in a block that starts with [[=
and ends with ]]
. For example:
<StartDate>[[= new Date().toISOString()]]</StartDate>.
Multiple lines are also possible. In that case, the result of the last line is the value used. For example:
<AuthToken>[[=
var key = "foobar";
var secret = "12345678";
var param = new Date().toISOString();
MD5(key + secret + param); // The result of this statement appears in AuthToken
]]
</AuthToken>
Two useful Javascript libraries are available by default in your code:
With MomentJS you can easily create formatted date and time strings:
<StartDate>[[= moment().format("MM/DD/YYYY")]]</StartDate>
You can also use the values of app-specific properties in your code by using these properties as described above: between double curly brackets, for example:
<EndDate>[[= moment().add({{daysAhead}}},'days').format("MM/DD/YYYY")]]</EndDate>
The Input/error inspector is a section that is collapsed by default, but can be opened and closed again by clicking on the title. When opened it will show the latest input that has been retrieved from the data source in a browsable way. This makes it a lot easier to find the right data you need in your transformation logic.
The Errors section will show errors that occur when retrieving data or executing your transformation logic.
In a "mini page" the rendered output is shown as it would be displayed when the app is used. When you click the Refresh icon, the next formatted article will be shown here or the running ticker with the formatted output.
By default the sample page has a white background, but if you are creating the app with light colors to specifically be used (by default) on a dark background, you can use the Sample background color color picker to display the app against a fitting background.
Within your company, you can configure multiple OAuth providers. An OAuth provider is a configuration to access an OAuth2 app that you have configured on a specific third party website. E.g. let's say you like to access the LinkedIn API. Then you need to have a LinkedIn account with which you go to LinkedIn's Developer section. There you create a new "app" through which you can access the LinkedIn data on behalf of yourself. You don't need much to configure such an "app"; the most important thing is that you need to specify the right callback URL, which should be set to:
https://screens.tplusv.tv/auth/oauth2_generic/callback
On the T+V Play end, you need to configure the settings listed below:
Property | Explanation |
---|---|
Name | Give your OAuth provider an appropriate name, since this will be shown in the selection box when configuring your app. E.g. "LinkedIn". |
Client ID | Fill in the client ID/key provided by the third party OAuth2 app you created. |
Client secret | Fill in the client secret provided by the third party OAuth2 app you created. |
User info URL | Fill in the full URL of where the OAuth2 user info can be retrieved from this provider. |
Authorization URL | Fill in the full OAuth2 authorization URL from this provider. |
Token URL | Fill in the full OAuth2 token URL from this provider. |
Scope | Fill in the scope for which you are requesting authorization. This needs to match the scopes that you specified in the third party app. If multiple keywords need to be specified, you generally separate them with a space. For instance r_liteprofile r_emailaddress r_organization_social . |
Path to email | (optional) The path to the attribute in the user info response where the user's email can be found. E.g. when the response is something like { user: { info: { email: "foo@bar.com", firstName: "Foo", lastName: "Bar" }}} , then specify the path, using a forward slash separator like so: user/info/email . |
Path to first name | (optional) The path to the attribute in the user info response where the user's first name can be found. E.g. in case of the user info response example above, specify the path, using a forward slash separator like so: user/info/firstName . |
Path to last name | The path to the attribute in the user info response where the user's last name can be found. E.g. in case of the user info response example above, specify the path, using a forward slash separator like so: user/info/lastName . |
Test account | Once your provider is configured correctly, you need to connect your own user account to it so that data can be retrieved on behalf of you. This can be done by clicking the Connect test account button. Note that this is also the account that will be used during playback of the app in which this OAuth provider is used. |