Polskie daty w Hugo
• tech • 663 słowa • 4 minuty czytania
Blog ten prowadzony jest w ojczystym języku, zatem dobrze jest zadbać o poprawne polskie zasady językowe, sformułowania, tłumaczenia, zwroty… Dotyczy to także dat i odmian nazw miesięcy. Kiedyś na szybko zrobiłem jakiś hack w szablonie używanym w WordPresie, a teraz muszę coś podobnego ogarnąć na stronie w Hugo.
Generator Hugo mimo iż posiada jakieś wsparcie dla wielojęzycznych stron, to jednak nie dotyczy to samych dat. Póki co język Go, w jakim tworzone jest to narzędzie, nie posiada takiej możliwości. Przy formatowaniu dat z nazwami lub skrótami miesięcy i dni tygodnia dostaniemy standardowe angielskie słówka.
Wiele rozwiązań tego problemu można znaleźć w sieci. Bazują one głównie na idei przedstawionej w dokumentacji - w dodatkowych plikach z danymi (lub w miejscu trzymania tłumaczeń) przechowywane są listy z nazwami miesięcy, do których mamy dostęp w szablonie. W poszczególnych implementacjach, zależnie od struktury i dostępnej wielojęzyczności strony, całość może się nieznacznie różnić w szczegółach.
Ja nie chcę dodawać specjalnie jednego pliku z nazwami miesięcy. No może gdybym miał więcej “jakiś” szablonowych danych na stronie to byłoby inaczej. Zamiast tego mógłbym wrzucić to w dodatkowe parametry w pliku konfiguracyjnym:
params:
months: [
unused, stycznia, lutego, marca, kwietnia, maja, czerwca,
lipca, sierpnia, września, października, listopada, grudnia
]
i użyć bezpośrednio w szablonie:
<time>{{ .Date.Day }} {{ index .Site.Params.Months .Date.Month }} {{ .Date.Year }}</time>
Niemniej nie chcę także zaśmiecać sobie “configa” niekonfiguracyjnymi rzeczami, więc pozostaje trzymanie takiej tablicy w szablonie. Żeby się nie powtarzać w szablonach to idealnym miejscem do tego są szablony cząstkowe.
A może iść dalej i zrobić sobie dedykowaną funkcję? W szablonach Go/Hugo nie ma możliwości tworzenia funkcji, ale za pomocą partial, które od jakiegoś czasu wspierają zwracanie wartości można zasymulować taką funkcję.
{{/*
Get month name in Polish language
usage: $month := partial "func/GetMonthName" <date-obj>
*/}}
{{ $Months := slice "unused" "stycznia" "lutego" "marca" ... "października" "listopada" "grudnia" }}
{{ return index $Months .Month }}
Powyższy kod zapisany w pliku partials/func/GetMonthName.html
można “wywołać” tak:
<time>
{{- .Date.Day }} {{ partial "func/GetMonthName" .Date }} {{ .Date.Year -}}
</time>
Może mógłbym to tak zostawić. Jednak skoro daty będą prezentowane w tagu <time/>
w niestandardowej formie to wypada dołączyć machine-readable znacznik czasu. Idealnie, aby był on formacie zgodnym z ISO 8601. Dodatkowo, przewiduję taką postać daty wyświetlać tylko w kontekście wpisów (posty, listy). To prowadzi mnie do zapakowania wszystkiego inline w dedykowany szablon cząstkowy, który wygeneruje taki oto fragment HTML-a:
<time datetime="2020-06-15T12:00:00+02:00">15 czerwca 2020</time>
Do otrzymania daty w postaci ISO8601/RFC3339 należy użyć taki ciąg formatujący: "2006-01-02T15:04:05Z07:00"
. Wynika to ze sposobu formatowania dat w Hugo. Bazuje on na pakiecie time z Go, który to używa trochę nienaturalnego zapisu w porównaniu do innych języków i przyzwyczajeń. Opiera się na referencyjnej dacie Jan 2 15:04:05 2006 MST
i numerycznych pozycjach w stringu. Szczegóły w dokumentacji, a ciekawostki na stronie “Hugo dateFormat”.
Składając wszystko do kupy, otrzymałem w pliku partials/post-date-tag.html
taki kod:
{{/*
Render <time/> tag with post date in Polish
usage: partial "post-date-tag.html" <date-obj>
*/}}
{{- $ISO8601 := "2006-01-02T15:04:05Z07:00" -}}
{{- $Months := slice "unused" "stycznia" "lutego" "marca" ... "października" "listopada" "grudnia" -}}
<time {{ .Format $ISO8601 | printf "datetime=%q" | safeHTMLAttr }}>
{{- .Day }} {{ index $Months .Month }} {{ .Year -}}
</time>
Żeby zapobiec “wy-escape-owaniu” znaku +
w wynikowym stringu trzeba go przepuścić przez safeHTMLAttr
, a ten działa na pełnym atrybucie (name=value), dlatego taki trochę potworek wychodzi ;)
Taki “partial” zaspokaja moje obecne potrzeby z formatowaniem dat w polskich realiach. Na podobnej zasadzie można spolszczyć dni tygodnia, nie tylko pełne nazwy, ale i skróty. Jeśli jednak takie polskie odpowiedniki używane mają być w wielu miejscach i kontekstach to zdecydowanie lepiej będzie skierować się w stronę wspomnianych plików danych.
Do takich plików z danymi można także wrzucić jakieś “stałe”, które będą widoczne w szablonach. Takie elementy mogą też “naprawiać” napotykane niedociągnięcia - na przykład brak predefiniowanych stałych z formatem dat jakie dostępne są w time.go
. Trzeba samemu się posiłkować, co widać było wyżej w moim kodzie ($ISO8601
). To na pewno poprawiłoby czytelność i mogło ustrzec przed głupimi błędami, czy literówkami…
Komentarze (0)