Jak na opakující se vykreslování entit (parametrizovatelné)?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
ales.kafka
Člen | 34
+
0
-

Zadání problému je následující: Máte entitu reprezentující např. článek a chcete ji vykreslit na různých místech vaší prezentace. Nikoli vykreslit celý článek, to se většinou děje jen na jednom místě, ale vykreslit jeho náhled v následujících situacích:

  1. Hlavní stránka – kdy je ve vykreslení zvolen širokoúhlý obrázek, titulek h2 v elementu
  2. Hlavní stránka – úvodní text je třeba omezit na 200 znaků, h3
  3. Hlavní stránka – vykresluje se i kategorie a omezení textu je 260 znaků, h3
  4. Na konci článku – potřeba vykreslit předchozí a následující článek, h3
  5. Článek má kategorii a u každé kategorie lze procházet historii článků, h3

Jedná se o prakticky totožné kousky kódu, kdy se liší jen v některých podmínkách. Není potřeba prakticky nic z venku, jen základní parametry + vykreslovaná entita, přes kterou se lze dostat ke všem hodnotám a závislostem. Vizualizace je upravována zejména na úrovni CSS.

Jak takovou situaci v šablonách řešíte?

Šaman
Člen | 2666
+
0
-

Entita je pojem z ER diagramu a návrhu aplikace. Není vykreslitelná, v praxi často jen objektově reprezentuje řádek tabulky.
To, co potřebuješ ty jsou komponenty. Té komponentě můžeš předat entitu, nebo celý repositáž (nebo databázi) a ona si je už obslouží sama. Komponenty mohou mít více různých pohledů (reprezentovaných několika render metodami a různými šablonami), ale stále pracují se stejnými daty. Na to, co zamýšlíš je to myslím vhodná volba.

ales.kafka
Člen | 34
+
0
-

Tohle všechno vím. Nicméně komponenty mi nikdy moc k srdci nepřirostly, hlavně ne na takové triviální vykreslování, kdy není potřeba obsluhovat žádné signály, atd. To předávání samotných objektů nebo celých repozitářů by bylo sakra složité, navíc kdo má vymýšlet pojmenovávání těch vytvářejících funkcí. Další problém je samotné předávání zmiňovaných parametrů – momentálně to i sám kóduju, ale mít na to kódera tak by třeba změna omezení délky úvodního textu musela být nastavena v Presenteru.

Přemýšlím, jak bych si život co nejvíc usnadnil a zároveň kód zůstal přehledný a nebyly to žádné prasárny. Zatím je to jen ve fázi nápadu a je třeba to ještě vychytat. Nicméně napadlo mě vyrobit si vlastní makro:

{render $article#article.preview, title=>h3, perex=>250}

Implementace by byla poměrně jednoduchá, využil bych existující makro includeblock → jen pushout parametry mezi exportované proměnné a vymyslet, jak obecně k article.preview najít odpovídající šablonu (nabízí se šablony registrovat, nutnost poskytnout callback, anebo by $article musela implementovat rozhraní IRenderable a makro by pracovalo s ním).

Proto se ptám, zda existuje nějaké jednoduché řešení, jiné než komponenty. Případně i komponenta, ale jestli jde vhodně ohnout, aby ta definice nemusela být na 3–4 místech.

JakubJarabica
Gold Partner | 184
+
0
-

Tiež som si nikdy veľmi nezvykol na komponenty(nie typu formulár atď) a volím ich, len keď potrebujem mať aj inú logiku ako prezentačnú na viac miestach(rôzne star ratings pre viac typov entít atď).

Tvoj problém riešim spokojne pomocou samostatných šablón – vo FrontModule/templates mám jednotlivé šablóny: https://www.dropbox.com/…00.30.03.png.
V nich môžem využívať makro {default} ak potrebujem inicializovať nejakú novú premennú na implicitnú hodnotu atď. Viacmenej v celej appke mám v rôznych kontextoch identické datasources(je to nad dibi) a jediné, čo mi vadí je nutnosť z rôznych kontextov(FrontModule/MyAccountModule/Estates) vždy includovať správnu cestu. To by šlo riešiť napr. nejakou konštantou GLOBAL_TEMPLATES_DIR(prípadne ak ide overridnuť makro include tak, aby kontrolovalo názov súboru v danom priečinku pre ešte kratší zápis v šablónach – ešte nebol čas to preskúmať), ale s týmto riešením som nebol spokojný, tak som to nechal otvorené.

Samozrejme treba napr. myslieť na absolútne odkazovanie v rámci modulov/presenterov atď, ale je to mega DRY a nemusím si na to písať factories – ktoré by zrejme aj tak boli v BasePresenteri kvôli globálnosti a bol by to god object alebo by som sa utovárničkoval s DI – takto len z modelu jedným riadkom v renderi vytiahnem čo treba a v šablóne to je tiež pragmatické.

Funguje mi to veľmi dobre na (stredne) veľkých projektoch typu realitný server atď.