Trans­lat­able cus­tom dates in Twig tem­plates of Drupal 8

How to use Twig with Drupal

Displaying dates here and there on a site is a quite common task. Let’s see some examples how to handle it in Drupal 8 Twig!

https://www.flickr.com/photos/kecko/15174912056/

Displaying dates here and there is quite a common task. Let's see some examples of how to handle it in Drupal 8 Twig!

In this tutorial, we will work on the page.html.twig file. You have to have your custom theme and your page template if you want to try the examples in this article.

Display copyright message with automatically updating end date

Let's start with a simple task: display a copyright message in which the end date updates automatically. All we have to do is adding this shortcode to the template.

<p>{{ 'All rights reserved 2015–'|t }}{{ 'now'|date('Y') }}.</p>

Let's see what happens here. The first part is just a string to which I added the Drupal specific t filter (could be trans too). It makes the string translatable through the admin interface.

In the second part I used the now keyword, which is supported by the strtotime function of PHP. Then I added the date() filter of Twig and set the format — using date syntax of PHP — to year only. And because we display alone the year, there is no need for translation.

Display current date

Imagine that your customer wants the current date to be shown in the site header. It would be comfortable using the same technique as above. We should only change the format to include month and day in the date() filter.

But what happens if we build a multilingual site? Then we have to deal with the different date formats of the different languages. It makes our life and our code a little more complicated:

{% set current_date = date()|date('U')|format_date('short') %}

<p>{% trans %}The current date is {{ current_date|placeholder|striptags }}{% endtrans %}</p>

Again, let's analyze it step by step.

First I created a new variable current_date using Twig's set tag and I assigned it to the value of actual date (and time) using the date()function instead of the date() filter.

"Wait a minute, man! You did not pass any argument to the date()function!" — you could say. Yes, it is true. But I didn't have to, because if no argument is passed, the function returns the current date.

Our old friend, the date() filter returns, and in this case, we format the data as a Unix timestamp. It is needed because of the second filter Drupal 8's own format_date() works with timestamp only. Its job is to transform the input to a date format that exists in Drupal. The date format can be defined by the system, a module, or the administrator, and we can choose by providing its machine name as an argument to the filter.

Now, that the variable is all set up, let's display the value. When we want to make a block of text — which includes variables — translatable it has to be surrounded by the trans and endtrans tags.

After the variable, there are two new filters. Again, the first one the placeholder is Drupal specific. If we did not use it, all new dates would generate a new translatable string.

I do not know the reason, but the placeholder filter (or, more precisely, the invoked drupal_placeholder() function) makes the content display as emphasized text. That is why we need the second filter striptags , which "strips SGML/XML tags and replaces adjacent whitespace by one space."

Display node's publication date and last updated date

Let's say that our customer wants the publication date and the "last updated" date of nodes displayed above the content title in full node view. Knowing and understanding the previous "current date" example, it won't be tricky. Only a small modification is needed.

{% if node.created.value and node.changed.value is defined %}
  {% set node_pub = node.created.value|format_date() %}
  {% set node_upd = node.changed.value|format_date() %}
  <p>{% trans %}Published: {{ node_pub|placeholder|striptags }}, last updated: {{ node_upd|placeholder|striptags }} {% endtrans %}</p>
{% endif %}

As you see, it is almost the same as before. There are just three things to mention.

First: we do not need the date() function, because we are working with Drupal data now. If we were in node.html.twig, we might use the date variable which displays a themed "creation date" field. But we do not know an equivalent for "updated date," and we are on page.html.twig. Thus, we have to use node.created.value and node.changed.value.

Second: the dates don't need to be transformed to a timestamp because Drupal uses that format already.

Third: there must be an if statement around the code block to check if created and updated date information is available. Drupal provides this data on node pages only, and without this check, all other pages (e.g., frontpage, user login, any views list, etc.) would break.

Want more?

Translatable, custom dates in Twig templates of Drupal 8

I'll talk about Short twig recipes for Drupalers — like these — at Drupal Iron Camp in Prague at the end of November 2016. Come and let's "cook" together! Please check my example repo!

Share with your friends!