.. vim: set noexpandtab fileencoding=utf-8 nomodified wrap textwidth=200 foldmethod=marker foldcolumn=4 ruler showcmd lcs=tab\:|- list:
giw2me - úvahy
################################################################################
:date: 2023.04.11 17:29:20
:modified: 2023.04.20 05:50:14
:tags: HowTo,giw2me,Makefile
:authors: Gilhad
:summary: Úvahy o giw2me a co má dělat Static Site Generátor
:title: giw2me - úvahy
%HEADER%
.. |styles2| raw:: html
Tato stránka je [OBSOLETE] - přešel jsem na novou verzi systému, kde jsou některé věci zcela jinak
|styles2|
.. role:: strike
intro
-------------------------------------------------------------------------------
Na nyxu se rozjela debata a já chci napsat (a časem vylepšit) poměrně dlouhou a rozsáhlou věc, co se mi bude později hodit, tak si ji napíšu tady a na Nyx jen pástnu a odkážu
Taky se mi bude hodit, že už tu mám celou existující situ, co dělá něco podobného a u každé stránky mám nahoře v černé navigační liště jako předposlední tlačítko SRC, které ukáže zdroják stránky,
takže se dá snadno podívat, co a jak kde je. A mám tu už pár článků a nějaké ty tagy, tak nemusím vymýšlet a rozepisovat umělé příklady, použiju reálná, živá data.
Upozornění - o `giw2me` budu mluvit jako o hotové věci, ačkoli ji teď zrovna píšu, protože se tím mnohé zjednodušší.
O co jde (co chci, ~analýza, ...)
-------------------------------------------------------------------------------
* `giw2me` znamená `GIlhadův Web 2 - Makefile Edition` a jde o `Static Site Generátor`
* |chatGPT >| `Static Site Generator` (`SSG`) je nástroj pro vytváření statických webových stránek. Na rozdíl od dynamických webových stránek, které jsou generovány na serverové straně, statické webové stránky jsou generovány předem a uživatelé obdrží hotový HTML obsah. SSG fungují tak, že vezmou obsah (např. v Markdownu) a šablonu, a poté vygenerují hotové HTML stránky. Tyto generované stránky mohou být hostovány na jakémkoliv webovém serveru, který podporuje statický obsah. SSG mají několik výhod, jako je rychlost načítání stránek, bezpečnost (protože není potřeba databáze ani serverového skriptování) a jednoduchost údržby. Některé populární SSG jsou například Jekyll, Hugo, Gatsby a Hexo.
* také v případě `giw2me` jsou bezpečnější pro uživatele, neboť neobsahují ani skritpy, ani cookies
* zatím jsem používal SSG `Pelican` a `Nikola` (a vyzkoušel pár dalších), nebylo to špatné, ale aspoň vím, kde mě bota tlačí a co naopak nepotřebuju (a s autorama se rozcházím v zájmech a pohledu do budoucnosti - oni tlačí moderní blogy, mě asi spíš sedí webové stránky)
* taky jsem si kdysi napsal a léta používal generátor stránek, založený na `make` a `M4`, ale ten generuje `php`
* taky jsem používal `Wordpress` (a pár dalších),
* ale furt to někdo hackuje, tak to sám provozovat nechci
* data někde :strike:`v čoudu` v "cloudu", kde je nemám pod kontrolou a nedají se snadno zálohovat (zvlášť když u SSG je naopak mám doma v gitovém repozitáři a všude dál, kam zálohuju)
* zacházení s obrázky tam bylo bez výjimky úděsné
* `RST` je `reStructuredText` (značkovací (markup) systém jako HTML, nebo Markdown)
* `site` je anglický název webových stránek tvořících jednu skupinu (Nyx, okoun, seznam, ..., cobra-mk3, micro-corner, ...) já to slovo používám i v češtině a skloňuju ho převážně podle vzoru `sajta` (s vyjímkou v prvním pádu, kde se kloním k `site`)
* podobných úchylek mám spoustu, například k všeobecnému pohošení odsazuju tabulátorama (které na to byly vymyšleny) a ne nahodilým počtem mezer (který se stejně zobrazuje všude jinak) - smiřte se
* `giw2me` má umožňovat následující věci:
* generování `html` stránek z `RST` (porovnejte HTML verzi této stránky s RST verzí a bude jasné, proč)
* snadné relativní adresování kdekoli
* výhody: odkazy fungují nejen na webu, ale i po stažení na lokálním disku čtenáře (pokud stáhnul celou situ), i před před publikací na lokálu u mě (pro debugování a odchytávání chyb)
* čili například pro pokec o Kritě místo ``_ použiju `../Krita/22-12-11-instalace-zacatky.html` nebo `.\root/HowTo/Krita/22-12-11-instalace-zacatky.html`
* praktická realizace je, že v každém zdrojovám adresáři mám symlink pojmenovaný `.\root` vedoucí do kořene sity (a pak se snadno doplňují odkazy typu `.\root/logos/favicon.ico`, protože to je platná cesta)
* při vytváření stránek se včechny výskyty řetězce `.\root` nahradí relativní cestou do kořene a ten symlink se nekopíruje (jo, to mi už pohodově chodí)
* `rst` soubory a obrázky a příklady ve stejném adresáři, pro snadné odkazování (a taky dohledávání offline), odkazy pak jsou jen typu ./obr1.png pro lokální a .\root/logos/favicon.ico pro globální
* vizuál podobný tomuto tématu (pomocí `Jinja2` templatů) (tenhle vizuál jsem si napsal sám pro SSG `Pelican`)
* akorát mít v navigaci 3 řádky: `tagy`, `breadcumbs`, `sourozenci` - vše s vysvícenýma aktuálníma položkama (a samozřejmě relativníma/.\root linkama, ale to není třeba furt zmiňovat, tak s tím přestanu)
* `sourozenci` jsou soubory a adresáře ve stejném adresáři. Adresáře budou jako první, s lomítkem na konci, pak budou soubory, ale jen ty generované z RST (nikoli obrázky a tak)
* `breadcumbs` je v podstatě cesta k tomuto adresáři, rozložená an jednotlivé prvky a slouží jako navigace, kde jsem a zároveň způsob, jak se dostat do rodičovských adresářů
* `tagy` jsou nálepky k jednotlivým článkům, které je zařazují do různých tématických oblastí. (Koukněte na RST této stránky, je tam nahoře řádek `:tags:` HowTo,giw2me`)(Koukněte na `tagy` vlevo v navigační liště - vedou na ``_) (jakožto autogenerovvané to nemá RST zdroják)
* `HowTo` dávám k různým návodům (Koukněte nad článkem vpravo, ``)]
* `giw2me` dávám k věcem okolo zmíněného (často v kombinaci s `css`, `prog`, `python`, `Makefile` a podobně). Pravda, na této sitě takových moc není, ale je veřejná. O `giw2me` jsem zatím psal hlavně na soukromých stránkách.
* takovýchto nálepek (tagů) jde nalepit na stránku libovolný počet a typicky souvisí pouze s obsahem stránky, nikoli jejím umístěním v adresářích
* po nějaké době používání sity se počet používaných tagů většinou ustálí a nové přibývají málokdy
* některé populární stránky používají něco jako mrak tagů, některé je mají orgganizovány jinak
* tagy slouží k tomu, že čtu nějaký článek, líbí se mi, chci vědět víc, kliknu na nějaký příhodný tag, kterým je otagován a octnu se na stránce, kde je seznam všech článků s daným tagem, takže snadno můžu sledovat jednu myšlenku přez rozpětí mnoha let a oborů
* Podobně jako `tagy` fungují i autoři (kterých taky článek může mít i víc, jednoho, nebo žádného) (Koukněte na RST této stránky, je tam nahoře řádek `:authors: Gilhad`)
* navigaci podle `tagů` a `autorů`
* tady ještě zvážím, zda mít jak :tag: tak i :tags:, nebo jen jedno z toho všude, nebo i obojí naráz - asi zvítězí varianta :tags: všude, i eventuálně prázdné či chybějící
* generování pomocí `make`, aby se negenerovaly pořád všechny stránky dokola a aby upload nebyl zbytečně velký
* upload pomocí rsync, aby byl snadný, rychlý a tahal jen to, co je potřeba
* odhadovaná velikost: stovky stránek, desítky tagů, tagů na stránce tak 2-5, počet autorů tak 3-10,
* většina článků s omezenou globální sadou ikonek/smajlíků, seriály s vlastní ikonkou, většina článků bez obrázků (možná jen do doby, kdy se uvolní obrázková AI zdarma), některé články s pár malými obrázky ("lineart" schémata a tak), pár s větší "galérií" ať už malých ilustrací, nebo obřích detailních fotek (mých oblíbených 6.000x4.000 bodů)
* hostování na vlastním serveru
* galérie jsem zatím nijak úspěšně nepoužil, takže nebudou (zatím?) implementovány - pokud tam ty fotky nebudou rozestrkané mezi řádky, tak si snadno vygeneruju tabulku a vrazím ji tam třeba jako raw (zatím tak 2 přípdy na 20 let?)
Co už mám
-------------------------------------------------------------------------------
* Projekt založený na `giw2me` (ale má zatím dost zborcených linek např. na tagy a autory a každou chvíli nefunguje jinak, protože něco zkouším, takže zatím veřejnosti nepřístupný)
* Základní generování stránek funguje `rst` se na `html` přeloží syntakticky správně
* `sourozenci` ok (možná vyhodit .hml)
* `breadcumbs` ok
* `tagy` - generují se aktuální, ale ostatní nejsou vůbec a linky nikam nevedou
* `.\root` úspěšně funguje
* site_config.conf se čte a aplikuje
* a proměnné můžou obsahovat i `rst` markup a odkazy na obrázky
* a v hodnotách se "\n" převede na nové řádky
* `Makefile` zvládá "vygenerovat" vše, ale až na několikátý pokus
* bin/compile2.py převádí RST na HTML a zapisuje něco do správných tags/\*.tag
* upload funguje
* stránky jsou (až na tagy a autory) funkční a použitelné
Co nefunguje (ale opravím/dopíšu si sám)
-------------------------------------------------------------------------------
* `css` je chaotický splácanec z více než 3 různých zdrojů a stejně nepokrývá všechno (teda, hlavně různé "code python", "code text" a tak)
* `tagy` - generují se aktuální, ale ostatní nejsou vůbec a linky nikam nevedou
* `authors` se generuje, ale nikam nevede
* `Makefile` zvládá "vygenerovat" vše, ale až na **několikátý** pokus
* navíc teda to **vše** je se značnou rezervou
* bin/compile2.py převádí RST na HTML a zapisuje **něco** do správných tags/\*.tag
* navíc negeneruje **authors**
* programy pro zpracování tagů zatím nejsou ("some magic")
* chybí automatické vytváření `.\root` a indexů
Problém kde potřebuju pomoc
-------------------------------------------------------------------------------
* `Makefile` a obecně možná celá struktura generování tagů a autorů
* moje představa je, že (v zaběhnutém stavu):
* `navigation.nav` obsahuje "předchřoustaný kód/data" pro obecnou navigační řádku `tagy`
* z RST a `navigation.nav` se udělá HTML.
* Přitom se z RST vyextrahuje seznam `tagů` a `autorů` a zkontroluje se, že v každém (pomocném) souboru `.tag` (v pomocném adresáři `build/.tags` nebo tak nějak) je také uloženo jméno výsledného HTML (aby na něj šlo později odkázat)
* tohle bych ještě uměl
* obdobně pro autory
* ono to bude ještě chtít nějáký závislostník typu `some/path/dir/.dep.d`, kam se každý RST zaregistruje, pokud tam není a který při změně vybudí celý adresář k vybuildování `sourozenců`
* teda, RST se tam nemusí registrovat, stačí, když ho to najde přez klasické závislosti, RST existuje od začátku běhu
* akorát, že by ho to mělo mít jen jako existenční závislost a netestovat čas - no, promyslím to ...
* a pravidlo pro něj je jednoduše tam vypsat obsah adresáře
* a když jsme v tom, tak projít i obsah nadadresářů, zda je tam tento adresář a zda jsou všude `indexy.rst` (a když tak je doplnit)
* a když jsme v tom, tak to bych tam mohl i zkontrolovat a případně nanutit ty `.\root` v rámci profylaxe
* až se projdou všechna RST, která potřebujou pořešit se pořeší, zda nejsou nějaké nové tagy `build/.tags/.tag` (a `indexy.rst` )
* a tady je ten háček, že to musí být až pak, protože právě během toho zpracovávání RST ty tagy můžou navznikat (protože jsem připsal třeba něco o koťátkách a přihodil nový tag `kotatka`)
* v běžném provozu to většinou nenastane, stejně jako se nepřifaří nový, dosud neznámý autor
* v běžném provozu jen opakovaně edituju a uplouduju články (a občas přidám nový (ale se starým autorem a tagy) a to pak musím rebuildovat celý adresář kvůli `sourozencům`)
* a pokud naopak nějaký `tag` vyhyne, tak se neděje nic strašného. Prostě tam bude chvíli strašit bez článků, dokud jednou za uherský rok nedám `make clean` a pak už se pojede bez něj (čti: z toho se nestřílí)
* :strike:`ale vlastně mě tak napadá`, že pokud by `navigation.nav` záviselo nejen na `build/.tags/\*.tag`, ale zároveň se do nějakého `navigation.nav.d` vygeneroval seznam tagů, z kterého se to budovalo, jako závislost, tak pokud by `.tag` zmizel, tak by se dalo udělat nějaké pravidlo na vytváření tagů, které by naopak opravovalo věci po zrušeném (a tedy požadovaném tagu)
* to by nešlo, právě proto, že při zpracování RST se blbě zjičťuje, že ztratilo tag
* to by šlo, kdyby se navíc po zpracování RST někam dal pomocný soubor, obsahující seznam tagů v něm, ale při zpracování by se naopak tento seznam načetl první a zkonfrontoval se zkutečností
* jenže to stejně neřeší smazání RST
* jenže já vlastně RST nikdy nemažu, už kvůli odkazům
* ale asi to stejně za tu práci nestojí. Zastydlý tag bez stránek není problém.
* ale lze příležitostně detekovat a nabonzovat (jen v druhém průchodu)
* Takže pokud už máme první průchod, je nutné se znovu podívat na soubory a znovu je načíst, teď už máme všechno, co potřebujeme, jen to možná není aktuální
* z tagů se vygeneruje navigation.nav a rst stránky pro tagy, které je ještě nemají (autoři totéž)
* do stránek tagů se vloží/přepíše (updatuje) seznam stránek z těch tagů
* ono by vlastně šlo už v tom prvním průchodu `touch`-nout ty nové stránky s nějakým "pravěkým" datumem a nechat naplnit ze závislostí až v posledním průchodu a tak si tento průchod úplně ušetřit.
* Ono by bylo ale úplně nejjednodušší to teď restartovat ještě jednou, protože nám (možná) navznikaly nové rst stránky pro tagy a/nebo autory (pokud to není rozbité, tak nové tagy a autoři nemají jak vzniknout)
* projdou se rst soubory, co nemají aktuální html, nebo se jim změnila navigation.nav a zpracují se (pokud to není rozbité, tak nové tagy a autoři nemají jak vzniknout)
* ty input/.tags/jméno.rst se skutečně vytváří :strike:`a automaticky modifikují`, aby pak šly i ručně editovat a popsat, co ten tag podrobně znamená. Odkazy na soubory se nevkládají přímo, ale generují z /build/.tags/jméno.tag až při generování html
Co na čem závisí
-------------------------------------------------------------------------------
.. csv-table:: Co na čem závisí
:header: soubor,závisí na,Poznámka
:delim: #
:widths: 40, 40, 200
input/some/path/jméno.rst # --- # Klasické zdrojáky
input/some/path/.\root # input/some/path/ # při spuštění Makefile se vygenerují chybějící symlinky
input/some/path/index.rst # input/some/path/ # při spuštění Makefile se vygenerují chybějící s tagem `index`, nemažou se
input/.tags/jméno.rst # build/.tags/jméno.tag # nemaže se, když neexistuje, vygeneruje se defaultní :strike:`sekce "odkazy" se nahradí novou hodnotou`
input/.authors/jméno.rst # build/.authors/jméno.author # nemaže se, když neexistuje, vygeneruje se defaultní :strike:`sekce "odkazy" se nahradí novou hodnotou`
# #
build/.tags/jméno.tag # **obsahu všech RST** # updatuje bin/compile2.py při zpracování každého RST
build/.authors/jméno.author # **obsahu všech RST** # updatuje bin/compile2.py při zpracování každého RST
# #
build/navigation.nav # build/.tags/\*.tag # záleží jen na jménech souborů, ne na obsahu - seznam tagů (pro navigaci přez tagy)
build/some/path/.dep.d # input/some/path/\*.rst # záleží jen na jménech souborů, ne na obsahu - seznam `sourozenců` v daném adresáři (pro místní navigaci)
# #
output/some/path/jméno.html # input/some/path/jméno.rst, build/navigation.nav, build/some/path/.dep.d # + na všech technických souborech jako Makefile a templaty.
TL,DR,
-------------------------------------------------------------------------------
.. |styles3| raw:: html
Tato stránka je [OBSOLETE] - přešel jsem na novou verzi systému, kde jsou některé věci zcela jinak
|styles3|
* Hlavní problém je, že stránky ve zdrojácích obsahují seznam autorů a tagů, který nejde vyvěštit ze jména souboru a příslušné soubory se objeví až při zpracování pravidel v Makefile, nikoli už při jejich čtení (a plnění proměnných)
* Takže když už ty soubory existují, tak o tom už `make` neví a potřeboval by to znovu vyhodnotit, nebo prostě celý spustit znovu
* problém je se soubory co závisí na **obsahu všech RST** a pak tím, co teda závisí na nich (a tak trochu i s tím, co z nich vzniká - input/.tags/jméno.rst input/.authors/jméno.rst)
* Závislosti `<#co-na-cem-zavisi>`_
* Jak jsem k nim došel `<#problem-kde-potrebuju-pomoc>`_
* o čem to celé vlastně je? `<#o-co-jde-co-chci-analyza>`_
konec hlášení
Další úvahy po odeslání na Nyx
-------------------------------------------------------------------------------
Možná bych mohl na začátku `Makefile` prostě touchnout chybějící tagy a obsah řešit později?
|chatGPT >| navrhuje
.. code:: bash
find input -type f -name "*.rst" -exec sh -c \\
'echo "$1" | grep -m1 "^:tags:" | sed "s/^:tags:\s*//; s/\s*,\s*/,/g" | tr "," "\n" | \\
xargs -I{} sh -c '\''[ ! -e "build/.tags/{}.tag" ] && touch "build/.tags/{}.tag"'\'' sh {}' _ {} \;
moc se mi to nelíbí, IMHO tam má blbě apostrofy a kdoví co dalšího, ale zkusím něco jako
.. code::
mkdir -p build/.tags
find input -type f -name "*.rst" -exec grep -h "^:tags:" {} \; | sed "s/^:tags:\s*//; s/\s*,\s*/,/g" | tr "," "\n" | sort -u | sed "s@^.*@[ ! -e 'build/.tags/\0.tag' ] \&\& touch 'build/.tags/\0.tag'@" |sh
nebo dokonce
.. code::
mkdir -p build/.tags
mkdir -p input/.tags
mkdir -p build/.authors
mkdir -p input/.authors
find input -type f -name "*.rst" -exec grep -h "^:tags:" {} \; | sed "s/^:tags:\s*//; s/\s*,\s*/,/g" | tr "," "\n" | sort -u | sed "s@^.*@( [ ! -e 'build/.tags/\0.tag' ] \&\& touch 'build/.tags/\0.tag' ; [ ! -e 'input/.tags/\0.rst' ] \&\& sed < .theme/defaults/tag.rst >'input/.tags/\0.rst' 's/%TAG_NAME%/\0/g')@" |sh
find input -type f -name "*.rst" -exec grep -h "^:authors:" {} \; | sed "s/^:authors:\s*//; s/\s*,\s*/,/g" | tr "," "\n" | sort -u | sed "s@^.*@( [ ! -e 'build/.authors/\0.author' ] \&\& touch 'build/.authors/\0.author' ; [ ! -e 'input/.authors/\0.rst' ] \&\& sed < .theme/defaults/author.rst >'input/.authors/\0.rst' 's/%TAG_NAME%/\0/g')@" |sh
a uvidím ...
.. |styles4| raw:: html
Tato stránka je [OBSOLETE] - přešel jsem na novou verzi systému, kde jsou některé věci zcela jinak
|styles4|