{{craftSnippets}}
Home Articles Plugins Starter theme Components on Github Gists About
  • Home
  • Articles
  • Working with dates in Craft CMS templates
Posted on Sep 09, 2019 by Piotr Pogorzelski

Working with dates in Craft CMS templates

Default date format macro on github gists
Time ago macro on github gists
Learn how dates work in Twig, and improve your templates with "time ago" and "default date format" Twig macros.
Table of contents:
  • Dates in Twig
  • Default date format macro
    • Macro code
    • Technical details
  • Time ago macro
    • Macro code
    • Technical details
  • Further reading

Dates in Twig #

Date objects work similarly both in PHP and Twig - before outputting them to template, you need to transform them into human-redeable format. In PHP, this is done by date() function. In Twig, you do that using date() filter:

{{entry.postDate|date('m/d/Y')}}

You can find about date formatting syntax on this w3schools page.

In Craft CMS you can also use date() filter to output date in the format used by current locale or set locale manually, as described in Craft documentation. This is important because different countries use different date formats - as shown in the picture below.

Default date format macro #

Dates tend to be showed in various parts of the website - for example, for blog websites it can be articles list and single article page. In order to make your templates easy to maintain, you should keep date format settings and date related code in one place - within Twig macro.

In this macro, date will be placed in time HTML element, in order to keep your markup semantic. time element will also have datetime attribute which will make date machine-readable. You can learn more about time element in this article on CSS tricks.

Macro code #

Default date format macro accepts two parameters:

  • date - can be date object (like entry.postDate) or string representing date - like now or 01-02-2018.
  • additionalAttributes - optional parameter for adding HTML attributes. If a single string is passed, it will add class to time element. If an object containing "attribute-value" pairs is passed, you can set what specific attributes time element should have.
{%- macro defaultDateFormat(date, additionalAttributes) -%}
{% if date is defined %}
{# settings #}
{% set format = 'medium' %}
{# logic #}
{% set attributes = {
	text: date|date(format),
	datetime: date|date('yy-m-d')
} %}
{% if additionalAttributes is defined and additionalAttributes is not iterable %}
	{% set attributes = attributes|merge({class: additionalAttributes}) %}
{% elseif additionalAttributes is iterable %}
	{% set attributes = attributes|merge(additionalAttributes) %}
{% endif %}
{{tag('time',attributes)}}
{% endif %}
{%- endmacro -%}

Feel free to modify formatting settings at the beginning of macro contained in format variable. You can also add logic that changes formatting depending on locale. Just don't change datetime attribute formatting - it is set to a machine-readable format.

Technical details #

This macro uses tag() function added in Craft 3.3 and thus won't work in earlier versions. tag() function works similarly to attr() function - it generates HTML element with attributes created from Twig object passed to function.

In this case, we first create an object containing text and datetime. text is not really HTML attribute, but what tag() function will use as content of time tag. Then, we optionally merge this object with any additional attributes that were passed to macro as the second parameter. Finally, we pass the object containing all attributes to tag() function.

So, for such parameters:

{{_self.defaultDateFormat('08-09-2019', {
	some-attribute: 'xxxxxx',
}) }}

We will get this result:

<time some-attribute="xxxxxx" datetime="2019-09-08">Sep 8, 2019</time>

Time ago macro #

Sometimes showing detailed date is not desirable. Users might want to know just how much time has passed from a specific date - and giving them detailed date might require them to perform calculations in their heads.

That's where time ago macro comes in. It works pretty similar to default date format macro - but instead of showing formatted date, it shows time that passed from that date - in a human-readable format. Detailed date is added to title attribute of time element - so if someone wants to know it, he or she can just hover the mouse over time element.

Macro code #

Time ago macro accepts two parameters:

  • date - can be date object (like entry.postDate) or string representing date - like now or 01-02-2018.
  • additionalAttributes - optional parameter for adding HTML attributes. If a single string is passed, it will add class to time element. If an object containing "attribute-value" pairs is passed, you can set what specific attributes time element should have.
{%- macro timeAgo(date, additionalAttributes) -%}
{% if date is defined %}
{# settings #}
{% set format = 'medium' %}
{% set locale = currentSite.language %}
{# logic #}
{% set formatter = create({ class: 'craft\\i18n\\Formatter', locale: locale }) %}
{% set attributes = {
	text: formatter.asRelativeTime(date),
	datetime: date|date('yy-m-d'),
	title: date|date(format),
} %}
{% if additionalAttributes is defined and additionalAttributes is not iterable %}
	{% set attributes = attributes|merge({class: additionalAttributes}) %}
{% elseif additionalAttributes is iterable %}
	{% set attributes = attributes|merge(additionalAttributes) %}
{% endif %}
{{tag('time',attributes)}}
{% endif %}
{%- endmacro -%}

Elapsed time is returned in the locale of the current site. If you want to change it, just change locale variable at the beginning of macro to specific locale code.

Word of caution - don't use this macro along with template caching - the elapsed time is calculated on each page load, so if template is cached, it will show outdated value.

Technical details #

Macro works almost the same as the default date macro. The only significant difference is the usage of create() function.

To use asRelativeTime function that outputs elapsed time in human-readable format, we need to instantiate craft\i18n\Formatter object - and we use create() for that. You can read more about it on nystudio blog.

Further reading #

  • date filter - Twig documentation
  • date filter - Craft CMS documentation
  • Date formatting syntax - w3schools
  • The time Element - CSS tricks

TAGS:
#macro
If you want to get latest updates on Craft CMS tutorials and components, follow me on Twitter or subscribe to RSS feed.
Quick links for this article:
Default date format macro on github gists
Time ago macro on github gists
Articles on blog:
  • Frontend testing for Craft CMS websites with Codeception and Cypress
  • Building reactive Craft Commerce product page with Sprig plugin
  • Dynamically generated PDF attachments for Freeform submissions
  • Using template hooks in Craft CMS
  • Alpine JS modal component for Craft CMS
  • Using template UI elements to extend Craft CMS control panel
  • Matrix within a Matrix - possible solutions for Craft CMS
  • Universal email template for Craft CMS
  • Creating attributes table from entry fields in Craft CMS
  • Namespacing forms in Craft CMS
  • Creating map-based navigation for Craft CMS
  • Placeholder image macro for Craft CMS
  • Building AJAX contact form with Craft CMS
  • Using incognito field plugin for Craft CMS
  • Email footer creator made with Craft CMS
  • Infinite scrolling and lazy loading with Craft CMS
  • Using Javascript in Twig templates with Craft CMS
  • Twig templating tips and tricks for Craft CMS
  • Basic SEO functionality for Craft CMS
  • Working with dates in Craft CMS templates
  • Working with SVG images in Craft CMS templates
  • Responsive and lazy-loaded youtube videos with Craft CMS
  • Debugging and inspecting Twig templates in Craft CMS
  • Creating article excerpts with Twig component in Craft CMS
  • Adding favicons to Craft CMS website
  • Truncating text with Twig macros in Craft CMS
  • Universal language switcher for Craft CMS
  • Read time macro for Craft CMS
  • Using attr() function to render HTML attributes in Craft CMS
  • Building dynamic, AJAX based pagination for Craft CMS
  • How to add Disqus comments to Craft CMS website
  • Ellipsis pagination component for Craft CMS
  • Converting email addresses into links using Twig macro
  • Breadcrumb created from URL for Craft CMS
  • Best developer-oriented Craft CMS plugins
  • Search autocomplete component for Craft CMS
  • RSS feed - template component for Craft CMS
  • Testing emails sent by Craft CMS using Mailtrap
  • Quick edit link - Twig component for Craft CMS
  • Filtering entries in control panel using Searchit plugin
  • Fetching routes into Twig templates in Craft CMS


Frontend testing for Craft CMS websites with Codeception and Cypress

Building reactive Craft Commerce product page with Sprig plugin

Dynamically generated PDF attachments for Freeform submissions

Using template hooks in Craft CMS

Alpine JS modal component for Craft CMS

Using template UI elements to extend Craft CMS control panel

Matrix within a Matrix - possible solutions for Craft CMS

Universal email template for Craft CMS

Copyright ©2023 Piotr Pogorzelski