Skip to content

Instantly share code, notes, and snippets.

@watershed
Last active July 2, 2021 10:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save watershed/5aba95f8a627891539a2e8e1a14a7f0a to your computer and use it in GitHub Desktop.
Save watershed/5aba95f8a627891539a2e8e1a14a7f0a to your computer and use it in GitHub Desktop.
CraftCMS datetime macro
{#
value : date and/or time value validated as not null (mandatory),
format : php date format string (mandatory),
options: {
prefix: string to append to processed format,
suffix: string to append to processed format,
tag : html tagname string,
html : markup, typically to be wrapped in a <time> element,
attr : hash of name:value attribute pairs
}
#}
{% macro datetime(value, format, options) %}
{% set timeFormats = ['g:i', 'G:i', 'h:i', 'H:i'] %}
{% set open = '' %}
{% set text = value|date(format) %}
{% set close = '' %}
{#
Values deriving from fields with date and time may have
the date set but not the time so make sure midnight
is not processed (assuming it is always out of scope)
#}
{% if format in timeFormats and text == '00:00' %}
{% set value = null %}
{% endif %}
{% if value %}
{% if options %}
{% set datetime = '' %}
{% set otherAttr = '' %}
{# Enclosing element is optional #}
{% if options.tag is defined %}
{% set datetime = options.tag == 'time' ? "datetime=\"#{text}\"" : '' %}
{# Write attributes other than 'datetime' #}
{% if options.attr is defined %}
{% for name, val in options.attr %}
{% set otherAttr = "#{otherAttr} #{name}=\"#{val}\"" %}
{% endfor %}
{% endif %}
{% set open = "<#{options.tag} #{datetime} #{otherAttr}>" %}
{% set close = "</#{options.tag}>" %}
{% endif %}
{#
Pass in markup from previous iterations of this macro with the same value:
e.g. When it has been used to generate inline elements to be wrapped in a <time> element
#}
{% set text = options.html is defined ? options.html : text %}
{# Prepend or append text #}
{% set text = options.prefix is defined ? "#{options.prefix}#{text}" : text %}
{% set text = options.suffix is defined ? "#{text}#{options.suffix}" : text %}
{% endif %}
{{ open|raw }}{{ text|raw }}{{ close|raw }}
{% endif %}
{% endmacro %}
@watershed
Copy link
Author

watershed commented Jun 20, 2021

Example application:

{# Day of week #}
{% set options = { suffix:',', tag:'span', attr:{class:'nowrap'} } %}
{% set dtDow %}{{ _self.datetime(value, 'D', options) }}{% endset %}

{# Short date #}
{% set options = {suffix:',', tag:'span', attr:{class:'nowrap'} } %}
{% set dtShort %}{{ _self.datetime(value, 'j M Y', options) }}{% endset %}

{# Start time #}
{% set options = { tag:'span' } %}
{% set tmStart %}{{ _self.datetime(value, 'H:i', options) }}{% endset %}
{% set tmStart = tmStart|trim %}

{# Wrap <time> element #}
{% set dtFormat = tmStart ? 'Y-m-d H:i' : 'Y-m-d' %}
{% set html     = "#{dtDow|trim} #{dtShort|trim} #{tmStart}" %}
{% set options  = { tag:'time', html:html } %}
{{ _self.datetime(value, dtFormat, options) }}

Which can generate:

<time datetime="2021-10-02 09:30">
    <span class="nowrap">Sat,</span> 
    <span class="nowrap">2 Oct 2021,</span> 
    <span>09:30</span>
</time>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment