Vlastní makro – přístup k presenteru?

Klobás
Člen | 113
+
0
-

Ahoj,

mám na procvičení jednoduché makro:

  1. a moje otázka je vlastně v komentáři, k presenteru ve Writteru se dostanu přes $_presenter (a získam například nějakou nadefinovanou metodu či proměnnou – to je OK), ale kdybych si chtěl udělat nějakou logiku mimo Writter a pak tam už jen poslat proměnnou – viz komentář.
  2. Jak se prosím dostanu k proměnné z Latte (at už vytvořené Latte nebo přes $this->template->var) = ‚foo‘)
  1. Upřímně psát to v tom Writteru když je složitejší kód, tak to vypadá strašně nepřehledně, jako kdybych to psal do Eval fce. Kdyby to byl delší kód, nedá se to napsat nějak lépe a jinam?
<?php
public function time(Latte\MacroNode $node, Latte\PhpWriter $write)
{
    $param = $node->args;
    //$presenter = $this->global->uiPresenter; NEFUNGUJE ?
    /*
        Jak se tady dostanu k presenteru abych mohl napsat neco jako
        $aaa = $presenter->getTime() a pote ve Writeru pouzit uz jen \$aaa
    */
    return $write->write("echo \$_presenter->getTime();");
}

?>

Čerpal jsem z http://css.chobits.ch/latte-makra/

Editoval Klobás (7. 3. 2018 17:09)

Klobás
Člen | 113
+
0
-

na 2) si odpovím sám stačí jen \$promenna ve writteru, ale opět, dá se na to šáhnout mimo writter? tj to samé jako se ptám na 1)?

David Matějka
Moderator | 6445
+
0
-
  1. to je spatny postup. v makru se nesnaz dostavat k runtime vecem. makro se vola pouze jednou a vygeneruje php kod. mas tedy vratit php kod, ktery pak zavola $this->global->uiPresenter->getTime()
  2. vsechny latte promenne jsou dostupne ve vyslednem kodu jako lokalni promenne
  3. ano, je to neprehledne. vzdycky si ale muzes udelat treba nejakou statickou funkci, kterou bude ten vygenerovany kod volat
Klobás
Člen | 113
+
0
-

David Matějka napsal(a):

  1. to je spatny postup. v makru se nesnaz dostavat k runtime vecem. makro se vola pouze jednou a vygeneruje php kod. mas tedy vratit php kod, ktery pak zavola $this->global->uiPresenter->getTime()
  2. vsechny latte promenne jsou dostupne ve vyslednem kodu jako lokalni promenne
  3. ano, je to neprehledne. vzdycky si ale muzes udelat treba nejakou statickou funkci, kterou bude ten vygenerovany kod volat
  1. Děkuji za vysvětlení, jak to tedy vypadá, protože mi Nette prostě řve, že$this->global->uiPresenter->getTime() prostě nezná, nebo to rvu někam blbě. Můžu požádat o názornou ukázku jak je to správně?
  2. Ano, už jsem na to taky přišel
  3. Opět, nějaká jednoduchá ukázka by nebyla?
David Matějka
Moderator | 6445
+
0
-
  1. a opravdu vracis php kod a nesnazis se to vykonat uvnitr makra? tedy vracis retezec s timhle obsahem a s escapovanym $?
  2. proste vratis treba return $writer->write('echo LatteRuntime::returnSomethingFromPresenter($this->global->uiPresenter);')
Klobás
Člen | 113
+
+1
-

David Matějka napsal(a):

  1. a opravdu vracis php kod a nesnazis se to vykonat uvnitr makra? tedy vracis retezec s timhle obsahem a s escapovanym $?
  2. proste vratis treba return $writer->write('echo LatteRuntime::returnSomethingFromPresenter($this->global->uiPresenter);')
  1. return $write->write("echo \$_presenter->getTime(); echo \$time; echo \$this->global->uiPresenter->getTime();");

první echo funguje, druhé taky, třetí ne, $this nezná, nebo zcela ještě nechápu jak s tím naložit.

  1. uff, to je zas na prozkoumání všech těhle tříd a i co je vlastně $this->global->uiPresenter, je to magické a není to popsané a já nejsem matfyzák :[
David Matějka
Moderator | 6445
+
0
-

a co pouzivas za verzi nette?

Klobás
Člen | 113
+
0
-

Ale asi pro moje potřeby stačí, že si umím sáhnout na presenter přes $presenter nebo $_presenter.
Tak se zeptám na praktické makro, jestli to tak půjde.
Chci vytvořit třeba detekci Desktopu a Telefonu (to je fuk proč na serverové straně).

Postup

  1. Udělám si model Detection, s metodou isMobile(), isDesktop()
  2. Injectnu do presenteru
  3. do nějakých protected proměnných $isMobile, $isDesktop nebo do latte proměnných $isMobile, $isDesktop si uložím volání zmíněných metod
  4. a pak už si vytvořím 2 jednoduchá makra, která budou na pricipu makra %if (s tím rozdílem, že místo node.args tam nasypu tyto 2 proměnné nebo tak nějak +/-).

Je to ok?

Klobás
Člen | 113
+
0
-

Co? :)

Klobás
Člen | 113
+
0
-

David Matějka napsal(a):

a co pouzivas za verzi nette?

Na jednom projektu mam ještě 2.1 a 2.2 (a ted na jednom 2.3). Zajímalo by mne jak to funguje napříč všemi.

CZechBoY
Člen | 3608
+
0
-

makra se právě celkem dost měnily v nette 2.4… @DavidMatějka ti psal jak by to vypadalo právě v nette 2.4

Klobás
Člen | 113
+
0
-

CZechBoY napsal(a):

makra se právě celkem dost měnily v nette 2.4… @DavidMatějka ti psal jak by to vypadalo právě v nette 2.4

Jasně a mohl bys mi tedy prosím napsat jak je to pro verzi 2.1–2.3?

Jedná se mi tedy o dořešení bodu 1 a 3

David Matějka
Moderator | 6445
+
0
-

na ten presenter se ve starsi verzi dostanes pres $_presenter. a u 3 ti neni jasny co? proste vratis kod, ktery zavola (statickou) funkci

Klobás
Člen | 113
+
0
-

David Matějka napsal(a):

na ten presenter se ve starsi verzi dostanes pres $_presenter. a u 3 ti neni jasny co? proste vratis kod, ktery zavola (statickou) funkci

  1. jasně, to jsem potřeboval tedy vědět.

A k té 3ce:

mohlo by to být tedy takto třeba?

<?php

public function time2(Latte\MacroNode $node, Latte\PhpWriter $write)
{

    return $write->write("echo \Nette\Latte\Macros\MacroPokus::renderTime(\$_presenter)");
}

public static function renderTime($presenter)
{
    return $presenter->getTime() . 'volano ze staticke metody a je to trosku cistci ...';
}
?>

A tím, že si tam prorvu presenter, tak se v presenteru dostanu na jakoukoliv metodu (která může v sobě volat volání metody z modelu a tam si můžu všechnu složitější logiku připravit), je to tedy OK?

Jestli je tohle správně a tys psal, at to řeším runtime, tak by mě zajímal ještě pohled na LOGIKA vs ZÁTĚŽ.


Kdybych chtěl mít třeba 2 makra na základě hodnoty třeba z pole $_SERVER a nějakého REGEXPU. (To je jedno, slouží pro ukázku).

  1. Mohl bysi udělat makro, které by v sobě ten regexp mělo a pokud bych pak v latté šabloně volal třeba 5× makro {checkWithRegexp}{/checkWithRegexp} tak se zbytečně bude 5 ověřovat něco co už bych teoreticky znal po 1× zavolání.

(V surovém php bych si udělal něco jako $checkWithRegexp = someMethodWithRegexp(); a poté už jen 5× v šabloně (if $checkWithRegexp)…

  1. Navazuji na konec jedničky, smysluplnější by tedy bylo, udělat si v basepresenteru $this->checkWithRegexp = someMethodWithRegexp() a pak mít makro které jen kontroluje tuto proměnnou.

Co je tedy lepší? Správnější je jednička (z logiky věci), ale díky snaze ušetřit zátěž je lepší 2ka.

Názor? A tím bysme to mohli uzavřít a moc děkuji :-)

David Matějka
Moderator | 6445
+
0
-

Jestli je tohle správně a tys psal, at to řeším runtime

musis to resit v runtime, jelikoz ty data (treba v _SERVER) se meni. kdybys uz v compile time zavolal treba to getTime(), tak tam budes mit ten cas v dobe kompilace nafurt :))

a neprehanej do s tema makrama. pokud to muzes vyhodnotit v presenteru, tak jen posli do sablony $checkWIthRegexp a pak to dej do {if}. Makra zacni psat az ve chvili, kdy v sablone budes mit hnusny kod nebo neco nepujde udelat lepe (tedy treba poslanim promenne z presenteru)

Klobás
Člen | 113
+
0
-

:-)

A čemu přesně říkáme runtime a kompilace? (Ukaž mi to někde v tom mém kódu). Protože ted si to zkouším a ukazuje mi to pořád nový a nový čas.
Jak bys zhodnotil můj dotaz 1 nebo 2? Nechci být jak kolovrátek, jen to chci pochopit do morku kostí.

S makrama to přehánět rozhodně nebudu, přijdou mi relativně složité a zatím sem se bez nich obešel.

Editoval Klobás (8. 3. 2018 16:13)

David Matějka
Moderator | 6445
+
0
-

kompilace – zavolani makra, ktere vygeneruje php kod. pote je zkompilovana sablona
runtime – provedeni toho kodu v sablone

Jak bys zhodnotil můj dotaz 1 nebo 2?

jestli myslis ty dve moznosti checkWithRegexp, tak v tomhle pripade je oboji zbytecne. ale jak to rikas, spravnejsi je asi to prvni.

Klobás
Člen | 113
+
0
-

:) díky moc. Už v tom mám celkem jasno, makra nebudu používat na denním pořádku, ale někdy se to třeba bude hodit.