Jekyll календарь на чистом Liquid template engine

Jekyll календарь на чистом Liquid template engine

Захотел попробовать сделать для своего блога на Jekyll календарь с использованием Liquid template engine. Не хотелось использовать JS библиотеки, решил написать календарик на чистом Liquid.

Предыстория

Делал календарик для отображения даты публикации постов. Решил не заморачиваться с написанием или поиском плагинов, взялся делать самостоятельно. К тому же, изучая CSS grid system понял, что делая минимум телодвижений можно заставить отображаться сквозной “список” дней с разбивкой на недели.

Jekyll календарь на чистом Liquid

Первым делом думал о получении даты начала месяца. Сделать это просто:

{{ 'now' | date: '%Y-%m-01' }}

Следующее что стоило сделать — каким-то образом перебрать все дни. Сделать это можно легко. Благо в сутках 24 часа =)

{% for i in (0..30) %}
{% assign day = 86400 | times: i | plus: month_starts_ts %}
{% endfor %}

Оставалась ещё проблемка: выводить нужно дни до первого числа месяца, чтобы правильно отобразить календарь средствами CSS grid. Пришлось оглядываться назад на недельку и вставлять заглушки для дней с прошлого месяца. Можно конечно и отображать, но делать цвет шрифта приглушённым.


{% for i in (-7..30) %}

{% assign day = 86400 | times: i | plus: month_starts_ts %}
{% assign dow = day | date: '%u' %}
{% assign m = day | date: '%m' %}

{% unless fd %}
{% if dow == '7' %}{% assign fd = true %}{% endif %}
{% continue %}
{% endunless %}

{% if month == m %}

{% case dow %}
{% when '6' %}<span class="calendar__we {{ has_posts }} ">
  {% when '7' %}<span class="calendar__we {{ has_posts }}">
  {% else %}<span class="{{ has_posts }}">
{% endcase %}{{ day | date: '%e' }}</span>

{% else %}<span></span>{% endif %}

{% endfor %}

Таким образом, fd сигнализирует о том, что попали на первый день календарного месяца.

Осталось отобразить наличие опубликованных постов в определённый день. С наскоку заюзать фильтр по дате не удалось, сделал через обычное условие.

Итоговый вид скрипта:


{% assign month_starts = 'now' | date: '%Y-%m-01' %}
{% assign month_starts_ts = month_starts | date: "%s" %}
{% assign month = 'now' | date: "%m" %}
{% assign fd = false %}
<div class="calendar">
<b>Пн</b><b>Вт</b><b>Ср</b><b>Чт</b><b>Пт</b>
<b class="calendar__we">Сб</b>
<b class="calendar__we">Вс</b>
{%- for i in (-7..30) %}
{%- assign day = 86400 | times: i | plus: month_starts_ts %}
{%- assign dow = day | date: '%u' %}
{%- assign m = day | date: '%m' %}
{%- assign dayf = day | date: "%Y-%m-%d" %}
{%- unless fd %}
{%- if dow == '7' %}{% assign fd = true %}{% endif %}
{%- continue %}
{%- endunless %}

{%- if month == m %}
{%- assign has_posts = '' %}
{%- for post in site.posts %}
    {%- assign d = post.date | date: "%Y-%m-%d" %}
    {%- if d == dayf %}{% assign has_posts = 'calendar__ext' %}{% break %}{% endif %}
{%- endfor %}
{%- case dow %}
{%- when '6' %}<span class="calendar__we {{ has_posts }} ">
  {%- when '7' %}<span class="calendar__we {{ has_posts }}">
  {%- else %}<span class="{{ has_posts }}">
{%- endcase %}{{ day | date: '%e' }}</span>
{%- else %}<span></span>{% endif %}
{%- endfor %}
</div>

Вёрстка календаря средствами CSS grid

С сеткой всё просто, когда знаешь, как пользоваться. Нужно указать ширину и высоту ячеек и их количество в строке.

.calendar {
  display: grid;
  grid-template-columns: repeat(7, 2rem);
  line-height: 2rem;
  text-align: center;
}
.calendar__we {
  color: #e22;
}
.calendar__ext {
  font-style: normal;
  position: relative;
  &:after{
    content: '•';
    position: absolute;
    top: -.45em;
    right: .125em;
  }
}

Заключение

Такой календарь удобно использовать скорее для бо́льших промежутков времени, т.к. всей картины периодичности постинга не видно. Однако, это мой первый опыт доскональной работы с Jekyll Liquid template engine и реализации календаря с использованием модного и удобного CSS grid.

Поделиться в соцсетях:

Занимаюсь front-end разработкой, улучшаю UX. Рассказываю о железячных проектах, настройке сервера, полезных Android приложениях.

Чтобы не пропускать новости, можно подписаться на email рассылку.