Přístup z componenty do layoutu

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

Zdravím,

vytvořil jsem componentu, která je potomkem Nette\Application\UI\Control a pak jsem si v @layout definoval blocky. Poté componentu vkládám přes {control component} a potřeboval bych, aby tato komponenta mohla přistoupit k blockům definovaným v @layout a mohl jsem například přepsat obsah nebo ho rozšířit pomocí {include parent}, dokáži se dostat z componenty do presenteru, která componentu vytváří, ale dále nevím, jak se dostat @layoutu nebo nějak zpřístupnit blocky z @layoutu mé componentě. Je toto nějak možné?

Děkuji moc za jakékoliv info.

Editoval pavel.vondrasek (15. 10. 2014 17:23)

Šaman
Člen | 2668
+
0
-

Z presenteru můžeš pracovat s bloky se snippety layoutu.
Edit: Pardon, myslel jsem, že se ptáš na něco jiného.

Editoval Šaman (15. 10. 2014 17:35)

akadlec
Člen | 1326
+
0
-

pokud vím tak nelze, taky jsem to řešil a zakládal zde téma či odpovídal jinde ale není cesty…

Editoval akadlec (15. 10. 2014 17:48)

pavel.vondrasek
Člen | 5
+
0
-

Jinak jen pro informaci, proč to potřebuji, snažím se řešit šablonu pro administraci, kterou chci použít na více webech a pouze si jí nainstalovat composerem a poté vložit componentu do templatu, kde jsem chtěl, aby se o vše již postarala sama a také když bych ji aktualizoval, tak si jí všude zaktualizuji přes composer update, ale teď řeším jak třeba spravovat javascripty nebo css. Zatím mě napadlo, že to mohu zkusit ještě tak, že pro JS a CSS vytvořím přímo nějaké speciální komponentu, která se bude starat o jejich správu napříč projektem, takže ta moje grafická componenta admin layoutu by si své css přidala přes componentu pro správu stylů, to je asi o dost čistější řešení.

Celkově jsem s componentami teprve začal, takže zkouším, co se s nimi dá vše provádět, takže píšu i z důvodu, zda někdo něco podobného neřešil, abych se mohl inspirovat lepšími a promyšlenějšími řešeními.

LeonardoCA
Člen | 296
+
0
-

To co chces samozrejme lze udelat.

1. Musis si polozit spravnou otazku.

Otazka neni: Jak se dostat z komponenty do @layoutu?

Otazka je: Jak zajistit, aby v pripade, ze si pridam do projektu nejakou komponentu, se mi automaticky pridal, do layoutu potrebny js a css?

2. Jak uz jsi zjistil, ve chvili kdy komponentu renderujes, tak uz je na nejake pridavani neceho do hlavicky pozde. Proc pozde?

  1. protoze, pokud vyuzivas spravne tovarnicek, tak uz je hlavicka ve chvili kdy se komponenta dostane ke slovu davno vygenerovana
  2. nebo pokud vyuzivas ajaxu a dynamicky se ti meni nejaka cast stranky a v ni se ti vygeneruje komponenta, ktera tam pri prvotnim zobrazeni stranky vubec nebyla, tak, takove komponente taky nebudes ajaxem pridavat js a css
  3. A ani to nema smysl pridavat js a css jen v pripade, ze se komponenta zobrazi. Cilem by melo byt, mit potrebne js a css soubory includovane vzdy, vzhledem k tomu, aby melo smysl je slucovat a komprimovat treba do nejakeho styles.min.css, scripts.min.js. Samozrejme muzes mit ruzne potreby na frontendu a backendu, a tak by se js a css tve komponenty pridaly jen tam, kde je to treba, tedy v tvem pripade jen do administrace.

3. Otazka je, zda-li na to jsou js a css tve komponenty pripravene. Tj. jestli v pripade, ze je budes mit pridane na jekokoli strance, tak nezpusobi konflikt s js a css jakekoli jine komponenty.

4. Pokud zajistis, aby byl splnen bod 3, tak nejcistsi a nejpeknejsi reseni je neresit pridani neceho do hlavicky az za behu aplikace, ale uz pri buildu a vyuzit treba bower pro nedefinovani js a css zavislosti a grunt na to aby projekt poskladal dohromady.

(Priklad jak takovou komponentu vytvorit a jak zajistit, aby se pro ni automaticky generoval nejen balicek pro composer, ale i balicek pro bower, se chystam popsat nekdy v nejblizsich dnech.)

Editoval LeonardoCA (15. 10. 2014 20:25)

pavel.vondrasek
Člen | 5
+
0
-

Ano, taková je moje představa do budoucna, pro zajímavost, našel jsem, že můžeš napsat balíček do composeru s vlastním instalátorem, jen jsem v aktuální situaci chtěl nějaké jednodušší řešení, protože jsem to chtěl pořešit rychle.

Našel jsem k tomu toto:
http://robloach.github.io/…t-installer/
https://getcomposer.org/…nstallers.md

Je tam zajímavé, že si mohu nastavit, co se stane například při instalaci, odinstalaci a updatu pluginu. Takže moje myšlenka do budoucna byla, že bych prošel vždy soubory té componenty (pluginu) a podle toho je roztřídil podle typu souboru a také třeba provedl úpravy na databázi, dle Doctrine Entit by se provedla aktualizace databáze.

Co se týče frontendu, tak ten sestavuji gulpem, protože tam mám LESS a provádím různé minifikace a slučování, ale bower mi zatím moc nesedl.

Každopádně díky moc za diskuzi, až něco vyprodukuji, tak to hodím na Github, myslím, že toto určitě řešil i někdo další :)

Editoval pavel.vondrasek (15. 10. 2014 20:33)

LeonardoCA
Člen | 296
+
0
-

Podle mne deleko lepsi nez nejaky components installer je pouzit grunt nebo gulp (ten jsem nezkousel, ale je to jen jina verze task manageru). Require.js, ktery je vyuzit tim instalerem zajistuje jen rychle nacitani stranky, s tim ze ridi jakym zpusobem se javascript nacita.

Ale zadny z tech nastroju neresi zavislosti. Na potrebu spravy zavislosti drive nebo pozdeji narazis, pokud budes pouzivat vice a nejen vlastnich komponent a budes je chtit jednoduse upgradovat, podobne jako upgradujes php balicky pres composer update. A to je ukol, ktery resi bower …

Editoval LeonardoCA (15. 10. 2014 21:06)

pavel.vondrasek
Člen | 5
+
0
-

Závislosti jsem chtěl řešit composerem, zkoušel jsem, že třeba administrace by měla závislost login nebo jsem zkoušel componentu článek (respektive mám to zatím jako dvě componenty v balíčku, výpis článků a editace) a ta je závislá na administraci a loginu.

Každopádně nechci použít components installer, jen jsem to bral jako příklad balíčku do composeru s vlastním instalátorem (pro mě byla novinka, že toto v composeru lze, balíčky už jsem dělat zkouel, ale nevěděl jsem, že to lze až tak dobře ohnout), samozřejmě to není úplně něco co chci, ale bral jsem to jako inspiraci.

LeonardoCA
Člen | 296
+
0
-

ja myslel js a css zavislosti, ty ani autori composeru resit composerem nedoporucuji

Jeste me napadlo takove prirovnani.

Composer tridi jablka, hrusky a jine ovoce podle kvality, bower tridi zampiony, pravaky a bedly podle kvality a Grunt nebo Gulp posle suroviny nejvyssi jakosti do exkluzivnich hotelu, 1. jakosti do tesca a odpad prasatum.

Composer se v houbach nevyzna, vlastne ani nevi, co to ho houby jsou a ucit ho to je ztrata casu, kdyz takovy bower uz pozna 20.000 druhu hub.

Editoval LeonardoCA (15. 10. 2014 21:42)

Michal Vyšinský
Člen | 608
+
0
-

Ahoj, problém s přidáváním něčeho do hlavičky z komponenty mám řešený v https://github.com/…cms/packages – a umí toho víc :) Nicméně nyní přemýšlím o zrušení balíčku, protože jsem viděl přednášku o Gulp devstacku (poslední sobota)

akadlec
Člen | 1326
+
0
-

@LeonardoCA : s tvým postem bych si dovolil nesouhlasit.

Jak uz jsi zjistil, ve chvili kdy komponentu renderujes, tak uz je na nejake pridavani neceho do hlavicky pozde.

Tady bych zase já tvrdil že to pozdě není. Mě osobně by se líbilo kdybych v okamžiku renderování měl ještě možnost zasáhnout do hlavního layoutu, či jiné komponenty. A důvod je prostý, renderuju komponentu co řeší nějaký výpis a vyžaduje své styly, js atd. tak si prostě ona komponenta, resp. část v šabloně šáne na layout a řekne mu „hele přidej mě tam ještě tyto CSSka“

A proč bych to chtěl řešit až na úrovni šablony? Protože chci mít šablony volné a ne svázané s celým PHP kódem. A kdykoliv se rozhodnu změnit šablonu tak to změním jen v ní a nebudu muset šahat do PHPka. Tady se mě nelíbí ta provázanost komponent/presenteru a šablon. Už jsem tohle řešení viděl i v jiném projektu (na symfony) akorát tam teda nemli komponenty ale celé to řešil controller.

akadlec
Člen | 1326
+
0
-

No zkoul jsem to video o GULPu…vypadá to schopně. Otázka, umí to řešit dynamicky skládané CSS/JS soubory? Resp ono to je jako GRUNT ne? tj. veme si to definované styly z layoutu v těch blocích že?

LeonardoCA
Člen | 296
+
0
-

@akadlec:

Tady bych zase já tvrdil že to pozdě není. Mě osobně by se líbilo

A nejsi sam, kdo nad tim takhle premysli. Ale zkus si precist znovu duvody proc je pozde o par prispevku vyse.

Nebo se zkus zamyslet, proc tak promysleny framework jako Nette, neco takoveho primo nepodporuje?

Mozna to bude jeste jasnejsi, kdyz to zkusim ilustrovat na hypotetickem prikladu:

Predstav si, ze budes chtit mit komponentu, ktera bude online zobrazovat pocet vrabcu na Petrinske rohledne. K tomu budes potrebovat mit na rozhledne nainstalovanych par kamer a nejaky software, ktery rozpozna vrabce od sykorky. A ted, jak to realizujes? Budes mit napsany modul, ktery, az ve chvili zobrazeni komponenty bude zjistovat jestli kamery jsou nainstalovane a v pripade ze ne, tak posle objednavku firme, ktera kamery nainstaluje a nebo email Pepovi, at vybehne nahoru a spocita vrabce?

Samozrejme, muzes to tak udelat. Otazka je, je to to nejpraktictejsi reseni?

Editoval LeonardoCA (16. 10. 2014 14:50)

Vojtěch Dobeš
Gold Partner | 1316
+
+3
-

Podlě mě jde o tradeoffs:

  • Pokud chci z komponenty, která se renderuje úplně na konci stránky, zasáhnout do hlavičky layoutu, musím držet většinu vyrenderování v output bufferu.
  • Pokud bych se tomu chtěl vyhnout, musím se všech komponent dotázat už v presenteru, což znamená, že:
    • V presenteru musím vědět, které komponenty se vyrenderují.
    • Musím všechny komponenty nechat vykonat svůj kód, ačkoliv s šablonovým cachováním bych se tomu někdy třeba vyhnul.
  • Anebo musím toto oželet a nechat rozhodnutí na layoutu, což je přesně to, čemu se chce toto vlákno vyhnout. Osobně se ale k této variantě taky přikláním :). Stejně je lepší v hlavičce natáhnout jeden CSS soubor než X podle toho jaké komponenty se do stránky dostaly. Viz Grunt/Gulp…
akadlec
Člen | 1326
+
0
-

@LeonardoCA ok nevidím problém v případě kdy máš jednoúčelovou appku, vše máš dopředu nalajnované tak si to celé klidně sestavíš na startu. Ale zkus si představit situaci kdy tvoje appka může změnit svuj kabát jen jednoduchou definicí či editací konfigurace. A teď si ještě představ že jedna šablona jede na bootstrapu a další na uikitu a ejhle máš problém. Či případně přes admin přidáš nějaký blok stránky který bude vyžadovat JS ale zase bude závislý na tom jakou šablonu si zvolil.

No každý máme jiný požadavek no, já nechci aby o šabloně, csskách atd věděla samotná aplikace, té to musí být šumák.

Řešení mám zatím tak že všechny šablonové specifické skripty přesunu k dané šabloně, i když se týkají jen nějakého modulu :(

@vojtech.dobes ano to že se natáhne jeden css file a jeden js file je i to co chci já, resp. to co mě teď děla překopaný webloader.

newPOPE
Člen | 648
+
0
-

@pavel.vondrasek: Komponenty nemaju co sahat do @layout-ov preto su to komponenty.

akadlec
Člen | 1326
+
0
-

@newPOPE tak tomu by se taky dalo oponovat ;) opět příkladem budiž asset který je jen pro danou komponentu a pokud se komponenta nepoužije tak je zbytečné aby se ten asset načítal. Další příklad je třeba že komponenta vloží do své šablony nějaký HTML element, ale aby to v celkovém layoutu fungovalo korektně je třeba přidat nějakou classu do body elementu apod. Ale komponentu můžeš vykresli dvěmi šablonami a z nich to vyžaduje jen jedna a kdyby se to použilo natvrdo tak by to zase dělalo bordel apod.

LeonardoCA
Člen | 296
+
0
-

Další příklad je třeba že komponenta vloží do své šablony nějaký HTML element, ale aby to v celkovém layoutu fungovalo korektně je třeba přidat nějakou classu do body elementu apod

  • chyba je, ze neco takoveho potrebujes → mel bys to zkusit udelat tak, at se bez takove podivnosti obejdes (jestli chces, napis priklad kdy potrebujes classu v body, treba to pujde vyresit jinak)
  • pokud uz by k tomu byl nejaky zavazny duvod, tak to muzes vyresit jednoduse tim, ze vyrenderujes nejakou takovou specialitku do iframu (na tomhle principu funguji veskere online sandboxy typu jsfiddle)

příkladem budiž asset který je jen pro danou komponentu a pokud se komponenta nepoužije tak je zbytečné aby se ten asset načítal

  • tezko se bavit o necem nekonkretnim, ale v zasade, u mensi webove aplikace neni duvod mit vic jak 1 js a 1 css, samozrejme u rozsahlych aplikaci jich muze byt vice, nebo muzou byt ruzne pro ruzne sekce webu, ale urcite se nevyplati loadovat js a styly pro kazdou komponentu zvlast

Editoval LeonardoCA (17. 10. 2014 13:14)

newPOPE
Člen | 648
+
0
-

akadlec napsal(a):

@newPOPE tak tomu by se taky dalo oponovat ;) opět příkladem budiž asset který je jen pro danou komponentu a pokud se komponenta nepoužije tak je zbytečné aby se ten asset načítal. Další příklad je třeba že komponenta vloží do své šablony nějaký HTML element, ale aby to v celkovém layoutu fungovalo korektně je třeba přidat nějakou classu do body elementu apod. Ale komponentu můžeš vykresli dvěmi šablonami a z nich to vyžaduje jen jedna a kdyby se to použilo natvrdo tak by to zase dělalo bordel apod.

  • ukaz mi jeden system ktory to takto robi (buildnem CSS, JS a mam vybavene)
  • HTML ktore je zavisle na vonkajsku? ten isty problem ako s komponentou ktora ovplyvnuje vonkajsi svet!

cize taketo zmyslanie mi pride uletene od zakladu.

akadlec
Člen | 1326
+
0
-

jakékoliv CMS co celý obsah dynamicky skládá.

Opět opakuji záleží na pohledu na aplikaci, pokud děláš něco „jednoúčelové“ tak ti to připadá mimo, pokud děláš něco „klikačkou“ customizovatelné tak bys na to narazil.

pavel.vondrasek
Člen | 5
+
0
-

Když už tu máme celkem zajímavou diskuzi, tak přidám další otázku, mrkněte se třeba na pluginy v PrestaShopu, Wordpressu a nebo Drupalu. Neřešme, jak to jsou nebo nejsou kvalitní systémy nebo jak jsou „zprasené“, ale představte si, že byste chtěli podobný systém mít i v CMS pro Nette, chtěli byste, aby si uživatelé mohli instalovat (nejlépe graficky) pluginy a zároveň byste si chtěli zachovat veškeré výhody vývoje v Nette, abyste systém mohl velmi pohodlně rozvíjet a chtěli byste, aby tento systém zůstal kompatibilní s defaultním Nette sandboxem, protože byste chtěli, aby si ho každý mohl nainstalovat bez jakýchkoliv změn a úprav kódu. Pro takovéto pluginy byste potřebovali řešit styly, javascripty, obrázky (například plugin by si s sebou mohl nést i svůj frontend) a další podobné věci, prostě aby se to chovalo podobně jako u těch systémů výše, kdy jen kliknete instalovat a vše až na drobnosti krásně jede. Jak byste postupovali?

akadlec
Člen | 1326
+
0
-

No to je to o čem tu mluvím ;) a na něčem takovém pracuji. Řešil bych to tak že by to vše bylo formou balíčků, v systému pak musí být když tak nějaký webloader kterému předáš assety.

Můj současný stav je ten že mám jeden základní systémový modul a do něj se přidávají další moduly které pak řeší dílčí části. A podle toho o jaký module se jedná tak jej systém registruje.

newPOPE
Člen | 648
+
0
-

Myslim, ze na toto mame patterny ktore Vam pomozu to vyriesit :). Predstav si ze tie komponenty su niekam registrovane a ten dany Register/Builder… (nazvite si to ako chcete) si od nich vyziada co potrebuje (este pred samotnym renderom). Napr. tie Vase assety a vlozi ich tam kde ma kedze on sa stara o skladanie stranky ako takej.

Cize nikto nikam do vonkajsieho sveta nezasahuje len da odpoved na to na co sa ho pytaju.

Editoval newPOPE (17. 10. 2014 17:37)

LeonardoCA
Člen | 296
+
0
-

Tech moznosti jak to resit je vice. V zasade vidim 2 moznosti.

1. Na urovni php

Jak pise o dva prispavky vyse akadlec

Řešil bych to tak že by to vše bylo formou balíčků, v systému pak musí být když tak nějaký webloader kterému předáš assety.

Webloader jsem nikdy nepouzil, takze ho neznam do hloubky, ale podstatne na tom jak funguje, je ze pridani potrebneho js/css do layoutu resi ne ve chvili, kdy se renderuje nejaka komponenta nebo template, ale ve chvili, kdy se sestavuje DI Container https://github.com/…xtension.php. Tak je zajisteno, ze spojovani souboru a cokoli jineho s nimi dela se nedeje pri kazdem generovani stranky, ale jen jednou kdyz se sablony kesuji. To znamena, ze mu balicky pro takovy system by mely mit ve svych CompilerExtension definovane assety, ktere chce predat Webloaderu. Jestli to nejakym zpusobem primo podporuje nevim, ale pokud ne, dala by se takova nadstavba nad webloader napsat.

Webloder funguje a to co dela zrejme dela dobre, staci definovant jak mu maji balicky predat assety. Nevyhoda: neumi spravu zavislosti.

2. Mimo php kod, pokud bych vedel ze neni problem na serveru poustet nodejs, pomoci nejakeho build systemu typu Grunt/Gulp, podobne jako resi "customize and download " napriklad http://getbootstrap.com/customize/ (starsi verze zdrojoveho kodu:https://github.com/…strap-server) nebo http://jqueryui.com/download/ zdrojovy kod: https://github.com/…jqueryui.com

Balicky pro takovy system by krome composer.json mely i bower.json s definici zavislosti a jake assety poskytuji a o zbytek se uz postara build script. (bower.json by mel obsahovat sekci „main“ a existuji reseni jako https://github.com/…runt-wiredep, ktere umi pridat js, css automaticky do layoutu)

Druhe reseni by bylo narocnejsi na prvotni realizaci, ale taky robustnejsi (diky spravy zavislosti pres bower) a flexibilnejsi. (o neco takoveho se pokousim)

Vyhoda: mohu do projektu pridat i ciste frontend zavislosti a aktualizovat je primo z jejich originalniho repository (bower nebo git)


V cem je zasadni rozdil?

1. reseni – Balicek bude obsahovat:

  • composer.json
  • nejake js, css, obrazky

V pripade, ze vice balicku ubsahuje stejny skript nebo stejny skript ve vice verzich, muzu mit problem s tim jak to osetrit. Nebo pokud nektery balicek bude spravne fungovat napriklad jen s nizsi verzi jquery, nedozvim se to po nahrati nebo aktualizaci balicku, ale klidne az nahodou, kdyz si zobrazim nejakou stranku, kde se chyba projevi a vsimnu si toho … O pripadnem problemu se dozvim nahodou, pokud vubec nekdy

2. reseni – Balicek bude obsahovat;

  • composer.json
  • bower.json
  • nejake js, css, obrazky

Balicky maji definovane zavislosti, tj napriklad s jakou verzi jquery funguji, po nahrati nebo aktualizaci balicku po spusteni buildu bower upozorni pokud zjisti nejaky konflikt. O pripadnem problemu se dozvim hned a mohu jej resit

Editoval LeonardoCA (18. 10. 2014 18:33)