Na nabídku

Nested tree menus hate


Nemám rád divný struktury. Tohle mezi ně suveréně patří. O co jde? Návrh menu, kde je rodič určen pomocí váh levá-pravá. Ne, že "tenhle prvek je rodič". Má to fixovat problém odmazaného rodiče (to je ale problém konzistence dat), ale pro řazení to dělá víc škody než užitku. Jednoduché řazení by ještě asi šlo, jakmile je ale potřeba cokoliv složitějšího, tak tohle přestává být příčetně použitelné.

Stávající situace: Mám stránky, kde je backend shodný pro několik domén (pobočky nějaké firmy). Je požadavek, aby jistá doména mohla řídit obsah i ostatním. Včetně menu. Ok...

Někdo ale měl blbý nápad/automat a do menu nacpal Nested tree. No a teď je potřeba rozlišit, kdo to tam dodal a podle toho upravit řazení. Vzhlem k nemožnosti určit, že prvky jsou pro jeden nebo druhý obsah, je potřeba řadit každý uzel extra. Protože je potřeba nad každým uzlem vyhodnotit, jestli dotčený obsah je od jedné domény nebo druhé.

Jakmile je "seřazeno", tak je potřeba od základu vyplnit onu nested strukturu. A to není triviální úloha. Jen hloupý přesun ve vyšší úrovni znamená hrozivé šachy s váhami v úrovních nižších. Pokud někdo tvrdí, že to lze udělat zároveň s přesunem, tak mu nabije tlamu první přehození, kde i s dost velkou opatrností dostane v určitou chvíli aspoň dva stromy v jednom rozsahu začínající na stejné úrovni. Tedy že data tvrdí, že dva stromy mají stejného parenta (na dotčené úrovni fakt nemají, výš budou).

U verze s rodičem (třeba kw_menu) se dá docela jednoduše nastavit omezení (constraint), že daný prvek nelze smazat, pokud na něm něco visí (on delete restrict), nebo že se má hodit na globální (on delete null). Řazení je opět o rozdělení, seskládání a zpětném uložení. Potomky v nižších úrovních taková změna nezajímá. Na rozdíl od Nested, kde jim hrabe do hodnot. Naprosto v rozporu s principem KISS.

Navíc v kw_menu je vidět další hezká vlastnost klasického provedení - a to že se tam dá definovat, jak velká je možná díra mezi položkami a později v prezenční části jak ji využít. Já na ní mám udělané ony oddělovače. A taky lze říct, že položky v pořadí nad něčím se nebudou ukazovat. Taky bezva. S nested to druhé chce odpočítávání přímo od uživatele a to první je řešitelné akorát přes nastavení přímo na položce (položku má zajímat pouze, jestli se má zobrazit sama, ne že se do menu nevejde). To už hezké není.

Změna nad kw_menu oproti tomu projetku je v tom, že v menu používám skutečné cesty. Takže přidání/odmaz je věcí jiné části systému a menu si akorát zaktualizuje data. Přesun je pak odmaz stávající a přidání jinam. Blbuvzdorné. Naopak v onom projektu je to na jedné hromadě obsahu a zbytek se řeší vztahy definovanými mimo.

Další zasažený modul je kw_pedigree. Tedy rodokmeny. Tam je opravdu nutné mít možnost zadat několik parentů. Protože to máme biologické, několik adoptivních nebo třeba zastupujících. To celé v několika kusech. Tam si opravdu nested nedokážu představit. Kw_pedigree v základní iteraci pracuje pouze s aktuálními, tedy jen biologickými, avšak rozšířit je by neměl být až takový problém. Verzi s Nested si ani nejsem schopen představit, neboť parentů je až několik.

Uvádí se, že Nested je fajn pro (My)SQL a jiné databáze. Nemyslím si. Za mě je daleko snazší vytáhnout správně nastavený klasický systém s parenty a pak ho do toho stromu kopnout pomocí jednoduché transformace přes indexy, než blbnout s nested systémem, kde vás zabije právě řazení. Navíc cvok, co má víc jak 50 položek v menu v několika úrovních, nebude patřit mezi populární. A ten trade-off ve spáleném času za tohle fakt nestojí.

  • Link na hezké vysvětlení
Petr Plšek, 182 00 Praha, me@kalanys.com