Doplněk Timestamp

Vít Petira 5 minuty, 40 sekundy 476 doplňky dokumentace yaml

Při používání Grav CMS lze narazit na omezení, která souvisejí s proměnnými typu datum, resp. v nich uložených hodnotách, které jsou typu řetězec. Proto vznikl doplněk Timestamp, který uvedené nedostatky řeší tím, že dynamicky přepisuje hodnoty všech vybraných proměnných typu datum z rozpoznatelného formátu řetězec na hodnotu ve formátu časové razítko. Pokud proměnná není na stránce uvedena, lze ji doplňkem Timestamp případně vytvořit a naplnit zvolenou hodnotou.

Časové razítkoNež si představíme nový doplněk Timestamp, který byl zveřejněn dne 23. 1. 2023, dopřejme si nejprve trochu obecného povídání.

Před nějakým časem vznikl doplněk Stamp, který nyní dostal bratříčka. Podobnost názvů je úmyslná, ale každý doplněk provádí zcela něco jiného a jsou na sobě zcela nezávislé. Ovšem jejich propojením vznikne mocný nástroj, který Gravu umožní snadné zpracování proměnných typu datum. Z předchozích příspěvků víme, že doplněk Stamp automaticky ukládá do hlavičky stánky mimo jiného i datum editace. Činí tak ve zvoleném formátu data, např. Y-m-d H:i:s, m/d/Y H:i:s nebo klidně H:i:s d-m-Y. Všechny uvedené zápisy data jsou korektní a nic by tedy nemělo bránit jejich budoucímu zpracování.

Korektní formáty zápisu data jsou všechny, které dokáže rozpoznat funkce strtotime().

Ale… Při bližším prozkoumání zjistíme, že narážíme na dvě zásadní omezení.

Ačkoliv se dále používá obecně slovo datum, je jím myšleno konkrétní určení času, tedy včetně hodin, minut a sekund.

Prvním omezením je, že se datum ukládá do hlavičky stránky, což není nic jiného než YAML soubor. Na rozdíl od relační databáze, kde se u příslušného sloupce definuje datový typ (např. řetězec, číslo, resp. v našem případě datum – názvy se u jednotlivých databázových strojů liší, proto je uvádím pouze obecně), podle něhož databázový stroj příslušnou položku záznamu ukládá a zpracovává, se nic takového v úložišti YAML neděje. Prakticky se do YAML dají uložit pouze řetězce, čísla, logické hodnoty (true/false), seznamy nebo (vícerozměrná) pole, popř. nepřiřazená hodnota null. Zatímco tedy v relační databázi můžeme s položkami záznamu na základě jejich typů snadno pracovat, v případě YAML je to složitější, neboť proměnné nemají datový typ nikde definován.

Pokud je hodnota proměnné např. 23 nebo 3.1415926, jedná se logicky o čísla a můžeme s nimi provádět matematické operace. V ostatních případech se obvykle jedná o řetězce, tedy např. 'Vít Petira', 'Doplněk Timestamp', image-001.jpg atd. Když se podíváme na formát data, např. '2022-11-29 17:08:22', zjistíme, že se jedná rovněž o řetězec. Budeme-li tedy potřebovat příspěvky seřadit podle data editace, např. od nejstaršího po nejnovější, bude řazení prováděno de facto abecedně. V případě formátu data '2022-11-29 17:08:22' (Y-m-d H:i:s) na zásadní problém nenarazíme, neboť řazení proběhne podle hodnot znaků zleva doprava.

Ale co v případě formátů m/d/Y H:i:s nebo dokonce H:i:s d-m-Y? Je evidentní, že zde by již řazení neproběhlo, jak má. Příklady uvádět nebudu, myslím, že je to dostatečně zřejmé. Zásadní problém spočívá v rozdílných hodnotách, kterých může zcela shodné datum uložené v řetězci nabývat. A to nemluvím o případu, kdy každá stránka bude mít datum uložený v jiném formátu, což je samozřejmě možné. Tudy tedy cesta nevede.

Druhým omezením je počitatelnost položek typu datum uložených v řetězci. Pokud budeme chtít znát rozdíl mezi dvěma daty, nebo vypočítat relativní dobu od publikování příspěvku, máme problém. A nebude nám nic platný ani jednotný formát data Y-m-d H:i:s.

Určitá řešení pro výpočet hodnot jsou, např. i v rámci Twigu, ale nepomohou třeba v případě řazení, kde je již nutné použít konkrétní hodnotu.

Abychom se posunuli od teorie k praxi. Řešení existuje, a to velmi elegantní. Datum uložené jako řetězec v libovolném rozpoznatelném formátu jednoduše převedeme na časové razítko, tedy na timestamp. Časové razítko není nic jiného, než číslo v intervalu 0, které odpovídá datu 1. 1. 1970 00:00:00 UTC, až 2147483647, které odpovídá datu 19. 1. 2038 03:14:07 UTC. Pro případné zájemce doporučuji vygooglit témata Epoch Time, Unix Time a jím podobná. Předpokládám ale, že se s uvedenými pojmy již každý alespoň okrajově setkal.

Grav CMS pracuje s výchozí systémovou hodnotou date, pokud je v hlavičce stránky uvedena, resp. s její virtuální alternativou modified, která odpovídá datu poslední editace souboru, rovněž jako s časovým razítkem.

Zbývá tedy to poslední, což je převést hodnoty z řetězců na časové razítko. Grav CMS to u uživatelských (vlastních) proměnných prozatím neumí a z diskuzí je zřejmé, že spousta uživatelů na uvedený problém narazila a potřebují jej vyřešit. Shodný problém jsem řešil v minulosti i já, když jsem na úvodní stránku Grav.cz umístil výpis 10 naposledy upravených příspěvků. Řazení narazilo právě na omezení, že Grav.cz má historicky nastavený formát data H:i:s Y-m-d a musel jsem přistoupit k alternativnímu řešení, kdy řazení bylo prováděno podle hodnoty proměnné modified, ale s uvedeným řešením jsem se nehodlal trvale spokojit. Uvedené mě motivovalo k napsání doplňku Timestamp, který řeší všechna shora uvedená omezení a nabízí ještě spoustu dalších vylepšení.

Níže uvedené časy a hodnoty jejich časového razítka odpovídají UTC. V naší časové zóně je rozdíl v hodnotě časového razítka 3600 (1 hodina) v případě zimního (standardního) času a 7200 (2 hodiny) v případě letního času. O správné výpočty se postará Grav CMS, který ve výchozím nastavení používá lokální čas serveru, resp. v pokročilém nastavení použije časovou zónu zadanou správcem webu.

Podrobný návod je v souboru README.md. Zde jenom ve stručnosti uvedu základní vlastnosti:

  • přepsání vybrané původní proměnné z původní hodnoty ve formátu řetězec na novou hodnotu ve formátu timestamp, např. date_modified = '14:36:27 18-01-2023' => date_modified = 1674052587,
  • vytvoření nové proměnné s novou hodnotou ve formátu timestamp, a to z vybrané původní proměnné, resp. z její původní hodnoty ve formátu řetězec, např. date_modified = '14:36:27 18-01-2023' => date_modified_new = 1674052587,
  • postupné přepisování hodnot proměnných, kdy lze do „uvolněné“ proměnné vložit jinou hodnotu, např. date_modified = '14:36:27 18-01-2023' => date_modified_new = 1674052587, date_created = '2020-11-29 17:08:22' => date_modified = 1606669702, přičemž platí, že hodnoty uvedené níže přepisují hodnoty uvedené výše,
  • volitelné naplnění hodnot původních proměnných, pokud jsou prázdné, resp. vůbec neexistují, např. do proměnné date_modified lze přiřadit hodnotu modified nebo počátku epochy UNIXu (kompletní výběr možností, resp. příkazů je k dispozici v souboru README.md).

Pro úplnost dodávám, že veškeré přepisy hodnot proměnných se provádějí dynamicky v rámci dané relace a původní hodnoty nejsou nijak upravovány či dokonce ukládány v rámci hlavičky stránky.

Všechny proměnné jsou uživatelsky definované (vlastní), což znamená, že jsou vždy přístupné výhradně přes header, včetně manipulace v kolekcích, například při řazení.

Doplněk Timestamp je kromě výchozí anglické verze plně lokalizován do češtiny a připraven i pro přidání překladů do dalších jazyků, ale to už je na zahraničních uživatelích, zda je vytvoří a následně poskytnou ke zveřejnění.

Doplněk Timestamp funguje i na vícejazyčných webech, pouze je třeba upravit nastavený jazykových verzí, podle návodu v README.md, jinak dojde k pádu. Přímá podpora v doplňku bude doplněna v některé budoucí verzi.

Doplněk Timestamp je aktuálně dostupný ve verzi 1.0.0 v repozitáři. Po validaci ze strany autorů Grav CMS bude k dispozici i v seznamu doplňků a současně i k přímé instalaci přes Admin Panel.

Nalezli jste v článku chybu, ať již gramatickou nebo faktickou? Článek prošel pouze autorskou korekturou a drobné nedostatky, jako překlepy nebo chybný slovosled, se v něm mohou vyskytovat. Pokud je objevíte, pomozte příspěvek upravit oznámením přes kontaktní formulář nebo na e-mail. Budou vám vděčni nejen autoři, ale zejména ostatní čtenáři.

Pomozte Grav.cz prolinkovat. Projekt Grav.cz se za dva roky provozu rozrostl a ve starších příspěvcích na Blogu mohou být uvedeny pasáže, které by stálo za to prolinkovat na konkrétní související řešení, která jsou uvedena v následujících příspěvcích. Pokud takové objevíte, pošlete informaci přes komunikační kanály uvedené v předchozím nebo následujícím odstavci.

Diskuze k článku není k dispozici. Pokud ale máte k tématu článku podněty, připomínky nebo dotazy, je možné je sdělit ve skupině na Facebooku, kde se k nim vyjádří nejen autor, ale případně i další diskutující.

Předchozí příspěvek Následující příspěvek