Liferay Freemarker Tips en Tricks: Datum & Tijdstip
Ik werk nu al een tijdje met Liferay, maar ik moet bekennen dat ik nog steeds niet echt de overstap heb gemaakt van Velocity naar Freemarker voor mijn sjablonen. Ook al weet ik dat er veel voordelen zijn aan het gebruik van Freemarker, zoals betere foutmeldingen, de Velocity kennis en bibliotheek van snippets die ik door de jaren heen heb opgebouwd is moeilijk op te geven. Maar met de komst van Liferay DXP, lijkt het nu het perfecte moment om over te stappen.
Toen ik vandaag aan een probleem werkte, waarbij de datum van wijziging van een onderdeel niet werd bijgewerkt bij het uitchecken/inchecken van een nieuwe versie, moest ik iets veranderen in een Freemarker display sjabloon dat werd gebruikt om een lijst van documenten weer te geven. In het begin, voordat ik wist dat er een probleem was in Liferay, dacht ik dat het probleem was dat de template de timeZone niet doorgaf aan de dateUtil call in de template:
<ul>
<#list entries as entry>
<#assign dateFormat = "MMM d, HH':'mm" />
<li>${entry.getTitle()} - ${dateUtil.getDate(entry.getModifiedDate(), dateFormat, locale)}</li>
</#list>
</ul>
Dit leek dus het perfecte moment om na te gaan hoe dit kon worden verholpen en of er verbeteringen konden worden aangebracht. Ik begon met de regel te repareren zoals hij was en voegde alleen de timeZone toe (die al aanwezig is in de sjablooncontext - zie com.liferay.portal.template.TemplateContextHelper).
<ul>
<#list entries as entry>
<#assign dateFormat = "MMM d, HH':'mm" />
<li>${entry.getTitle()} - ${dateUtil.getDate(entry.getModifiedDate(), dateFormat, locale, timeZone)}</li>
</#list>
</ul>
Hoewel deze oplossing het probleem verhelpt en de juiste datetime produceert in de tijdzone die we willen, zag het er wel een beetje omslachtig uit. Dus vroeg ik me af of Freemarker wat bood dat het korter/handiger/beter zou maken. Na wat rondkijken, vond ik deze 2 dingen: ingebouwde datumopmaak en verwerkingsinstellingen.
De eerste zou ons in staat stellen de dateUtil te laten vallen, maar lijkt geen regeling te hebben voor het opgeven van een locale en/of tijdzone. Dit is waar het tweede artikel om de hoek komt kijken. Deze verwerkingsinstellingen stellen ons in staat een aantal dingen in te stellen waar verdere Freemarker verwerking rekening mee zal houden en gelukkig voor ons is de datetime een van die dingen. Dus met de combinatie van beide, wordt onze template:
<#setting time_zone=timeZone.ID>
<#setting locale=locale.toString()>
<#setting datetime_format="MMM d, HH':'mm">
<ul>
<#list entries as entry>
<li><li>${entry.title} - ${entry.modifiedDate?datetime}</li></li>
</#list>
</ul>
Nu zie je dat we de processor gewoon vooraf kunnen instellen om de Liferay tijdzone en locale te gebruiken, maar ook het door ons geselecteerde datetime formaat. Dit laat ons toe om rechtstreeks de Freemarker ?datetime functie te gebruiken op het datumveld van de asset entry. Het zal ook van toepassing zijn op alle andere data die je wilt afdrukken in dit sjabloon met behulp van ?datetime (of ?date of ?time). Aangezien het slechts van toepassing is op één processor-run, kun je verschillende sjablonen toepassen die deze processorinstellingen verschillend instellen, op dezelfde pagina zonder dat ze elkaar storen. De volgende schermafbeelding toont het sjabloon hierboven en hetzelfde sjabloon waarbij de tijdzone, locale en datetime formaat verschillend zijn ingesteld:
De elegantie en het gebruiksgemak van deze kleine verbetering heeft me al van gedachten doen veranderen!