In the previous three parts we have primarily discussed the visible innovations and improvements of WoltLab Suite 5.3. In the previous part New Features in WoltLab Suite 5.3 (Part 3) we have, for example, taken a closer look at the revised management of notification settings or the redesign of trophies.
We would like to interrupt this series to present changes that are significant for developers of plugins and apps. This part is exclusively for developers, we will cover further innovations for administrators and users in the upcoming part 4.
New Template Plugins
We have add several new template plugins with the goal to reduce template and language item complexities and duplicate code.
anchor
The anchor template plugin generates a HTML elements and can either be passed an object implementing ITitledLinkObject:
{anchor object=$object}
{* generates the same output as: *}
<a href="{$object->getLink()}">{$object->getTitle()}</a>
or link and content attributes can be used:
{anchor link=$linkObject content=$content}
{* generates the same output as: *}
<a href="{$linkObject->getLink()}">{$content}</a>
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.
More information can be found in our developer documentation.
user
Links to user profiles are frequently generated in templates. To make it easier, the user template plugin was added, which only requires a UserProfile object to generate a link:
is equivalent to
<a href="{$user->getLink()}" data-object-id="{$user->userID}" class="userLink">{@$user->getFormattedUsername()}</a>
Note that by default, the formatted username will be used, which relies on the “User Marking” setting of the relevant user group. Additionally, attributes are added to that hovering over the link will open the user popover card.
More information, for example on how to generate linked avatars, can be found in our developer documentation.
plural
The plural template plugins makes it easier to generate a string that depends on a numeric value without having to use if constructs. # is used a placeholder for the actual value in the strings.
German Example
{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>
{* generates *}
<h1>Hallo Welten!</h1>
<p>Es gibt 2 Welten!</p>
English Example
{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>
{* generates *}
<h1>Hello Worlds!</h1>
<p>There are 2 worlds!</p>
More information on the syntax, in particular for languages with more complex rules, can be found in our developer documentation.
jslang
When making language items available in JavaScript code via Language.addObject(), instead of the lang template plugin, jslang should be used now within a single quoted string to avoid problems with quotation marks in the language item:
// old
Language.addObject({
'app.foo.bar': '{lang}app.foo.bar{/lang}',
});
// new
Language.addObject({
'app.foo.bar': '{jslang}app.foo.bar{/jslang}',
});
Reduced Complexity of Notification Phrases
Phrases related to notifications could be quite complex, in particular for stacked notification. In addition to using the plural template plugin, we have changed several other aspects of phrases for notifications to reduce their complexity:
As the whole notification is clickable now, all links have been replaced with strong elements in notification messages.
Commonly found template code to output reactions and labels are also easier now due to new helper methods:
{* old *}
{implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}
{* new *}
{@$__wcf->getReactionHandler()->renderInlineList($reactions)}
{* old *}
<span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span>
{* new *}
{@$like->render()}
{* old *}
<span class="label badge{if $label->getClassNames()} {$label->getClassNames()}{/if}">{$label->getTitle()}</span>
{* new *}
{@$label->render()}
Display More
Lastly, the commonly used construct
{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{/if}
in stacked notification messages can be replaced with a new language item:
void Package Installation Plugin
To update the metadata of a package without changing else, the <void/> marker has been added for update instructions:
If the <void/> marker is present, no other update instructions are allowed.
Additional information can be found in our migrations guide for WoltLab Suite 5.2 to WoltLab Suite 5.3 in our developer documentation: