Files
Cloud-CMS/modules/templates/article-static.xml

1455 lines
52 KiB
XML
Raw Normal View History

2025-12-02 10:32:59 -05:00
<!--
~ Copyright (C) 2023 Xibo Signage Ltd
~
~ Xibo - Digital Signage - https://xibosignage.com
~
~ This file is part of Xibo.
~
~ Xibo is free software: you can redistribute it and/or modify
~ it under the terms of the GNU Affero General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ any later version.
~
~ Xibo is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU Affero General Public License for more details.
~
~ You should have received a copy of the GNU Affero General Public License
~ along with Xibo. If not, see <http://www.gnu.org/licenses/>.
-->
<templates>
<template>
<id>article_custom_html</id>
<type>static</type>
<dataType>article</dataType>
<showIn>none</showIn>
<title>Articles shown with custom HTML</title>
<properties>
<property id="customTemplate" type="hidden">
<default>1</default>
</property>
<property id="moduleType" type="hidden">
<default>article</default>
</property>
<property id="effect" type="effectSelector" variant="all">
<title>Effect</title>
<helpText>Please select the effect that will be used to transition between items.</helpText>
<default>noTransition</default>
</property>
<property id="speed" type="number">
<title>Speed</title>
<helpText>The transition speed of the selected effect in milliseconds (normal = 1000) or the Marquee Speed in a low to high scale (normal = 1)</helpText>
<default>1000</default>
</property>
<property id="itemsSideBySide" type="checkbox">
<title>Show items side by side?</title>
<helpText>Should items be shown side by side?</helpText>
<default>0</default>
</property>
<property id="itemsPerPage" type="number">
<title>Items per page</title>
<helpText>If an effect has been selected from the General tab, how many pages should we split the items across? If you don't enter anything here 1 item will be put on each page.</helpText>
<default>1</default>
</property>
<property id="dateFormat" type="text" variant="dateFormat">
<title>Date Format</title>
<helpText>The format to apply to all dates returned by the Widget.</helpText>
<default>#DATE_FORMAT#</default>
</property>
<property id="backgroundColor" type="color">
<title>Background Colour</title>
<helpText>The selected effect works best with a background colour. Optionally add one here.</helpText>
<default></default>
</property>
<property id="textDirection" type="dropdown" mode="single">
<title>Text direction</title>
<helpText>Which direction does the text in the feed use?</helpText>
<default>ltr</default>
<options>
<option name="ltr">Left to Right (LTR)</option>
<option name="rtl">Right to Left (RTL)</option>
</options>
</property>
<property id="template" type="code" allowLibraryRefs="true" variant="html">
<title>Item Template</title>
<helpText>Enter text in the box below, used to display each article.</helpText>
</property>
<property id="dataTypeSnippets" type="snippet" mode="dataType" target="template">
<title>Snippets</title>
<helpText>Choose element to add to template</helpText>
</property>
<property id="noDataMessage" type="code" allowLibraryRefs="true" variant="html">
<title>No data message</title>
<helpText>A message to display when no data is returned from the source</helpText>
</property>
<property id="css" type="code" allowLibraryRefs="true" variant="css">
<title>Optional Stylesheet Template</title>
</property>
<property id="javaScript" type="code" allowLibraryRefs="true" variant="javascript">
<title>Optional JavaScript</title>
<helpText>Add JavaScript to be included immediately before the closing body tag. Do not use [] array notation as this is reserved for library references. Do not include script tags.</helpText>
</property>
<property id="copyright" type="text">
<title>Copyright</title>
<helpText>Copyright information to display as the last item in this feed.</helpText>
</property>
</properties>
<stencil>
<twig><![CDATA[
{% if javaScript %}<script type="text/javascript">{{javaScript|raw}}</script>{% endif %}
]]></twig>
<style><![CDATA[
{% if css or itemsSideBySide or backgroundColor or textDirection == "rtl" %}
{% if itemsSideBySide %}.text-render-item, .page { float: left; }{% endif %}
{% if textDirection == "rtl" %}#content { direction: rtl; }{% endif %}
{% if backgroundColor %}body { background-color: {{backgroundColor}} !important; }{% endif %}
{{css|raw}}
{% endif %}
]]></style>
</stencil>
<onTemplateRender><![CDATA[
// id: The id of the widget
// target: The target element to render
// items: The items to render
// properties: The properties for the widget
// -------------------------------------------
if (items.length > 0) {
items = $(items).xiboSubstitutesParser(properties.template, properties.dateFormat, ['date', 'publishedDate'], {
description: 'summary',
copyright: 'author',
});
}
// No data message
if (items.length <= 0 && properties.noDataMessage && properties.noDataMessage !== '') {
items.push(properties.noDataMessage);
}
// Copyright
if (properties.copyright) {
items.push({
title: properties.copyright
});
}
// Clear container
$(target).find('#content').empty();
// Add items to container
for (var index = 0; index < items.length; index++) {
var $newItem = $('<div>').addClass('item').html(items[index]);
$(target).find('#content').append($newItem);
}
// Render
$(target).xiboLayoutScaler(properties);
$(target).xiboTextRender(properties, $(target).find('#content > *'));
$(target).find('img').xiboImageRender(properties);
]]></onTemplateRender>
<onTemplateVisible><![CDATA[
// Start effects for this template
$(target).xiboLayoutAnimate(properties);
]]></onTemplateVisible>
</template>
<template>
<id>article_image_only</id>
<type>static</type>
<dataType>article</dataType>
<title>Image only</title>
<thumbnail>article_image_only</thumbnail>
<startWidth>600</startWidth>
<startHeight>400</startHeight>
<properties>
<property id="backgroundColor" type="color">
<title>Background</title>
<default></default>
</property>
<property id="itemImageFit" type="dropdown" mode="single">
<title>Image Fit</title>
<helpText>How should images be scaled by default?</helpText>
<default>contain</default>
<options>
<option name="contain">Contain</option>
<option name="cover">Cover</option>
<option name="fill">Fill</option>
</options>
</property>
<property id="effect" type="effectSelector" variant="showPaged">
<title>Effect</title>
<helpText>Please select the effect that will be used to transition between items.</helpText>
<default>noTransition</default>
</property>
<property id="speed" type="number">
<title>Speed</title>
<helpText>The transition speed of the selected effect in milliseconds (normal = 1000).</helpText>
</property>
<property id="noDataMessage" type="richText" allowLibraryRefs="true" variant="html">
<title>No data message</title>
<helpText>A message to display when no data is returned from the source</helpText>
</property>
<property id="copyright" type="text">
<title>Copyright</title>
<helpText>Copyright information to display as the last item in this feed.</helpText>
</property>
</properties>
<stencil>
<hbs><![CDATA[
<div class="image">
{{#if image}}<img src="{{image}}"/>{{/if}}
</div>
]]></hbs>
<style><![CDATA[
#content, .text-render-item, .image, .image img {
width:100%; height: 100%;
}
.image img {
object-fit: {{itemImageFit}} !important;
}
{% if backgroundColor %}
body {
background-color: {{backgroundColor}} !important;
}
{% endif %}
{% if copyright %}
.copyright {
width: 100%;
height: 100%;
text-align: center;
}
.copyright span {
position: relative;
font-size: 30px;
line-height: 0;
top: 50%;
transform: translateY(-50%);
}
{% endif %}
]]></style>
</stencil>
<onTemplateRender><![CDATA[
// id: The id of the widget
// target: The target element to render
// items: The items to render
// properties: The properties for the widget
// -------------------------------------------
// No data message
if (items.length <= 0 && properties.noDataMessage && properties.noDataMessage !== '') {
$(target).find('#content').append(properties.noDataMessage);
}
// Add copyright if we have at least one item
// and copyright is not already added
if (
properties.copyright &&
$(target).find('#content > .image').length > 0 &&
$(target).find('#content > .copyright').length <= 0
) {
$(target).find('#content').append(
$('<div class="copyright"><span>' + properties.copyright + '</span></div>')
);
// Increase numItems to include the copyright
properties.numItems = parseInt(properties.numItems) + 1;
}
// Render
$(target).xiboLayoutScaler(properties);
$(target).xiboTextRender(properties, $(target).find('#content > .image, #content > .copyright'));
$(target).find('img').xiboImageRender(properties);
]]></onTemplateRender>
<onTemplateVisible><![CDATA[
// Start effects for this template
$(target).xiboLayoutAnimate(properties);
]]></onTemplateVisible>
<assets>
<asset id="article_image_only" type="path" cmsOnly="true" mimeType="image/png" path="/modules/assets/template-thumbnails/article/image-only.png" />
</assets>
</template>
<template>
<id>article_with_left_hand_text</id>
<type>static</type>
<dataType>article</dataType>
<title>Image overlaid with the Feed Content on the Left</title>
<thumbnail>article_with_left_hand_text</thumbnail>
<startWidth>600</startWidth>
<startHeight>400</startHeight>
<properties>
<property id="backgroundColor" type="color">
<title>Background</title>
<default></default>
</property>
<property id="itemBackgroundColor" type="color">
<title>Background (content)</title>
<default>black</default>
</property>
<property id="backgroundOpacity" type="number">
<title>Background opacity (content)</title>
<default>0.6</default>
</property>
<property id="itemTitleColor" type="color">
<title>Title</title>
<default>white</default>
</property>
<property id="itemDescriptionColor" type="color">
<title>Description</title>
<default>white</default>
</property>
<property id="itemFontSize" type="number">
<title>Font Size</title>
<default>16</default>
</property>
<property id="fontFamily" type="fontSelector">
<title>Font</title>
<helpText>Select a custom font - leave empty to use the default font.</helpText>
</property>
<property id="itemImageFit" type="dropdown" mode="single">
<title>Image Fit</title>
<helpText>How should images be scaled by default?</helpText>
<default>contain</default>
<options>
<option name="contain">Contain</option>
<option name="cover">Cover</option>
<option name="fill">Fill</option>
</options>
</property>
<property id="effect" type="effectSelector" variant="showPaged">
<title>Effect</title>
<helpText>Please select the effect that will be used to transition between items.</helpText>
<default>noTransition</default>
</property>
<property id="speed" type="number">
<title>Speed</title>
<helpText>The transition speed of the selected effect in milliseconds (normal = 1000).</helpText>
</property>
<property id="noDataMessage" type="richText" allowLibraryRefs="true" variant="html">
<title>No data message</title>
<helpText>A message to display when no data is returned from the source</helpText>
</property>
<property id="copyright" type="text">
<title>Copyright</title>
<helpText>Copyright information to display as the last item in this feed.</helpText>
</property>
</properties>
<stencil>
<hbs><![CDATA[
<div class="image">
{{#if image}}<img src="{{image}}"/>{{/if}}
<div class="cycle-overlay background">
<div class="title">{{title}}</div>
<div class="description">{{{summary}}}</div>
</div>
</div>
]]></hbs>
<style><![CDATA[
html {
/* Global font size, change for font scale */
font-size: 16px;
}
#content, .text-render-item, .image, .image img {
width: 100%;
height: 100%;
}
.cycle-overlay {
display: flex;
flex-direction: column;
justify-content: center;
color: white;
background: black;
position: absolute;
bottom: 0;
top: 0px;
width: 20%;
height: 100%;
padding: 0.8rem;
}
.cycle-overlay>div {
font-family: Arial, Verdana, sans-serif;
}
.cycle-overlay .title {
font-size: 1.2rem;
color: white;
font-weight: bold;
}
.cycle-overlay .description {
font-size: 1rem;
margin-top: 1rem;
}
{% if backgroundColor %}
body {
background-color: {{backgroundColor}} !important;
}
{% endif %}
{% if backgroundOpacity %}
.cycle-overlay {
opacity: {{backgroundOpacity}};
filter: alpha(opacity={{backgroundOpacity*100}});
}
{% endif %}
{% if itemImageFit %}
.image img {
object-fit: {{itemImageFit}};
}
{% endif %}
{% if itemBackgroundColor %}
.background {
background-color: {{itemBackgroundColor}} !important;
}
{% endif %}
{% if itemTitleColor %}
.title {
color: {{itemTitleColor}} !important;
}
{% endif %}
{% if itemDescriptionColor %}
.description {
color: {{itemDescriptionColor}} !important;
}
{% endif %}
{% if itemFontSize %}
html {
font-size: {{itemFontSize}}px !important;
}
{% endif %}
{% if fontFamily %}
.description, .title {
font-family: {{fontFamily}} !important;
}
{% endif %}
{% if copyright %}
.copyright {
width: 100%;
height: 100%;
text-align: center;
}
.copyright span {
position: relative;
font-size: 30px;
line-height: 0;
top: 50%;
transform: translateY(-50%);
}
{% endif %}
]]></style>
</stencil>
<onTemplateRender><![CDATA[
// id: The id of the widget
// target: The target element to render
// items: The items to render
// properties: The properties for the widget
// -------------------------------------------
// No data message
if (items.length <= 0 && properties.noDataMessage && properties.noDataMessage !== '') {
$(target).find('#content').append(properties.noDataMessage);
}
// Add copyright if we have at least one item
// and copyright is not already added
if (
properties.copyright &&
$(target).find('#content > .image').length > 0 &&
$(target).find('#content > .copyright').length <= 0
) {
$(target).find('#content').append(
$('<div class="copyright"><span>' + properties.copyright + '</span></div>')
);
// Increase numItems to include the copyright
properties.numItems = parseInt(properties.numItems) + 1;
}
// Render
$(target).xiboLayoutScaler(properties);
$(target).xiboTextRender(properties, $(target).find('#content > .image, #content > .copyright'));
$(target).find('img').xiboImageRender(properties);
]]></onTemplateRender>
<onTemplateVisible><![CDATA[
// Start effects for this template
$(target).xiboLayoutAnimate(properties);
]]></onTemplateVisible>
<assets>
<asset id="article_with_left_hand_text" type="path" cmsOnly="true" mimeType="image/png" path="/modules/assets/template-thumbnails/article/image-with-left-hand-text.png" />
</assets>
</template>
<template>
<id>article_with_title</id>
<type>static</type>
<dataType>article</dataType>
<title>Image overlaid with the Title</title>
<thumbnail>article_with_title</thumbnail>
<startWidth>600</startWidth>
<startHeight>400</startHeight>
<properties>
<property id="backgroundColor" type="color">
<title>Background</title>
<default></default>
</property>
<property id="itemBackgroundColor" type="color">
<title>Background (content)</title>
<default>black</default>
</property>
<property id="backgroundOpacity" type="number">
<title>Background opacity (content)</title>
<default>0.6</default>
</property>
<property id="itemTitleColor" type="color">
<title>Title</title>
<default>white</default>
</property>
<property id="itemFontSize" type="number">
<title>Font Size</title>
<default>16</default>
</property>
<property id="fontFamily" type="fontSelector">
<title>Font</title>
<helpText>Select a custom font - leave empty to use the default font.</helpText>
</property>
<property id="itemImageFit" type="dropdown" mode="single">
<title>Image Fit</title>
<helpText>How should images be scaled by default?</helpText>
<default>contain</default>
<options>
<option name="contain">Contain</option>
<option name="cover">Cover</option>
<option name="fill">Fill</option>
</options>
</property>
<property id="effect" type="effectSelector" variant="showPaged">
<title>Effect</title>
<helpText>Please select the effect that will be used to transition between items.</helpText>
<default>noTransition</default>
</property>
<property id="speed" type="number">
<title>Speed</title>
<helpText>The transition speed of the selected effect in milliseconds (normal = 1000).</helpText>
</property>
<property id="noDataMessage" type="richText" allowLibraryRefs="true" variant="html">
<title>No data message</title>
<helpText>A message to display when no data is returned from the source</helpText>
</property>
<property id="copyright" type="text">
<title>Copyright</title>
<helpText>Copyright information to display as the last item in this feed.</helpText>
</property>
</properties>
<stencil>
<hbs><![CDATA[
<div class="image">
{{#if image}}<img src="{{image}}"/>{{/if}}
<div class="cycle-overlay background">
<div class="title">{{title}}</div>
</div>
</div>
]]></hbs>
<style><![CDATA[
html {
/* Global font size, change for font scale */
font-size: 16px;
}
#content, .text-render-item, .image, .image img {
width: 100%;
height: 100%;
}
.image img {
object-fit: cover;
}
.cycle-overlay {
color: white;
background: black;
position: absolute;
bottom: 0;
width: 100%;
padding: 2rem 0;
text-align: center;
}
.cycle-overlay>div {
font-family: Arial, Verdana, sans-serif;
}
.cycle-overlay .title {
font-size: 1.2rem;
color: white;
font-weight: bold;
}
{% if backgroundColor %}
body {
background-color: {{backgroundColor}} !important;
}
{% endif %}
{% if backgroundOpacity %}
.cycle-overlay {
opacity: {{backgroundOpacity}};
filter: alpha(opacity={{backgroundOpacity*100}});
}
{% endif %}
{% if itemImageFit %}
.image img {
object-fit: {{itemImageFit}};
}
{% endif %}
{% if itemBackgroundColor %}
.background {
background-color: {{itemBackgroundColor}} !important;
}
{% endif %}
{% if itemTitleColor %}
.title {
color: {{itemTitleColor}} !important;
}
{% endif %}
{% if itemFontSize %}
html {
font-size: {{itemFontSize}}px !important;
}
{% endif %}
{% if fontFamily %}
.title {
font-family: {{fontFamily}} !important;
}
{% endif %}
{% if copyright %}
.copyright {
width: 100%;
height: 100%;
text-align: center;
}
.copyright span {
position: relative;
font-size: 30px;
line-height: 0;
top: 50%;
transform: translateY(-50%);
}
{% endif %}
]]></style>
</stencil>
<onTemplateRender><![CDATA[
// id: The id of the widget
// target: The target element to render
// items: The items to render
// properties: The properties for the widget
// -------------------------------------------
// No data message
if (items.length <= 0 && properties.noDataMessage && properties.noDataMessage !== '') {
$(target).find('#content').append(properties.noDataMessage);
}
// Add copyright if we have at least one item
// and copyright is not already added
if (
properties.copyright &&
$(target).find('#content > .image').length > 0 &&
$(target).find('#content > .copyright').length <= 0
) {
$(target).find('#content').append(
$('<div class="copyright"><span>' + properties.copyright + '</span></div>')
);
// Increase numItems to include the copyright
properties.numItems = parseInt(properties.numItems) + 1;
}
// Render
$(target).xiboLayoutScaler(properties);
$(target).xiboTextRender(properties, $(target).find('#content > .image, #content > .copyright'));
$(target).find('img').xiboImageRender(properties);
]]></onTemplateRender>
<onTemplateVisible><![CDATA[
// Start effects for this template
$(target).xiboLayoutAnimate(properties);
]]></onTemplateVisible>
<assets>
<asset id="article_with_title" type="path" cmsOnly="true" mimeType="image/png" path="/modules/assets/template-thumbnails/article/image-with-title.png" />
</assets>
</template>
<template>
<id>article_with_desc_and_name_separator</id>
<type>static</type>
<dataType>article</dataType>
<title>Prominent title with description and name separator</title>
<thumbnail>article_with_desc_and_name_separator</thumbnail>
<startWidth>600</startWidth>
<startHeight>600</startHeight>
<properties>
<property id="backgroundColor" type="color">
<title>Background</title>
<default></default>
</property>
<property id="itemNameColor" type="color">
<title>Name</title>
<default>#000</default>
</property>
<property id="itemTitleColor" type="color">
<title>Title</title>
<default>#000</default>
</property>
<property id="itemDescriptionColor" type="color">
<title>Description</title>
<default>#000</default>
</property>
<property id="itemFontSize" type="number">
<title>Font Size</title>
<default>16</default>
</property>
<property id="fontFamily" type="fontSelector">
<title>Font</title>
<helpText>Select a custom font - leave empty to use the default font.</helpText>
</property>
<property id="effect" type="effectSelector" variant="all">
<title>Effect</title>
<helpText>Please select the effect that will be used to transition between items.</helpText>
<default>noTransition</default>
</property>
<property id="speed" type="number">
<title>Speed</title>
<helpText>The transition speed of the selected effect in milliseconds (normal = 1000) or the Marquee Speed in a low to high scale (normal = 1)</helpText>
<default>1000</default>
</property>
<property id="showSeparator" type="checkbox">
<title>Show a separator between items?</title>
<default>0</default>
<visibility>
<test type="or">
<condition field="effect" type="eq">marqueeLeft</condition>
<condition field="effect" type="eq">marqueeRight</condition>
<condition field="effect" type="eq">marqueeUp</condition>
<condition field="effect" type="eq">marqueeDown</condition>
</test>
</visibility>
</property>
<property id="showSideBySide" type="checkbox">
<title>Show items side by side?</title>
<default>0</default>
<visibility>
<test type="or">
<condition field="effect" type="eq">marqueeLeft</condition>
<condition field="effect" type="eq">marqueeRight</condition>
<condition field="effect" type="eq">marqueeUp</condition>
<condition field="effect" type="eq">marqueeDown</condition>
</test>
</visibility>
</property>
<property id="separator" type="richText" allowLibraryRefs="false" variant="html">
<title>Separator</title>
<helpText>A separator to show between marquee items</helpText>
<default>
<![CDATA[
<p><span style="font-size: 72px;">/</span></p>
]]></default>
<visibility>
<test type="and">
<condition field="effect" type="neq">none</condition>
<condition field="effect" type="neq">noTransition</condition>
<condition field="effect" type="neq">fade</condition>
<condition field="effect" type="neq">fadeout</condition>
<condition field="effect" type="neq">scrollHorz</condition>
<condition field="effect" type="neq">scrollVert</condition>
<condition field="effect" type="neq">flipHorz</condition>
<condition field="effect" type="neq">flipVert</condition>
<condition field="effect" type="neq">shuffle</condition>
<condition field="effect" type="neq">tileSlide</condition>
<condition field="effect" type="neq">tileBlind</condition>
<condition field="showSeparator" type="eq">1</condition>
</test>
</visibility>
</property>
<property id="noDataMessage" type="richText" allowLibraryRefs="true" variant="html">
<title>No data message</title>
<helpText>A message to display when no data is returned from the source</helpText>
</property>
<property id="copyright" type="text">
<title>Copyright</title>
<helpText>Copyright information to display as the last item in this feed.</helpText>
</property>
</properties>
<stencil>
<hbs><![CDATA[
<div class="article">
<div><div class="name">{{author}}</div></div>
<div><div class="title"><strong>{{title}}</strong></div></div>
<div><div class="description">{{{summary}}}</div></div>
</div>
]]></hbs>
<style><![CDATA[
html {
/* Global font size, change for font scale */
font-size: 16px;
}
.text-render-item {
padding: 1rem;
}
.text-render-item.cycle-slide {
width: calc(100% - 2rem) !important;
}
.article > div {
font-family: Arial, Verdana, sans-serif;
{% if showSideBySide %}
display: inline-block;
padding-left: 10px;
{% endif %}
}
.name {
font-size: 2rem;
}
.description, .title {
font-size: 3rem;
}
{% if backgroundColor %}
body {
background-color: {{backgroundColor}} !important;
}
{% endif %}
{% if itemTitleColor %}
.title {
color: {{itemTitleColor}} !important;
}
{% endif %}
{% if itemDescriptionColor %}
.description {
color: {{itemDescriptionColor}} !important;
}
{% endif %}
{% if itemNameColor %}
.name {
color: {{itemNameColor}} !important;
}
{% endif %}
{% if itemFontSize %}
html {
font-size: {{itemFontSize}}px !important;
}
{% endif %}
{% if fontFamily %}
.title, .name, .description {
font-family: {{fontFamily}} !important;
}
{% endif %}
{% if copyright %}
.copyright {
width: 100%;
height: 100%;
text-align: center;
}
.js-marquee .copyright {
width: auto;
}
.copyright span {
position: relative;
font-size: 30px;
line-height: 0;
top: 50%;
transform: translateY(-50%);
}
{% endif %}
]]></style>
</stencil>
<onTemplateRender><![CDATA[
// id: The id of the widget
// target: The target element to render
// items: The items to render
// properties: The properties for the widget
// -------------------------------------------
// No data message
if (items.length <= 0 && properties.noDataMessage && properties.noDataMessage !== '') {
$(target).find('#content').append(properties.noDataMessage);
}
// Add copyright if we have at least one item
// and copyright is not already added
if (
properties.copyright &&
$(target).find('#content .article').length > 0 &&
$(target).find('#content .copyright').length <= 0
) {
$(target).find('#content').append(
$('<div class="copyright"><span>' + properties.copyright + '</span></div>')
);
// Increase numItems to include the copyright
properties.numItems = parseInt(properties.numItems) + 1;
}
// Add separator
if (
(
properties.effect == 'marqueeLeft' ||
properties.effect == 'marqueeRight' ||
properties.effect == 'marqueeUp' ||
properties.effect == 'marqueeDown'
) && properties.showSeparator == 1 &&
properties.separator != ''
) {
var $separator = $(properties.separator);
$separator.addClass('separator');
$(target).find('#content .article, #content .copyright').after($separator);
}
// Render
$(target).xiboLayoutScaler(properties);
$(target).xiboTextRender(properties, $(target).find('#content .article, #content .copyright, #content .separator'));
]]></onTemplateRender>
<onTemplateVisible><![CDATA[
// Start effects for this template
$(target).xiboLayoutAnimate(properties);
]]></onTemplateVisible>
<assets>
<asset id="article_with_desc_and_name_separator" type="path" cmsOnly="true" mimeType="image/png" path="/modules/assets/template-thumbnails/article/title-description-name.png" />
</assets>
</template>
<template>
<id>article_title_only</id>
<type>static</type>
<dataType>article</dataType>
<title>Title Only</title>
<thumbnail>article_title_only</thumbnail>
<startWidth>600</startWidth>
<startHeight>200</startHeight>
<properties>
<property id="backgroundColor" type="color">
<title>Background</title>
<default></default>
</property>
<property id="itemTitleColor" type="color">
<title>Title</title>
<default>#000</default>
</property>
<property id="itemFontSize" type="number">
<title>Font Size</title>
<default>16</default>
</property>
<property id="fontFamily" type="fontSelector">
<title>Font</title>
<helpText>Select a custom font - leave empty to use the default font.</helpText>
</property>
<property id="effect" type="effectSelector" variant="all">
<title>Effect</title>
<helpText>Please select the effect that will be used to transition between items.</helpText>
<default>noTransition</default>
</property>
<property id="speed" type="number">
<title>Speed</title>
<helpText>The transition speed of the selected effect in milliseconds (normal = 1000) or the Marquee Speed in a low to high scale (normal = 1)</helpText>
<default>1000</default>
</property>
<property id="showSeparator" type="checkbox">
<title>Show a separator between items?</title>
<default>0</default>
<visibility>
<test type="or">
<condition field="effect" type="eq">marqueeLeft</condition>
<condition field="effect" type="eq">marqueeRight</condition>
<condition field="effect" type="eq">marqueeUp</condition>
<condition field="effect" type="eq">marqueeDown</condition>
</test>
</visibility>
</property>
<property id="separator" type="richText" allowLibraryRefs="false" variant="html">
<title>Separator</title>
<helpText>A separator to show between marquee items</helpText>
<default>
<![CDATA[
<p><span style="font-size: 72px;">/</span></p>
]]></default>
<visibility>
<test type="and">
<condition field="effect" type="neq">none</condition>
<condition field="effect" type="neq">noTransition</condition>
<condition field="effect" type="neq">fade</condition>
<condition field="effect" type="neq">fadeout</condition>
<condition field="effect" type="neq">scrollHorz</condition>
<condition field="effect" type="neq">scrollVert</condition>
<condition field="effect" type="neq">flipHorz</condition>
<condition field="effect" type="neq">flipVert</condition>
<condition field="effect" type="neq">shuffle</condition>
<condition field="effect" type="neq">tileSlide</condition>
<condition field="effect" type="neq">tileBlind</condition>
<condition field="showSeparator" type="eq">1</condition>
</test>
</visibility>
</property>
<property id="noDataMessage" type="richText" allowLibraryRefs="true" variant="html">
<title>No data message</title>
<helpText>A message to display when no data is returned from the source</helpText>
</property>
<property id="copyright" type="text">
<title>Copyright</title>
<helpText>Copyright information to display as the last item in this feed.</helpText>
</property>
</properties>
<stencil>
<hbs><![CDATA[
<div class="article">
<div><div class="title"><strong>{{title}}</strong></div></div>
</div>
]]></hbs>
<style><![CDATA[
html {
/* Global font size, change for font scale */
font-size: 16px;
}
.text-render-item {
padding: 1rem;
}
.text-render-item.cycle-slide {
width: calc(100% - 2rem) !important;
}
.article > div {
font-family: Arial, Verdana, sans-serif;
}
.title {
font-size: 3rem;
}
{% if backgroundColor %}
body {
background-color: {{backgroundColor}} !important;
}
{% endif %}
{% if itemTitleColor %}
.title {
color: {{itemTitleColor}} !important;
}
{% endif %}
{% if itemFontSize %}
html {
font-size: {{itemFontSize}}px !important;
}
{% endif %}
{% if fontFamily %}
.title {
font-family: {{fontFamily}} !important;
}
{% endif %}
{% if copyright %}
.copyright {
width: 100%;
height: 100%;
text-align: center;
}
.copyright span {
position: relative;
font-size: 30px;
line-height: 0;
top: 50%;
transform: translateY(-50%);
}
.js-marquee .copyright {
width: auto;
}
{% endif %}
]]></style>
</stencil>
<onTemplateRender><![CDATA[
// id: The id of the widget
// target: The target element to render
// items: The items to render
// properties: The properties for the widget
// -------------------------------------------
// No data message
if (items.length <= 0 && properties.noDataMessage && properties.noDataMessage !== '') {
$(target).find('#content').append(properties.noDataMessage);
}
// Add copyright if we have at least one item
// and copyright is not already added
if (
properties.copyright &&
$(target).find('#content .article').length > 0 &&
$(target).find('#content .copyright').length <= 0
) {
$(target).find('#content').append(
$('<div class="copyright"><span>' + properties.copyright + '</span></div>')
);
// Increase numItems to include the copyright
properties.numItems = parseInt(properties.numItems) + 1;
}
// Add separator
if (
(
properties.effect == 'marqueeLeft' ||
properties.effect == 'marqueeRight' ||
properties.effect == 'marqueeUp' ||
properties.effect == 'marqueeDown'
) && properties.showSeparator == 1 &&
properties.separator != ''
) {
var $separator = $(properties.separator);
$separator.addClass('separator');
$(target).find('#content .article, #content .copyright').after($separator);
}
// Render
$(target).xiboLayoutScaler(properties);
$(target).xiboTextRender(properties, $(target).find('#content .article, #content .copyright, #content .separator'));
]]></onTemplateRender>
<onTemplateVisible><![CDATA[
// Start effects for this template
$(target).xiboLayoutAnimate(properties);
]]></onTemplateVisible>
<assets>
<asset id="article_title_only" type="path" cmsOnly="true" mimeType="image/png" path="/modules/assets/template-thumbnails/article/title-only.png" />
</assets>
</template>
<template>
<id>article_marquee</id>
<type>static</type>
<dataType>article</dataType>
<title>Articles shown in a marquee</title>
<startWidth>1200</startWidth>
<startHeight>80</startHeight>
<properties>
<property id="selectedTags" type="tickerTagSelector">
<title>Selected Tags</title>
<helpText>Select tags to be displayed.</helpText>
</property>
<property id="effect" type="effectSelector" variant="showAll">
<title>Effect</title>
<helpText>Please select the effect that will be used to transition between items.</helpText>
<default>marqueeLeft</default>
</property>
<property id="speed" type="number">
<title>Speed</title>
<helpText>Marquee Speed in a low to high scale (normal = 1)</helpText>
<default>1</default>
</property>
<property id="dateFormat" type="text" variant="dateFormat">
<title>Date Format</title>
<helpText>The format to apply to all dates returned by the Widget.</helpText>
<default>#DATE_FORMAT#</default>
</property>
<property id="gapTags" type="number">
<title>Gap between tags</title>
<helpText>Value (in pixels) to set a gap between each item's tags.</helpText>
<default>6</default>
</property>
<property id="gapItems" type="number">
<title>Gap between items</title>
<helpText>Value (in pixels) to set a gap between each item.</helpText>
<default>6</default>
</property>
<property id="backgroundColor" type="color">
<title>Background Colour</title>
<helpText>The selected effect works best with a background colour. Optionally add one here.</helpText>
<default></default>
</property>
<property id="textDirection" type="dropdown" mode="single">
<title>Text direction</title>
<helpText>Which direction does the text in the feed use?</helpText>
<default>ltr</default>
<options>
<option name="ltr">Left to Right (LTR)</option>
<option name="rtl">Right to Left (RTL)</option>
</options>
</property>
<property id="showSeparator" type="checkbox">
<title>Show a separator between items?</title>
<default>0</default>
<visibility>
<test type="or">
<condition field="effect" type="eq">marqueeLeft</condition>
<condition field="effect" type="eq">marqueeRight</condition>
<condition field="effect" type="eq">marqueeUp</condition>
<condition field="effect" type="eq">marqueeDown</condition>
</test>
</visibility>
</property>
<property id="separator" type="richText" allowLibraryRefs="false" variant="html">
<title>Separator</title>
<helpText>A separator to show between marquee items</helpText>
<default>
<![CDATA[
<p><span style="font-size: 16px;">/</span></p>
]]></default>
<visibility>
<test type="and">
<condition field="effect" type="neq">none</condition>
<condition field="effect" type="neq">noTransition</condition>
<condition field="effect" type="neq">fade</condition>
<condition field="effect" type="neq">fadeout</condition>
<condition field="effect" type="neq">scrollHorz</condition>
<condition field="effect" type="neq">scrollVert</condition>
<condition field="effect" type="neq">flipHorz</condition>
<condition field="effect" type="neq">flipVert</condition>
<condition field="effect" type="neq">shuffle</condition>
<condition field="effect" type="neq">tileSlide</condition>
<condition field="effect" type="neq">tileBlind</condition>
<condition field="showSeparator" type="eq">1</condition>
</test>
</visibility>
</property>
<property id="copyright" type="text">
<title>Copyright</title>
<helpText>Copyright information to display as the last item in this feed.</helpText>
</property>
<property id="copyrightFontFamily" type="fontSelector">
<title>Copyright Font Family</title>
<helpText>Select a custom font - leave empty to use the default font.</helpText>
<visibility>
<test>
<condition field="copyright" type="neq"></condition>
</test>
</visibility>
</property>
<property id="copyrightFontColor" type="color">
<title>Copyright Font Colour</title>
<default></default>
<visibility>
<test>
<condition field="copyright" type="neq"></condition>
</test>
</visibility>
</property>
<property id="copyrightFontSize" type="number">
<title>Copyright Font Size</title>
<default></default>
<visibility>
<test>
<condition field="copyright" type="neq"></condition>
</test>
</visibility>
</property>
<property id="copyrightBold" type="checkbox">
<title>Bold</title>
<helpText>Should the copyright text be bold?</helpText>
<default>0</default>
<visibility>
<test>
<condition field="copyright" type="neq"></condition>
</test>
</visibility>
</property>
<property id="copyrightItalics" type="checkbox">
<title>Italics</title>
<helpText>Should the copyright text be italicised?</helpText>
<default>0</default>
<visibility>
<test>
<condition field="copyright" type="neq"></condition>
</test>
</visibility>
</property>
<property id="copyrightUnderline" type="checkbox">
<title>Underline</title>
<helpText>Should the copyright text be underlined?</helpText>
<default>0</default>
<visibility>
<test>
<condition field="copyright" type="neq"></condition>
</test>
</visibility>
</property>
<property id="noDataMessage" type="richText" allowLibraryRefs="true" variant="html">
<title>No data message</title>
<helpText>A message to display when no data is returned from the source</helpText>
</property>
</properties>
<stencil>
<twig><![CDATA[
{% if javaScript %}<script type="text/javascript">{{javaScript|raw}}</script>{% endif %}
]]></twig>
<style><![CDATA[
{% if textDirection == "rtl" %}#content { direction: rtl; }{% endif %}
{% if backgroundColor %}body { background-color: {{backgroundColor}} !important; }{% endif %}
{% if (effect == "marqueeLeft") or (effect == "marqueeRight") %}
{% if gapTags %}.marquee-item { margin-right: {{gapTags}}px; }{% endif %}
{% if gapItems %}.item.text-render-item, .separator { margin-right: {{gapItems}}px; }{% endif %}
.is-media-item { display: inline-block; }
.marquee-item { vertical-align: middle; }
{% endif %}
{% if (effect == "marqueeUp") or (effect == "marqueeDown") %}
{% if gapTags %}.marquee-item { margin-bottom: {{gapTags}}px; }{% endif %}
{% if gapItems %}.item.text-render-item, .separator { margin-bottom: {{gapItems}}px; }{% endif %}
.marquee-item { display: block; }
{% endif %}
]]></style>
</stencil>
<onTemplateRender><![CDATA[
// id: The id of the widget
// target: The target element to render
// items: The items to render
// properties: The properties for the widget
// -------------------------------------------
// Generate template from chosen fields
var selectedTags = (properties.selectedTags != null && properties.selectedTags != '') ? JSON.parse(properties.selectedTags) : [];
properties.template = '';
for (var tag in selectedTags) {
var isImage = (selectedTags[tag]['tagType'] === 'image');
properties.template += '<span class="marquee-item marquee-' + tag;
if (isImage) {
properties.template += ' is-media-item';
}
properties.template += '" style="';
for (var style in selectedTags[tag]) {
if (style === 'fontSize' && selectedTags[tag][style]) {
properties.template += 'font-size:' + selectedTags[tag][style] + 'px;';
}
if (style === 'fontColor' && selectedTags[tag][style]) {
properties.template += 'color:' + selectedTags[tag][style] + ';';
}
if (style === 'fontFamily' && selectedTags[tag][style]) {
properties.template += 'font-family:' + selectedTags[tag][style] + ';';
}
if (style === 'bold' && selectedTags[tag][style]) {
properties.template += 'font-weight: bold;';
}
if (style === 'italics' && selectedTags[tag][style]) {
properties.template += 'font-style: italic;';
}
if (style === 'underline' && selectedTags[tag][style]) {
properties.template += 'text-decoration: underline;';
}
if (style === 'width' && selectedTags[tag][style]) {
properties.template += 'width:' + selectedTags[tag][style] + 'px;';
}
if (style === 'height' && selectedTags[tag][style]) {
properties.template += 'height:' + selectedTags[tag][style] + 'px;';
}
if (style === 'opacity' && selectedTags[tag][style]) {
properties.template += 'opacity:' + selectedTags[tag][style] + ';';
}
}
if (isImage) {
properties.template += '"><img style="width: 100%; height: 100%;" src="[' + tag + ']" /></span>';
} else {
properties.template += '">[' + tag + ']</span>';
}
}
if (items.length > 0) {
items = $(items).xiboSubstitutesParser(properties.template, properties.dateFormat, ['date', 'publishedDate'], {
description: 'summary',
copyright: 'author',
});
}
// No data message
if (items.length <= 0 && properties.noDataMessage && properties.noDataMessage !== '') {
// Add message to the target content
$(target).find('#content').after(
$('<div>')
.addClass('no-data-message')
.append(properties.noDataMessage)
);
}
// Copyright
if (properties.copyright) {
var copyrightTemplate = '<span class="marquee-item marquee-copyright" style="';
if (properties.copyrightFontFamily) {
copyrightTemplate += 'font-family:' + properties.copyrightFontFamily + ';';
}
if (properties.copyrightFontColor) {
copyrightTemplate += 'color:' + properties.copyrightFontColor + ';';
}
if (properties.copyrightFontSize) {
copyrightTemplate += 'font-size:' + properties.copyrightFontSize + 'px;';
}
if (properties.copyrightBold) {
copyrightTemplate += 'font-weight: bold;';
}
if (properties.copyrightItalics) {
copyrightTemplate += 'font-style: italic;';
}
if (properties.copyrightUnderline) {
copyrightTemplate += 'text-decoration: underline;';
}
copyrightTemplate += '">' + properties.copyright + '</span>';
items.push(copyrightTemplate);
}
// Clear container
$(target).find('#content').empty();
// Add items to container
for (var index = 0; index < items.length; index++) {
var $newItem = $('<div>').addClass('item').html(items[index]);
$(target).find('#content').append($newItem);
}
// Add separator
if (
(
properties.effect == 'marqueeLeft' ||
properties.effect == 'marqueeRight' ||
properties.effect == 'marqueeUp' ||
properties.effect == 'marqueeDown'
) && properties.showSeparator == 1 &&
properties.separator != ''
) {
var $separator = $(properties.separator);
$separator.addClass('separator');
$(target).find('.item').after($separator);
}
// Render
$(target).xiboLayoutScaler(properties);
$(target).xiboTextRender(properties, $(target).find('#content > *'));
$(target).find('img').xiboImageRender(properties);
]]></onTemplateRender>
<onTemplateVisible><![CDATA[
// Start effects for this template
$(target).xiboLayoutAnimate(properties);
]]></onTemplateVisible>
</template>
</templates>