### Example: Read XML Config File
Source: https://github.com/onsigntv/apps/blob/master/docs/JSBRIDGE.md
Demonstrates reading an XML configuration file using its ContentID. This example loads the SDK, configures an XML input, and then reads the content.
```html+jinja
{{ entry.title }}
{# More info on formatting dates at http://strftime.org/ #}
{{ entry.publish_date.strftime("%m/%d/%Y") }}
{% if entry.content %}
{{ entry.content }}
{% endif %}
{% if entry.image %}

{% endif %}
{% if entry.extra %}
{{ entry.extra.summary }}
{% endif %}
{% endfor %}
```
--------------------------------
### HTML Structure and Styling
Source: https://github.com/onsigntv/apps/blob/master/samples/datafeed-media-cycling/app.html
Basic HTML and CSS setup for the media cycling app, ensuring elements fill the available space and defining styles for play buttons and aspect ratio adjustments.
```html
html, body { margin: 0; padding: 0; overflow: hidden; background-color: transparent; }
html, body, img, video, #container, #play-box { width: 100%; height: 100%; }
img, video { object-fit: contain; }
#container, #play-box { display: flex; align-items: center; justify-content: center; }
#play-box { position: absolute; background-color: rgba(0, 0, 0, 0.5); }
.play-btn { width: 80px; height: 80px; background-color: rgba(0, 0, 0, 0.5); border: 2px solid #fff; border-radius: 50%; position: relative; cursor: pointer; }
.play-btn::before { content: ''; position: absolute; top: 18px; left: 28px; border-style: solid; border-width: 20px 0 20px 30px; border-color: transparent transparent transparent #fff; }
.fit-height { height: 100%; width: auto; }
.fit-width { width: 100%; height: auto; }
.fill { object-fit: fill; }
.cover { object-fit: cover; }
```
--------------------------------
### Handle Signage Visibility and Timer
Source: https://github.com/onsigntv/apps/blob/master/samples/weather/small-weather-forecast/app.html
Starts a timer to cycle through forecast displays only after the application becomes visible on screen. This ensures resources are not wasted when the app is not in view.
```javascript
// window.signageVisible resolves when the app becomes visible on screen.
// Start the day-cycling timer only after the app is actually visible.
// For more info on signage promises, check: https://github.com/onsigntv/apps/blob/master/docs/JSBRIDGE.md#signagevisible
window.signageVisible.then(function() {
var activeForecast = 1;
window.setInterval(function cycleWeather() {
activeForecast += 1;
if (activeForecast > 3) {
activeForecast = 1;
}
document.querySelector('.forecast').setAttribute('data-active', activeForecast);
}, 5000);
});
```
--------------------------------
### Load Facebook SDK
Source: https://github.com/onsigntv/apps/blob/master/samples/social/facebook/app.html
Ensure the Facebook SDK is loaded in all applications using Javascript before initializing the configuration. Refer to the provided GitHub link for detailed setup instructions.
```html
{{ __loadsdk__ }}
```
--------------------------------
### Choice Configuration using Meta Tags
Source: https://github.com/onsigntv/apps/blob/master/docs/USERCONF.md
Configure user choices using multiple meta tags with the same name. The 'value' attribute is mandatory. This example sets the background color.
```html+jinja
Title
Subtitle
Have fun styling your text with a variety of options.
This is a WYSIWYG editor. Be creative!
```
--------------------------------
### Start Quote Loop After Visibility
Source: https://github.com/onsigntv/apps/blob/master/samples/datafeed-movie-quotes/app.html
Starts the quote loop only after both the data feed has loaded and the signage becomes visible. Includes a timeout to synchronize timers on Android devices.
```javascript
Promise.all([window.dataFeed, window.signageVisible]).then(function() {
// Sometimes Android devices have a slightly offset time between Android
// and Javascript timers. This was causing some apps to flash a new item
// before it is changed to a different content.
// The 500ms timeout below fixes this issue and ensures the current position is
// correcly saved through `localStorage`.
// The first item will be shown for an additional 500ms.
setTimeout(function() {
// Initializes the quote loop and sets the interval for content updates
// based on the configured display duration. Ensures each quote is shown
// for the specified number of seconds before changing to the next.
setInterval(renderData, Math.max(window.appConfig.quote_duration * 1000, 1000));
}, 500);
});
```
--------------------------------
### Load SDK and Configuration
Source: https://github.com/onsigntv/apps/blob/master/samples/weather/weather-forecast-horizontal-bar/app.html
Ensures the SDK is loaded before configuration. Provides links to user configuration documentation.
```html
{# Make sure you load the SDK in all apps that use Javascript before starting configuration! #}
{{ __loadsdk__ }}
{# Check https://github.com/onsigntv/apps/blob/master/docs/USERCONF.md for info on how to add user-configurable variables. #}
```
--------------------------------
### Initialize Weather Data and Display
Source: https://github.com/onsigntv/apps/blob/master/samples/weather/small-weather-forecast/app.html
Sets up global variables for forecast data, localization strings, and temperature scale. It then defines functions to display temperature and the daily forecast, and loads the initial forecast data.
```javascript
var PRELOADED_FORECAST = {{ weather.forecast_data|safe }};
var TODAY = { 'pt-br': 'hoje', 'es': 'hoy', 'en': 'today', 'it': 'oggi', 'da': 'i dag', 'fr': "aujourd'hui", 'nn': 'i dag', 'sv': 'i dag', 'zh': '今天', 'ja': '今日' }['{{ lang }}'];
var WEEK_DAYS = { 'pt-br': ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab'], 'es': ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab'], 'en': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 'it': ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'], 'da': ['søn', 'man', 'tir', 'ons', 'tor', 'fre', 'lør'], 'fr': ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'], 'nn': ['sun', 'mån', 'tys', 'ons', 'tor', 'fre', 'lau'], 'sv': ['sön', 'mån', 'tis', 'ons', 'tor', 'fre', 'lör'], 'zh': ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], 'ja': ['日', '月', '火', '水', '木', '金', '土'] }['{{ lang }}'];
var SCALE = '{{ scale }}';
function displayTemperature(celsius) {
celsius = parseInt(celsius, 10);
if (!isFinite(celsius)) {
return '-';
}
// If the scale is in Fahrenheit we must convert
if (SCALE == 'f') {
celsius = (celsius * 1.8) + 32;
}
return Math.round(celsius) + '°';
}
function displayForecast(forecast) {
var today = Math.floor((Date.now() + (forecast.offset * 60 * 60 * 1000)) / (1000 * 60 * 60 * 24)) * (60 * 60 * 24);
var weekday = (new Date()).getDay();
var forecasts = document.querySelectorAll('.forecast-day');
for (var i = 0; i < forecasts.length; i++) {
var el = forecasts[i];
var date = today + (3600 * 24 * i);
el.className = 'forecast-day ' + forecast.daily[date].icon;
el.querySelector('.max').innerHTML = displayTemperature(forecast.daily[date].temperatureMax);
el.querySelector('.min').innerHTML = displayTemperature(forecast.daily[date].temperatureMin);
if (i === 0) {
el.querySelector('.date').innerHTML = TODAY;
} else {
el.querySelector('.date').innerHTML = WEEK_DAYS[(weekday + i) % 7];
}
}
}
function loadForecast() {
var forecast = PRELOADED_FORECAST;
try {
var cached = JSON.parse(localStorage.getItem('weather:{{ weather.forecast_url }}'));
if (cached) {
var max_cached = Math.max.apply(window, Object.keys(cached.hourly));
var max_preloaded = Math.max.apply(window, Object.keys(PRELOADED_FORECAST.hourly));
if (max_cached > max_preloaded) {
forecast = cached;
}
}
} catch (e) {
console.log("Unable to use cached data", e);
}
try {
displayForecast(forecast);
} catch (e) {
console.error('got exception loading weather', e);
}
var now = Math.floor((Date.now() + (forecast.offset * 60 * 60 * 1000)) / (1000 * 60 * 60)) * (60 * 60);
var hourly = Object.keys(forecast.hourly).sort();
var position = hourly.indexOf('' + now);
if (position < 0 || position >= 3) {
var request = new XMLHttpRequest();
request.open('GET', '{{ weather.forecast_url }}', true);
request.onload = function apiResponse() {
if (request.status >= 200 && request.status < 400) {
try {
var forecast = JSON.parse(request.responseText);
displayForecast(forecast);
// Try to save it locally as a cache
localStorage.setItem('weather:{{ weather.forecast_url }}', request.responseText);
} catch (e) {
console.error('Unable to update weather', e);
}
}
};
request.send();
}
}
loadForecast();
```
--------------------------------
### Load SDK and Configure App
Source: https://github.com/onsigntv/apps/blob/master/samples/rss/uol-rss/app2.html
Ensures the SDK is loaded before app configuration. User-configurable variables can be added as described in the provided documentation link.
```html
{# Make sure you load the SDK in all apps that use Javascript before starting configuration! #}
{{ __loadsdk__ }}
{# Check https://github.com/onsigntv/apps/blob/master/docs/USERCONF.md for info on how to add user-configurable variables. #}
{{ __config__(name="section", type="choice", label="Categoria:", choices=[
("world", "UOL - Internacional"),
("sports", "UOL - Esportes"),
("economy", "UOL - Economia"),
("daily", "UOL - Cotidiano"),
("celebrities", "UOL - Celebridades"),
("politics", "UOL - Política"),
("entertainment", "UOL - Entretenimento"),
("television", "UOL - Televisão"),
]) }}
{{ __config__(name="duration", type="number", label="Mostrar cada notícia por (segundos)", value=10, js=True) }}
{{ __config__(name="animation", type="bool", label="Animação entre as notícias", value=True) }}
```
--------------------------------
### signage.getBrightness
Source: https://github.com/onsigntv/apps/blob/master/docs/JSBRIDGE.md
Get the current value of screen brightness, from 0 to 100.
```APIDOC
## signage.getBrightness
### Description
Get the current value of screen brightness, from `0` to `100`.
### Method
`signage.getBrightness()`
### Response
#### Success Response
- **value** (number) - The current screen brightness level (0-100).
```
--------------------------------
### Load SDK and Configuration
Source: https://github.com/onsigntv/apps/blob/master/samples/weather/weather-forecast-bar/app.html
Ensures the SDK is loaded and provides configuration options for location, language, and temperature scale. User-configurable variables are managed via the __config__ function.
```html
{# Make sure you load the SDK in all apps that use Javascript before starting configuration! #} {{ __loadsdk__ }} {# Check https://github.com/onsigntv/apps/blob/master/docs/USERCONF.md for info on how to add user-configurable variables. #} {{ __config__(name="weather", type="location", label="Forecast location", help="Type the location of the forecast and choose from the dropdown") }} {{ __config__(name="lang", type="choice", label="Language", choices=["en", "pt-br", "es", "it", "da", "fr", "nn", "sv", "zh", "ja"]) }} {{ __config__(name="weather_format", type="choice", label="Temperature Scale", choices=["fahrenheit", "celsius"]) }}
```
--------------------------------
### Font Face and Family CSS
Source: https://github.com/onsigntv/apps/blob/master/docs/USERCONF.md
These examples show the resulting CSS for `@font-face` and `font-family` when a font is selected.
```html
```
--------------------------------
### signage.ttsStop
Source: https://github.com/onsigntv/apps/blob/master/docs/JSBRIDGE.md
Stops any utterance currently being spoken. If there are enqueued utterances, the oldest one is immediately dequeued and started.
```APIDOC
## `signage.ttsStop()`
### Description
Stops any utterance currently being spoken. If there are enqueued utterances, the oldest one is immediately dequeued and started. To completely stop the engine, call `signage.ttsFlush()` before calling `signage.ttsStop()`.
```
--------------------------------
### Check App Visibility
Source: https://github.com/onsigntv/apps/blob/master/docs/JSBRIDGE.md
Returns a boolean indicating whether the app is currently visible. Apps are often preloaded before playback starts.
```javascript
console.log('App is visible?', signage.isVisible());
```
--------------------------------
### signage.getVolume
Source: https://github.com/onsigntv/apps/blob/master/docs/JSBRIDGE.md
Get the current hardware volume, from 0 to 100. This method represents the volume of the hardware itself, not the volume your app is configured to use.
```APIDOC
## signage.getVolume
### Description
Get the current hardware volume, from `0` to `100`. This method represents the volume of the hardware itself, not the volume your app is configured to use.
### Method
`signage.getVolume()`
### Response
#### Success Response
- **value** (number) - The current hardware volume level (0-100).
```
--------------------------------
### Get Screen Brightness
Source: https://github.com/onsigntv/apps/blob/master/docs/JSBRIDGE.md
Retrieves the current screen brightness level, ranging from 0 to 100. This value reflects hardware or software configuration.
```javascript
signage.getBrightness()
```
--------------------------------
### Configure Facebook Feed
Source: https://github.com/onsigntv/apps/blob/master/samples/social/facebook/app.html
Configure the Facebook feed with a name, type, label, and help text. The feed URL must start with 'https://www.facebook.com/'.
```html
{{ __config__(name="feed", type="webfeed", label="Facebook page", help="Enter the Facebook page URL you want to show. It should start with https://www.facebook.com/") }}
```
--------------------------------
### App Configuration with __config__
Source: https://github.com/onsigntv/apps/blob/master/docs/USERCONF.md
This Jinja2 template demonstrates how to use the `__config__` function to define various configuration parameters for an application, including text input and color pickers. It shows how to set default values, labels, and optional groups for these configurations.
```html+jinja