118 lines
5.8 KiB
HTML
118 lines
5.8 KiB
HTML
{{- /*
|
|
Tour schedule from data/schedule/<event>.yaml, one column of tour cards per day.
|
|
On narrow screens the days stack; with JavaScript a day picker shows one day at a time.
|
|
|
|
Usage: {{< schedule >}} on a section page (the event is the section name),
|
|
or {{< schedule 39c3 >}}.
|
|
*/ -}}
|
|
{{- $event := .Get 0 | default .Page.Section -}}
|
|
{{- /* A missing or empty data file, or one without tours, renders nothing but a warning. */ -}}
|
|
{{- $file := false -}}
|
|
{{- $days := slice -}}
|
|
{{- with hugo.Data.schedule -}}
|
|
{{- if isset . $event }}{{ $file = true }}{{ end -}}
|
|
{{- with index . $event }}{{ with .days }}{{ $days = . }}{{ end }}{{ end -}}
|
|
{{- end -}}
|
|
{{- $tourCount := 0 -}}
|
|
{{- range $days }}{{ with .tours }}{{ $tourCount = add $tourCount (len .) }}{{ end }}{{ end -}}
|
|
{{- if not $file -}}
|
|
{{- warnidf "warning-schedule-empty" "schedule: no data file data/schedule/%s.yaml: %s" $event .Position -}}
|
|
{{- else if not $tourCount -}}
|
|
{{- warnidf "warning-schedule-empty" "schedule: no tours in data/schedule/%s.yaml: %s" $event .Position -}}
|
|
{{- else -}}
|
|
{{- $id := printf "schedule-%s" $event | anchorize -}}
|
|
{{- /* Tour page titles start with the event name ("39C3 Rote Flora"); the cards don't need it. */ -}}
|
|
{{- $prefix := printf `(?i)^%s\s+` $event -}}
|
|
{{- /*
|
|
On wide screens tours line up by start time: every start time gets a grid row, or several
|
|
when one day has more than one tour starting then. $slotRow maps a time to its first row.
|
|
Every hour from the first to the last tour starts a new row ($hours) with a line above it,
|
|
so an hour without tours still gets a row.
|
|
*/ -}}
|
|
{{- $slotCount := dict -}}
|
|
{{- range $days -}}
|
|
{{- $count := dict -}}
|
|
{{- range .tours -}}
|
|
{{- $count = merge $count (dict .time (add (index $count .time | default 0) 1)) -}}
|
|
{{- end -}}
|
|
{{- range $time, $n := $count -}}
|
|
{{- if gt $n (index $slotCount $time | default 0) -}}
|
|
{{- $slotCount = merge $slotCount (dict $time $n) -}}
|
|
{{- end -}}
|
|
{{- end -}}
|
|
{{- end -}}
|
|
{{- $times := slice -}}
|
|
{{- range $time, $n := $slotCount }}{{ $times = $times | append $time }}{{ end -}}
|
|
{{- $hourOf := dict -}}
|
|
{{- range $times }}{{ $hourOf = merge $hourOf (dict . (int (strings.TrimLeft "0" (substr . 0 2) | default "0"))) }}{{ end -}}
|
|
{{- $slotRow := dict -}}
|
|
{{- $hours := slice -}}
|
|
{{- $rows := 0 -}}
|
|
{{- range $hour := seq (index $hourOf (index $times 0)) (index $hourOf (index $times (sub (len $times) 1))) -}}
|
|
{{- $start := add $rows 1 -}}
|
|
{{- range $time := $times -}}
|
|
{{- if eq (index $hourOf $time) $hour -}}
|
|
{{- $slotRow = merge $slotRow (dict $time (add $rows 1)) -}}
|
|
{{- $rows = add $rows (index $slotCount $time) -}}
|
|
{{- end -}}
|
|
{{- end -}}
|
|
{{- if eq $rows (sub $start 1) }}{{ $rows = $start }}{{ end -}}
|
|
{{- $hours = $hours | append (dict "hour" $hour "row" $start) -}}
|
|
{{- end -}}
|
|
<div class="schedule" id="{{ $id }}" data-schedule>
|
|
<div class="schedule__picker" role="group" aria-label="{{ i18n "schedule_pick_day" }}" hidden>
|
|
{{- range $days }}
|
|
<button type="button" class="schedule__pick" aria-controls="{{ $id }}-day-{{ .day }}" aria-pressed="false" data-date="{{ .date }}">{{ i18n "schedule_day" (dict "Day" .day) }} <span class="schedule__pick-date">{{ time.AsTime .date | time.Format "2.1." }}</span></button>
|
|
{{- end }}
|
|
</div>
|
|
<div class="schedule__days" style="--schedule-days: {{ len $days }}; --schedule-rows: {{ $rows }}">
|
|
{{- range $column, $day := $days }}
|
|
<section class="schedule__day" id="{{ $id }}-day-{{ .day }}" aria-labelledby="{{ $id }}-day-{{ .day }}-title" style="--schedule-column: {{ add $column 1 }}">
|
|
<h2 class="schedule__day-title" id="{{ $id }}-day-{{ .day }}-title">{{ i18n "schedule_day" (dict "Day" .day) }} <span class="schedule__date">{{ time.AsTime .date | time.Format "Mon 2.1." }}</span></h2>
|
|
<ol class="schedule__list">
|
|
{{- $seen := dict }}
|
|
{{- range sort (.tours | default slice) "time" }}
|
|
{{- $nth := index $seen .time | default 0 }}
|
|
{{- $seen = merge $seen (dict .time (add $nth 1)) }}
|
|
{{- $page := $.Page.GetPage .tour }}
|
|
{{- if not $page }}{{ warnf "schedule: %s: no page for tour %q on day %v" $event .tour $day.day }}{{ end }}
|
|
{{- $entry := . }}
|
|
{{- $soldOut := eq .status "soldout" }}
|
|
{{- /* A tour's own title, in the page's language, replaces its page's title. */}}
|
|
{{- $ownTitle := "" }}
|
|
{{- with .title }}{{ $ownTitle = index . site.Language.Name | default (index . "en") }}{{ end }}
|
|
<li class="schedule__card{{ if $soldOut }} schedule__card--soldout{{ end }}" style="--schedule-row: {{ add (index $slotRow .time) $nth }}">
|
|
<span class="schedule__when">
|
|
<time class="schedule__time" datetime="{{ $day.date }}T{{ .time }}">{{ .time }}</time>
|
|
{{- if $soldOut }}
|
|
<span class="schedule__status">{{ i18n "schedule_soldout" }}</span>
|
|
{{- end }}
|
|
</span>
|
|
{{- with .lang }}
|
|
<span class="schedule__langs">{{ range (cond (reflect.IsSlice .) . (slice .)) }}{{ partial "lang-badge.html" (dict "code" . "class" "schedule__lang") }}{{ end }}</span>
|
|
{{- end }}
|
|
{{- with $page }}
|
|
{{- $title := $ownTitle | default (.LinkTitle | replaceRE $prefix "") }}
|
|
<a class="schedule__title" href="{{ .RelPermalink }}" title="{{ $title }}">{{ $title }}</a>
|
|
{{- else }}
|
|
<span class="schedule__title">{{ $ownTitle | default $entry.tour }}</span>
|
|
{{- end }}
|
|
</li>
|
|
{{- end }}
|
|
</ol>
|
|
</section>
|
|
{{- end }}
|
|
{{- /* Hour lines; where the first day has no tour in the hour's first row, its column shows the hour.
|
|
They sit in .schedule__days, whose first row holds the day titles, hence the + 1. */}}
|
|
{{- $firstDay := index $days 0 }}
|
|
{{- range $hours }}
|
|
{{- $row := .row }}
|
|
<div class="schedule__hour" style="--schedule-row: {{ add .row 1 }}" aria-hidden="true">
|
|
{{- $busy := false }}
|
|
{{- range $firstDay.tours }}{{ if eq (index $slotRow .time) $row }}{{ $busy = true }}{{ end }}{{ end }}
|
|
{{- if not $busy }}<span class="schedule__hour-label">{{ printf "%02d:00" .hour }}</span>{{ end -}}
|
|
</div>
|
|
{{- end }}
|
|
</div>
|
|
</div>
|
|
{{- end }}
|