ZaxCMS\UI – (nejen) komponenta pro AJAX

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

Zdravím přátelé,

snad každý, kdo viděl přednášku od Honzy Tvrdíka, pochopil, že komponenty v Nette jsou naprosto super věc. Nicméně v základu jsou poněkud chudé, zrovna moc toho neumí (což není nutně nevýhoda, o to jsou univerzálnější) a některé věci se musí řešit pořád dokola, zejména nastavování cesty k šabloně a (používáte-li AJAX) „if is ajax, redraw, else redirect“. Také jim schází podpora pohledů – teď nemyslím pohledy ve smyslu {control someControl:view}, ale spíše v tom smyslu, v jakém je používají presentery, tj. s možností tvořit na ně odkazy.

Tyto nedostatky se snaží napravit má komponenta, kterou jsem před nějakou dobou naprogramoval, a nyní jsem se i dokopal k tomu, abych ji trochu zkulturnil, přidal jsem nějaké testy, odstranil kusy kódu, které sloužily jen pro mou potřebu, a uvolnil ji pod MIT licencí. Najít ji můžete na Githubu.

(Je to první knihovna, kterou uvolňuji pod otevřenou licencí, a rád bych časem vydal i něco dalšího, takže budu moc rád za jakýkoliv feedback – co dělám špatně, co mohu vylepšit, co se vám třeba nelíbí a nechcete mou komponentu kvůli tomu používat apod., abych se případně mohl polepšit. Díky!)

Instalace

Tradičně pomocí Composeru:

{
    "require": {
        "zaxcms/ui": "v1.0.0"
    }
}

(Knihovna vyžaduje min. PHP 5.4, jelikož jsem lenoch a používám zkrácený tvar zápisu polí. A 5.3 už prostě musí umřít.)

Použití

Anglický návod najdete přímo v repozitáři, pokud si s něčím nevíte rady, nebojte se zeptat.

A ať vám dobře slouží!

Editoval Zax (8. 1. 2015 5:19)

akadlec
Člen | 1326
+
0
-

Takže díky téhle ext. můžu udělat komponentu co bude vypisovat třeba nějaké položky ve viewDefault a pak jejich editace/přidání ve viewEdit/viewCreate ? Tedy tak jako bych to dělal v presenteru?

LeonardoCA
Člen | 296
+
+1
-

Komponenta vypada zajimave (nekdy testnu), na prvni pohled jen drobny tip:

  • trosku vic informaci do composer.json – krom jineho napr. muzes pridat do required "php": ">=5.4.0",
Zax
Člen | 370
+
0
-

akadlec napsal(a):

Takže díky téhle ext. můžu udělat komponentu co bude vypisovat třeba nějaké položky ve viewDefault a pak jejich editace/přidání ve viewEdit/viewCreate ? Tedy tak jako bych to dělal v presenteru?

Přesně tak. Vnitřně to není nic jiného než persistentní parametr $view spolu s ošetřením, aby škůdci přes něj nemohli načítat „cizí“ šablony – kontroluje to jak syntax (povolené jen alfanumerické znaky), tak existenci view<View> metody.

Jednu fičuru jsem zapomněl v dokumentaci zmínit (brzy napravím) – pokud šablona neexistuje, hledá se v nadřazené třídě, což ti ušetří práci pokud máš hodně komponent, které mají stejnou šablonu (z praxe např. {control form}) a dědí ze společného předka.

LeonardoCA napsal(a):

Komponenta vypada zajimave (nekdy testnu), na prvni pohled jen drobny tip:

  • trosku vic informaci do composer.json – krom jineho napr. muzes pridat do required "php": ">=5.4.0",

Díky. To bych určitě udělat měl.

akadlec
Člen | 1326
+
0
-

Hmm sakryš, už jsem myslel že mi to vyřeší problém co v komponentách mám, ale asi ne :( mám třeba komponentu pro vykreslení avatara a zároveň jde ten avatar měnit, takže je tam handle na zobrazení formu do modalu. Toto by se tedy dalo rozdělit na ty pohledy ale pokud to dobře chápu tak se ten prostor pro komponentu vždy překreslí při ajaxu konkrétním view ne? Škoda že komponenty nejde více propojit s layoutem :(

Dokáže tohle řešení aspoň pokrýt problém s invalidovaním komponenty která má změněnu render metodu?

{control someComponent:other}

kdy při invalidaci snipettu se použije běžný renderer

enumag
Člen | 2118
+
+1
-

@Zax Nevypadá to špatně, ale rád bych využil pouze některé featury tvé Control. Konkrétně pro hledání šablon mám vlastní mechaniku a zásadně nikdy je neumisťuji relativně ke komponentě. Z tohoto důvodu bych raději kdyby features té Control byly rozdělené na několik trait, stějně jako to dělá Kdyby a Nextras.

Zax
Člen | 370
+
0
-

@enumag Hledání šablon si můžeš upravit poděděním a přetížením metody getTemplatePath($view, $render = ''), nestačí?

@akadlec Hmm teď si nejsem jistý, jestli chápu dotaz… je to v podstatě nadesignovaný pro nejčastější případ kdy máš celou šablonu komponenty obalenou jedním snippetem. Při ajaxu by se měl vykreslit aktuální view podle toho, co je v tom persistentním parametru. Jinak layout (pokud chápu co potřebuješ) v latte by myslím měl normálně fungovat, např.:

@layout.latte

{snippet}
 {include content}
{/snippet}

Default.latte

{layout './@layout.latte'}
{define content}
blabla
{/define}

Editoval Zax (9. 1. 2015 11:02)

enumag
Člen | 2118
+
+1
-

@Zax Ne, nestačí, jsou tam i další věci co nechci nebo je řeším jinak. Traity jsou dneska víceméně standard když píšeš knihovnu rozšiřující Control nebo Presenter.

Editoval enumag (9. 1. 2015 10:56)

Zax
Člen | 370
+
0
-

@enumag Ok, zkusím to nějak promyslet. Fičurky navíc IMO nevadí, je to jen pár (kilo)bajtů kódu navíc, ale pokud ti to nějak leze do cesty, tak to už je důvod pro zlepšení. Díky za feedback!

akadlec
Člen | 1326
+
0
-

@Zax jo control může mít svůj layout ale tím to pro něj končí, je v podstatě samostatná jednotka pokud jsem to pochopil správně.

Já mám třeba ten control pro avatara, takže v defaultní šabloně ho vykreslím a pokud má uživatel tu možnost tak mu tam přidám button na editaci/nahrání nového což je vlastně odkaz na signál. A kliknutím způsobí to že se se do té šablony default ještě vloží form pro to nahrání nového, ale to jde do modalu, takže tohle asi na pohledy nedokážu rozdělit, to by se mě pak překresloval už zobrazený avatar.

No a ten druhý případ co zmiňuju je že pokud máš např. v presenteru jeden control 2× ale pokaždé s jinou template, či jen jen prostě na jedné stránce chceš control vykreslit jinak:

{control someComponent:other}

a provedeš AJAXový požadavek a invaliduješ jen jeden snipet uvnitř toho controlu tak se ten parametr other ignoruje, tak mě napadá zda by to šlo nějak pořešit těmi tvými pohledy?

Zax
Člen | 370
+
0
-

@akadlec Modály jsou dost specifický a každý si je řeší po svým, takže nad tím jsem vůbec nepřemýšlel. Pokud ti jde obecně o to, aby se ti po kliknutí přidalo nějaký HTML do šablony navíc, pak by na to měl v poho stačit layout se snippetem. Ano, sice se překreslí i to, co je v layoutu, ale toho si uživatel ani nevšimne. A nebo holt prostě co šablona, to snippet, s tím, že v Default.latte bude prázdný a v např. Modal.latte bude ve snippetu kód s modálem.

Pokud jde o {control someComponent:other}, tak s tím nepomůžu, to je omezení v Nette a přes moje pohledy to asi obejít nepůjde, resp. nenapadá mě jak.

Editoval Zax (9. 1. 2015 16:18)

Zax
Člen | 370
+
+1
-

Pushnul jsem do masteru rozdělení na traity:

  • TControlAjax
  • TControlForward
  • TControlLifeCycle
  • TControlMergeLinkParams

Význam jednotlivých trait je popsán v dokumentaci.

Custom renderování by nyní mělo jít třeba takto:

class Control extends Nette\Application\UI\Control implements Zax\Application\UI\IHasControlLifeCycle {

	use Zax\Application\UI\TControlLifeCycle;

	public function viewDefault() {}

	public function beforeRender() {}

	public function run($render = '', $renderParams = []) {
		$view = $this->view;
		// my custom rendering logic...
	}

}

nebo takto:

class Control extends Nette\Application\UI\Control {

	use Zax\Application\UI\TControlLifeCycle;

	public function viewDefault() {}

	public function beforeRender() {
		$view = $this->view;
		// my custom rendering logic...
	}

}
enumag
Člen | 2118
+
0
-

Hezké. :-)

To AjaxMacro by bylo myslím lepší registrovat pomocí extension – example.

Zax
Člen | 370
+
0
-

To jsem si taky říkal, ale přišlo mi to trochu jak kladivo na komára. Ale zas je fakt, že se tím uvolní metoda createTemplate… tak jo :-)

EDIT: a je to

Editoval Zax (14. 1. 2015 11:49)

chemix
Nette Core | 1296
+
0
-

@Zax co to predstavit na lednove posobote? Staci 5min jako lighting talk

Zax
Člen | 370
+
0
-

@chemix Jako nabídka dobrá, ale já jsem hodně špatný řečník, nechce se mi to ani zkoušet, sorry :-/

chemix
Nette Core | 1296
+
0
-

@Zax popremyslej o tom, defakto je to jen rici co to je co to umi a treba ukazat jak to funguje … Sup sup 3minuty a mas video a muze se o tom dozvedet vic lidi pokud to je dobre

Zax
Člen | 370
+
0
-

@chemix ok ještě o tom budu přemýšlet. Zrovna jsem v situaci že si hledám práci, čeká mě za několik dní pohovor, takže nervy pracují, ale když mi to klapne, tak to nejdřív zkusím ukázat novým kolegům a uvidím, co mi na to řeknou. Já se trochu bojím jít s kůží jen tak z fleku před publikum, zčásti protože jsem nervák a zčásti protože jsem trochu zaspal dobu a jak teď vše zkouším dohnat, tak si prostě dost nevěřím. Doufám taky, že mi nová práce ukáže, co všechno dělám špatně, abych se mohl polepšit a nebyl zbytečně za trotla :-)

BTW knihovny budou ještě přibývat, nástroj pro routování už je venku, dál plánuji vydat pár rozšíření pro formuláře, něco pro bootstrap, DI atd. (nad svým „bastl-CMS“ jsem strávil hodně času a nechci ho zahodit, radši z něj vyextrahuju vše užitečné), takže když už, tak bych to radši nechal na později (březen?) a vyhradil si klidně půlhodinku.

To zní fér, ne? ;-)

chemix
Nette Core | 1296
+
0
-

@Zax ok ;-) drzim palce