Skip to content

Instantly share code, notes, and snippets.

@dsiebel
Created October 18, 2013 06:41
Show Gist options
  • Save dsiebel/7037385 to your computer and use it in GitHub Desktop.
Save dsiebel/7037385 to your computer and use it in GitHub Desktop.
A Twig template rendering a calendar/datepicker.
{#
time can be any string acceptable by http://www.php.net/strtotime, the
template will output that time's month.
If you don't want to pass in a date you can set time like this:
{% set time = "now"|date("U") %}
{% set time = "December 2012"|date("U") %}
How ever you want to output items onto the calendar is a different issue,
but I'd assume pushing everything into an array numerically indexed by that day:
$days = array(1=>array('Something on the first'),31=>array('Halloween'));
#}
{% set data = data|default([]) %}
{% set today = date("today") %}
{% set time = date(time|default(today)) %}
{% set numberOfMonth = numberOfMonth|default(3) %}
{% set spanOtherMonth = spanOtherMonth|default(false) %}
{% set firstDay = firstDay|default(1) %}
{% set dateStringToday = time|date('Y-m-d') %}
{% set disableNavigation = disableNavigation|default(false) %}
{% set prevText %}<i class="cal-icon-prev">&laquo;</i>{% endset %}
{% set nextText %}<i class="cal-icon-next">&raquo;</i>{% endset %}
{% set daynames = daynames|default({
0: { short: 'calendar_short_day_sunday' | translate, full: 'calendar_full_day_sunday' | translate },
1: { short: 'calendar_short_day_monday' | translate, full: 'calendar_full_day_monday' | translate },
2: { short: 'calendar_short_day_tuesday' | translate, full: 'calendar_full_day_tuesday' | translate },
3: { short: 'calendar_short_day_wednesday' | translate, full: 'calendar_full_day_wednesday' | translate },
4: { short: 'calendar_short_day_thursday' | translate, full: 'calendar_full_day_thursday' | translate },
5: { short: 'calendar_short_day_friday' | translate, full: 'calendar_full_day_friday' | translate },
6: { short: 'calendar_short_day_saturday' | translate, full: 'calendar_full_day_saturday' | translate }
}) %}
{% set monthnames = monthnames|default({
1: { short: 'january' | translate, full: 'january' | translate},
2: { short: 'february' | translate, full: 'february' | translate},
3: { short: 'march' | translate, full: 'march' | translate},
4: { short: 'april' | translate, full: 'april' | translate},
5: { short: 'may' | translate, full: 'may' | translate},
6: { short: 'june' | translate, full: 'june' | translate},
7: { short: 'july' | translate, full: 'july' | translate},
8: { short: 'august' | translate, full: 'august' | translate},
9: { short: 'september' | translate, full: 'september' | translate},
10: { short: 'october' | translate, full: 'october' | translate},
11: { short: 'november' | translate, full: 'november' | translate},
12: { short: 'december' | translate, full: 'december' | translate}
}) %}
{% if app.debug %}
<!-- // DEBUG
data: {{ data|json_encode }}
today: {{ today.format('Y-m-d H:i:s') }}
time: {{ time.format('Y-m-d H:i:s') }}
numberOfMonth: {{ numberOfMonth }}
spanOtherMonth: {{ spanOtherMonth }}
firstDay: {{ firstDay }}
disableNavigation: {{ disableNavigation }}
-->
{% endif %}
<div class="cal-calendar{% if numberOfMonth > 1 %} cal-group{% endif %}">
{% if not disableNavigation -%}
<div class="cal-btn">
<a class="cal-prev" title="">
<span class="cal-prev-btn">{{ prevText | raw }}</span>
</a>
</div>
{%- endif %}
{% for i in range(0, numberOfMonth-1) -%}
{% if not loop.first %}
{% set time = time|date_modify('+1 month') %}
{% endif %}
{% set year = time.format('Y') %}
{% set month = time.format('m') %}
{% if app.debug %}
<!-- // DEBUG
loop.index: {{ loop.index }}
time: {{ time.format('Y-m-d H:i:s') }}
year: {{ year }}
month: {{ month }}
-->
{% endif %}
<div class="cal-month{% if loop.first %} cal-group-first{% endif %}{% if loop.last %} cal-group-last{% endif %}" data-year="{{ year }}" data-month="{{ month }}">
<table>
<thead>
<tr>
<th colspan="7" class="center cal-month-title">
{{ monthnames[month].full }}
</th>
</tr>
<tr>
{% for dow in range(0, 6) %}
{% set day = (dow + firstDay) % 7 %}
<th><span title="{{ daynames[day].full }}">{{ daynames[day].short }}</span></th>
{% endfor %}
</tr>
</thead>
<tbody>
{% set daysInMonth = time.format('t') %}
{% set startDow = (time.format('F 1\\s\\t Y')|date('w')) %}
{% set dow = startDow %}
{% set pos = (7 + (startDow - firstDay)) % 7 %}
<tr class="cal-week">
{% for dom in range(1,daysInMonth) -%}
{#
TODO
- disable days before today in calendar
-
#}
{% set dom_date_s = "%d-%02d-%02d"|format(year, month, dom) %}
{% set dom_date = date(dom_date_s) %}
{% set dom_id = "cal_" ~ ("%d%02d%02d"|format(year, month, dom)) %}
{% set cal_day_classes = (
'cal-day'
~ (dom_date < today ? ' cal-unselectable' : '')
~ ((pos + firstDay + 6) % 7 >= 5 ? ' cal-weekend' : '')
~ (data[dom_date_s] is defined ? ' cal-day-data' : '')
) %}
{% if loop.first and pos > 0 -%}
{% if not spanOtherMonth %}
{% for _dom in range(1, pos) -%}
<td class="cal-day"><span>&nbsp;</span></td>
{%- endfor %}
{% else %}
<td colspan="{{ pos }}"><span>&nbsp;</span></td>
{% endif %}
{%- endif %}
<td id="{{ dom_id }}" class="{{ cal_day_classes }}" data-date="{{ dom_date_s }}" data-handler="selectDay" data-event="click">
<a{% if data[dom_date_s] is defined %} title="{{ data[dom_date_s] }}"{% endif %}>
{{- dom -}}
</a>
</td>
{% if loop.last and pos != 6 -%}
{% if not spanOtherMonth %}
{% for _dom in range(1, 6 - pos) -%}
<td class="cal-day"><span>&nbsp;</span></td>
{%- endfor %}
{% else %}
<td colspan="{{ 6 - pos }}"><span>&nbsp;</span></td>
{% endif %}
{%- endif %}
{% if pos == 6 and not loop.last %}
{% set pos = 0 %}
{% set dow = firstDay %}
</tr>
<tr class="cal-week">
{% else %}
{% set dow = (dow + 1) % 7 %}
{% set pos = pos + 1 %}
{% endif %}
{%- endfor %}
</tr>
</tbody>
</table>
</div>
{%- endfor %}
{% if not disableNavigation -%}
<div class="cal-btn">
<a class="cal-next" title="">
<span class="cal-next-btn">{{ nextText | raw }}</span>
</a>
</div>
{%- endif %}
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment