Template Plugins#
5.3+ anchor
#
The anchor
template plugin creates a
HTML elements.
The easiest way to use the template plugin is to pass it an instance of ITitledLinkObject
:
{anchor object=$object}
generates the same output as
<a href="{$object->getLink()}">{$object->getTitle()}</a>
Instead of an object
parameter, a link
and content
parameter can be used:
{anchor link=$linkObject content=$content}
where $linkObject
implements ILinkableObject
and $content
is either an object implementing ITitledObject
or having a __toString()
method or $content
is a string or a number.
The last special attribute is append
whose contents are appended to the href
attribute of the generated anchor element.
All of the other attributes matching ~^[a-z]+([A-z]+)+$~
, expect for href
which is disallowed, are added as attributes to the anchor element.
If an object
attribute is present, the object also implements IPopoverObject
and if the return value of IPopoverObject::getPopoverLinkClass()
is included in the class
attribute of the anchor
tag, data-object-id
is automatically added.
This functionality makes it easy to generate links with popover support.
Instead of
<a href="{$entry->getLink()}" class="blogEntryLink" data-object-id="{@$entry->entryID}">{$entry->subject}</a>
using
{anchor object=$entry class='blogEntryLink'}
is sufficient if Entry::getPopoverLinkClass()
returns blogEntryLink
.
5.3+ anchorAttributes
#
anchorAttributes
compliments the StringUtil::getAnchorTagAttributes(string, bool): string
method.
It allows to easily generate the necessary attributes for an anchor tag based off the destination URL.
<a href="https://www.example.com" {anchorAttributes url='https://www.example.com' appendHref=false appendClassname=true isUgc=true}>
Attribute | Description |
---|---|
url |
destination URL |
appendHref |
whether the href attribute should be generated; true by default |
isUgc |
whether the rel="ugc" attribute should be generated; false by default |
appendClassname |
whether the class="externalURL" attribute should be generated; true by default |
append
#
If a string should be appended to the value of a variable, append
can be used:
{assign var=templateVariable value='newValue'}
{$templateVariable} {* prints 'newValue *}
{append var=templateVariable value='2'}
{$templateVariable} {* now prints 'newValue2 *}
If the variables does not exist yet, append
creates a new one with the given value.
If append
is used on an array as the variable, the value is appended to all elements of the array.
assign
#
New template variables can be declared and new values can be assigned to existing template variables using assign
:
{assign var=templateVariable value='newValue'}
{$templateVariable} {* prints 'newValue *}
capture
#
In some situations, assign
is not sufficient to assign values to variables in templates if the value is complex.
Instead, capture
can be used:
{capture var=templateVariable}
{if $foo}
<p>{$bar}</p>
{else}
<small>{$baz}</small>
{/if}
{/capture}
concat
#
concat
is a modifier used to concatenate multiple strings:
{assign var=foo value='foo'}
{assign var=templateVariable value='bar'|concat:$foo}
{$templateVariable} {* prints 'foobar *}
counter
#
counter
can be used to generate and optionally print a counter:
{counter name=fooCounter print=true} {* prints '1' *}
{counter name=fooCounter print=true} {* prints '2' now *}
{counter name=fooCounter} {* prints nothing, but counter value is '3' now internally *}
{counter name=fooCounter print=true} {* prints '4' *}
Counter supports the following attributes:
Attribute | Description |
---|---|
assign |
optional name of the template variable the current counter value is assigned to |
direction |
counting direction, either up or down ; up by default |
name |
name of the counter, relevant if multiple counters are used simultaneously |
print |
if true , the current counter value is printed; false by default |
skip |
positive counting increment; 1 by default |
start |
start counter value; 1 by default |
5.4+ csrfToken
#
{csrfToken}
prints out the session's CSRF token (“Security Token”).
<form action="{link controller="Foo"}{/link}" method="post">
{* snip *}
{csrfToken}
</form>
The {csrfToken}
template plugin supports a type
parameter.
Specifying this parameter might be required in rare situations.
Please check the implementation for details.
currency
#
currency
is a modifier used to format currency values with two decimals using language dependent thousands separators and decimal point:
{assign var=currencyValue value=12.345}
{$currencyValue|currency} {* prints '12.34' *}
cycle
#
cycle
can be used to cycle between different values:
{cycle name=fooCycle values='bar,baz'} {* prints 'bar' *}
{cycle name=fooCycle} {* prints 'baz' *}
{cycle name=fooCycle advance=false} {* prints 'baz' again *}
{cycle name=fooCycle} {* prints 'bar' *}
The values attribute only has to be present for the first call. If cycle
is used in a loop, the presence of the same values in consecutive calls has no effect. Only once the values change, the cycle is reset.
Attribute | Description |
---|---|
advance |
if true , the current cycle value is advanced to the next value; true by default |
assign |
optional name of the template variable the current cycle value is assigned to; if used, print is set to false |
delimiter |
delimiter between the different cycle values; , by default |
name |
name of the cycle, relevant if multiple cycles are used simultaneously |
print |
if true , the current cycle value is printed, false by default |
reset |
if true , the current cycle value is set to the first value, false by default |
values |
string containing the different cycles values, also see delimiter |
date
#
date
generated a formatted date using wcf\util\DateUtil::format()
with DateUtil::DATE_FORMAT
internally.
{$timestamp|date}
3.1+ dateInterval
#
dateInterval
calculates the difference between two unix timestamps and generated a textual date interval.
{dateInterval start=$startTimestamp end=$endTimestamp full=true format='sentence'}
Attribute | Description |
---|---|
end |
end of the time interval; current timestamp by default (though either start or end has to be set) |
format |
output format, either default , sentence , or plain ; defaults to default , see wcf\util\DateUtil::FORMAT_* constants |
full |
if true , full difference in minutes is shown; if false , only the longest time interval is shown; false by default |
start |
start of the time interval; current timestamp by default (though either start or end has to be set) |
encodeJS
#
encodeJS
encodes a string to be used as a single-quoted string in JavaScript by replacing \\
with \\\\
, '
with \'
, linebreaks with \n
, and /
with \/
.
<script>
var foo = '{@$foo|encodeJS}';
</script>
encodeJSON
#
encodeJSON
encodes a JSON string to be used as a single-quoted string in JavaScript by replacing \\
with \\\\
, '
with '
, linebreaks with \n
, and /
with \/
.
Additionally, htmlspecialchars
is applied to the string.
'{@$foo|encodeJSON}'
escapeCDATA
#
escapeCDATA
encodes a string to be used in a CDATA
element by replacing ]]>
with ]]]]><![CDATA[>
.
<![CDATA[{@$foo|encodeCDATA}]]>
event
#
event
provides extension points in templates that template listeners can use.
{event name='foo'}
fetch
#
fetch
fetches the contents of a file using file_get_contents
.
{fetch file='foo.html'} {* prints the contents of `foo.html` *}
{fetch file='bar.html' assign=bar} {* assigns the contents of `foo.html` to `$bar`; does not print the contents *}
filesizeBinary
#
filesizeBinary
formats the filesize using binary filesize (in bytes).
{$filesize|filesizeBinary}
filesize
#
filesize
formats the filesize using filesize (in bytes).
{$filesize|filesize}
hascontent
#
In many cases, conditional statements can be used to determine if a certain section of a template is shown:
{if $foo === 'bar'}
only shown if $foo is bar
{/if}
In some situations, however, such conditional statements are not sufficient. One prominent example is a template event:
{if $foo === 'bar'}
<ul>
{if $foo === 'bar'}
<li>Bar</li>
{/if}
{event name='listItems'}
</li>
{/if}
In this example, if $foo !== 'bar'
, the list will not be shown, regardless of the additional template code provided by template listeners.
In such a situation, hascontent
has to be used:
{hascontent}
<ul>
{content}
{if $foo === 'bar'}
<li>Bar</li>
{/if}
{event name='listItems'}
{/content}
</ul>
{/hascontent}
If the part of the template wrapped in the content
tags has any (trimmed) content, the part of the template wrapped by hascontent
tags is shown (including the part wrapped by the content
tags), otherwise nothing is shown.
Thus, this construct avoids an empty list compared to the if
solution above.
Like foreach
, hascontent
also supports an else
part:
{hascontent}
<ul>
{content}
{* … *}
{/content}
</ul>
{hascontentelse}
no list
{/hascontent}
htmlCheckboxes
#
htmlCheckboxes
generates a list of HTML checkboxes.
{htmlCheckboxes name=foo options=$fooOptions selected=$currentFoo}
{htmlCheckboxes name=bar output=$barLabels values=$barValues selected=$currentBar}
Attribute | Description |
---|---|
5.2+ disabled |
if true , all checkboxes are disabled |
disableEncoding |
if true , the values are not passed through wcf\util\StringUtil::encodeHTML() ; false by default |
name |
name attribute of the input checkbox element |
output |
array used as keys and values for options if present; not present by default |
options |
array selectable options with the key used as value attribute and the value as the checkbox label |
selected |
current selected value(s) |
separator |
separator between the different checkboxes in the generated output; empty string by default |
values |
array with values used in combination with output , where output is only used as keys for options |
htmlOptions
#
htmlOptions
generates an select
HTML element.
{htmlOptions name='foo' options=$options selected=$selected}
<select name="bar">
<option value=""{if !$selected} selected{/if}>{lang}foo.bar.default{/lang}</option>
{htmlOptions options=$options selected=$selected} {* no `name` attribute *}
</select>
Attribute | Description |
---|---|
disableEncoding |
if true , the values are not passed through wcf\util\StringUtil::encodeHTML() ; false by default |
object |
optional instance of wcf\data\DatabaseObjectList that provides the selectable options (overwrites options attribute internally) |
name |
name attribute of the select element; if not present, only the contents of the select element are printed |
output |
array used as keys and values for options if present; not present by default |
values |
array with values used in combination with output , where output is only used as keys for options |
options |
array selectable options with the key used as value attribute and the value as the option label; if a value is an array, an optgroup is generated with the array key as the optgroup label |
selected |
current selected value(s) |
All additional attributes are added as attributes of the select
HTML element.
implode
#
implodes
transforms an array into a string and prints it.
{implode from=$array key=key item=item glue=";"}{$key}: {$value}{/implode}
Attribute | Description |
---|---|
from |
array with the imploded values |
glue |
separator between the different array values; ', ' by default |
item |
template variable name where the current array value is stored during the iteration |
key |
optional template variable name where the current array key is stored during the iteration |
5.2+ ipSearch
#
ipSearch
generates a link to search for an IP address.
{"127.0.0.1"|ipSearch}
3.0+ js
#
js
generates script tags based on whether ENABLE_DEBUG_MODE
and VISITOR_USE_TINY_BUILD
are enabled.
{js application='wbb' file='WBB'} {* generates 'http://example.com/js/WBB.js' *}
{js application='wcf' file='WCF.Like' bundle='WCF.Combined'}
{* generates 'http://example.com/wcf/js/WCF.Like.js' if ENABLE_DEBUG_MODE=1 *}
{* generates 'http://example.com/wcf/js/WCF.Combined.min.js' if ENABLE_DEBUG_MODE=0 *}
{js application='wcf' lib='jquery'}
{* generates 'http://example.com/wcf/js/3rdParty/jquery.js' *}
{js application='wcf' lib='jquery-ui' file='awesomeWidget'}
{* generates 'http://example.com/wcf/js/3rdParty/jquery-ui/awesomeWidget.js' *}
{js application='wcf' file='WCF.Like' bundle='WCF.Combined' hasTiny=true}
{* generates 'http://example.com/wcf/js/WCF.Like.js' if ENABLE_DEBUG_MODE=1 *}
{* generates 'http://example.com/wcf/js/WCF.Combined.min.js' (ENABLE_DEBUG_MODE=0 *}
{* generates 'http://example.com/wcf/js/WCF.Combined.tiny.min.js' if ENABLE_DEBUG_MODE=0 and VISITOR_USE_TINY_BUILD=1 *}
5.3+ jslang
#
jslang
works like lang
with the difference that the resulting string is automatically passed through encodeJS
.
require(['Language', /* … */], function(Language, /* … */) {
Language.addObject({
'app.foo.bar': '{jslang}app.foo.bar{/jslang}',
});
// …
});
lang
#
lang
replaces a language items with its value.
{lang}foo.bar.baz{/lang}
{lang __literal=true}foo.bar.baz{/lang}
{lang foo='baz'}foo.bar.baz{/lang}
{lang}foo.bar.baz.{$action}{/lang}
Attribute | Description |
---|---|
__encode |
if true , the output will be passed through StringUtil::encodeHTML() |
__literal |
if true , template variables will not resolved but printed as they are in the language item; false by default |
__optional |
if true and the language item does not exist, an empty string is printed; false by default |
All additional attributes are available when parsing the language item.
language
#
language
replaces a language items with its value.
If the template variable __language
exists, this language object will be used instead of WCF::getLanguage()
.
This modifier is useful when assigning the value directly to a variable.
{$languageItem|language}
{assign var=foo value=$languageItem|language}
link
#
link
generates internal links using LinkHandler
.
<a href="{link controller='FooList' application='bar'}param1=2¶m2=A{/link}">Foo</a>
Attribute | Description |
---|---|
application |
abbreviation of the application the controller belongs to; wcf by default |
controller |
name of the controller; if not present, the landing page is linked in the frontend and the index page in the ACP |
encode |
if true , the generated link is passed through wcf\util\StringUtil::encodeHTML() ; true by default |
isEmail |
sets encode=false and forces links to link to the frontend |
Additional attributes are passed to LinkHandler::getLink()
.
newlineToBreak
#
newlineToBreak
transforms newlines into HTML <br>
elements after encoding the content via wcf\util\StringUtil::encodeHTML()
.
{$foo|newlineToBreak}
3.0+ page
#
page
generates an internal link to a CMS page.
{page}com.woltlab.wcf.CookiePolicy{/page}
{page pageID=1}{/page}
{page language='de'}com.woltlab.wcf.CookiePolicy{/page}
{page languageID=2}com.woltlab.wcf.CookiePolicy{/page}
Attribute | Description |
---|---|
pageID |
unique id of the page (cannot be used together with a page identifier as value) |
languageID |
id of the page language (cannot be used together with language ) |
language |
language code of the page language (cannot be used together with languageID ) |
pages
#
pages
generates a pagination.
{pages controller='FooList' link="pageNo=%d" print=true assign=pagesLinks} {* prints pagination *}
{@$pagesLinks} {* prints same pagination again *}
Attribute | Description |
---|---|
assign |
optional name of the template variable the pagination is assigned to |
controller |
controller name of the generated links |
link |
additional link parameter where %d will be replaced with the relevant page number |
pages |
maximum number of of pages; by default, the template variable $pages is used |
print |
if false and assign=true , the pagination is not printed |
application , id , object , title |
additional parameters passed to LinkHandler::getLink() to generate page links |
plainTime
#
plainTime
formats a timestamp to include year, month, day, hour, and minutes.
The exact formatting depends on the current language (via the language items wcf.date.dateTimeFormat
, wcf.date.dateFormat
, and wcf.date.timeFormat
).
{$timestamp|plainTime}
5.3+ plural
#
plural
allows to easily select the correct plural form of a phrase based on a given value
.
The pluralization logic follows the Unicode Language Plural Rules for cardinal numbers.
The #
placeholder within the resulting phrase is replaced by the value
.
It is automatically formatted using StringUtil::formatNumeric
.
English:
Note the use of 1
if the number (#
) is not used within the phrase and the use of one
otherwise.
They are equivalent for English, but following this rule generalizes better to other languages, helping the translator.
{assign var=numberOfWorlds value=2}
<h1>Hello {plural value=$numberOfWorlds 1='World' other='Worlds'}!</h1>
<p>There {plural value=$numberOfWorlds 1='is one world' other='are # worlds'}!</p>
<p>There {plural value=$numberOfWorlds one='is # world' other='are # worlds'}!</p>
German:
{assign var=numberOfWorlds value=2}
<h1>Hallo {plural value=$numberOfWorlds 1='Welt' other='Welten'}!</h1>
<p>Es gibt {plural value=$numberOfWorlds 1='eine Welt' other='# Welten'}!</p>
<p>Es gibt {plural value=$numberOfWorlds one='# Welt' other='# Welten'}!</p>
Romanian:
Note the additional use of few
which is not required in English or German.
{assign var=numberOfWorlds value=2}
<h1>Salut {plural value=$numberOfWorlds 1='lume' other='lumi'}!</h1>
<p>Există {plural value=$numberOfWorlds 1='o lume' few='# lumi' other='# de lumi'}!</p>
<p>Există {plural value=$numberOfWorlds one='# lume' few='# lumi' other='# de lumi'}!</p>
Russian:
Note the difference between 1
(exactly 1
) and one
(ending in 1
, except ending in 11
).
{assign var=numberOfWorlds value=2}
<h1>Привет {plural value=$numberOfWorld 1='мир' other='миры'}!</h1>
<p>Есть {plural value=$numberOfWorlds 1='мир' one='# мир' few='# мира' many='# миров' other='# миров'}!</p>
Attribute | Description |
---|---|
value | The value that is used to select the proper phrase. |
other | The phrase that is used when no other selector matches. |
Any Category Name | The phrase that is used when value belongs to the named category. Available categories depend on the language. |
Any Integer | The phrase that is used when value is that exact integer. |
prepend
#
If a string should be prepended to the value of a variable, prepend
can be used:
{assign var=templateVariable value='newValue'}
{$templateVariable} {* prints 'newValue *}
{prepend var=templateVariable value='2'}
{$templateVariable} {* now prints '2newValue' *}
If the variables does not exist yet, prepend
creates a new one with the given value.
If prepend
is used on an array as the variable, the value is prepended to all elements of the array.
shortUnit
#
shortUnit
shortens numbers larger than 1000 by using unit suffixes:
{10000|shortUnit} {* prints 10k *}
{5400000|shortUnit} {* prints 5.4M *}
smallpages
#
smallpages
generates a smaller version of pages
by using adding the small
CSS class to the generated <nav>
element and only showing 7 instead of 9 links.
tableWordwrap
#
tableWordwrap
inserts zero width spaces every 30 characters in words longer than 30 characters.
{$foo|tableWordwrap}
time
#
time
generates an HTML time
elements based on a timestamp that shows a relative time or the absolute time if the timestamp more than six days ago.
{$timestamp|time} {* prints a '<time>' element *}
truncate
#
truncate
truncates a long string into a shorter one:
{$foo|truncate:35}
{$foo|truncate:35:'_':true}
Parameter Number | Description |
---|---|
0 | truncated string |
1 | truncated length; 80 by default |
2 | ellipsis symbol; wcf\util\StringUtil::HELLIP by default |
3 | if true , words can be broken up in the middle; false by default |
5.3+ user
#
user
generates links to user profiles.
The mandatory object
parameter requires an instances of UserProfile
.
The optional type
parameter is responsible for what the generated link contains:
type='default'
(also applies if notype
is given) outputs the formatted username relying on the “User Marking” setting of the relevant user group. Additionally, the user popover card will be shown when hovering over the generated link.type='plain'
outputs the username without additional formatting.type='avatar(\d+)'
outputs the user’s avatar in the specified size, i.e.,avatar48
outputs the avatar with a width and height of 48 pixels.
The last special attribute is append
whose contents are appended to the href
attribute of the generated anchor element.
All of the other attributes matching ~^[a-z]+([A-z]+)+$~
, except for href
which may not be added, are added as attributes to the anchor element.
Examples:
{user object=$user}
generates
<a href="{$user->getLink()}" data-object-id="{$user->userID}" class="userLink">{@$user->getFormattedUsername()}</a>
and
{user object=$user type='avatar48' foo='bar'}
generates
<a href="{$user->getLink()}" foo="bar">{@$object->getAvatar()->getImageTag(48)}</a>