Pojďme otestovat nette/application 3.1

David Grudl
Nette Core | 8082
+
+22
-

Poprosil bych o testování nette/application 3.1.0-RC, která přináší několik novinek důležitých pro typované šablony.

Přes všechny změny v šablonách by nemělo dojít k žádnému porušení zpětné kompatibility. Ale samozřejmě je to potřeba ověřit, obzvlášť pokud nakládáte se šablonou pro mě nečekaným způsobem.

Hlavní změny u šablon:

  • Nette\Bridges\ApplicationLatte\Template přestává používat magické settery a gettery, takže obvyklý zápis $template->val = $var je skutečným zápisem do proměnné objektu $template, což přinese i malé zrychlení (mnoho uživatelů nejspíš ani netušilo, že se tam používaly magické settery a gettery)
  • createTemplate() v Presenter a Control skrze TemplateFactory nyní nevyrábějí Template, ale buď jejího potomka a novou třídu DefaultTemplate
  • …nebo pokud existuje třída pojmenovaná stejně jako presenter či control, jen místo koncovky Presenter/Control končící na Template, vyrobí objekt této třídy
  • Pro Homepage:default se zkusí také šablona HomepageDefaultTemplate
  • zároveň createTemplate() přijímá volitelný parametr kterým lze přímo říct, jakou třídu má vyrobit. Abych skutečně předešel porušení zpětné kompatibility, je tento parametr zatím skrytý
  • Presenter::sendTemplate() přijímá volitelný parameter $template, můžete tedy odeslat jakoukoliv šablonu, třeba tu, kterou si vytvoříte pomocí createTemplate()

Deprecated stuff:

  • Template::__toString() je deprecated ve prospěch renderToString(), jeho účel pradávno převzaly bloky v Latte
  • Presenter::getContext() také vyhazuje deprecation notice. Je na čase tento krok udělat. Pokud DI kontejner v presenterech používáte a není snadné se ho zbavit, nevadí, předejte si jej konstruktorem nebo proměnnou s anotací inject a používejte nadále (klidně si přepište metodu getContext). Jde o to, aby se ho zbavil samotný UI\Presenter.
  • RouteList: deprecated jsou rozhraní Countable and IteratorAggregate, nahrazuje je metoda getRouters()
  • RouteList a SimpleRouter mají deprecated flagy. Dnes existuje jen flag ONE_WAY. Nelekejte se, vypadá to jako zásadní změna, ale ve skutečnosti jde o to, že k velkému posunu routování došlo ve verzi Nette 3.0, ve které se routy flagují trošku jinak a tohle je krůček v postupném přesunu k modernímu způsobu a úprava by měla být triviální.

Prosím tedy o otestování, ať může v brzké době vyjít a vývoj se posune dál směrem k šablonám testovaným pomocí PHPStanu.

David Grudl
Nette Core | 8082
+
+1
-

Někdo se zmiňoval, že (string) $template používá (asi v souvislosti s tvorbou emailů). Pokud je to používané, tak bych stav deprecated zrušil.

enumag
Člen | 2118
+
0
-

Dovolím si menší rýpnutí. Něco velmi podobného typovaným šablonám používám v Nette i Symfony už dávno (dávám tomu koncovku View). Ale proč by tenhle value objekt měl dědit Nette\Bridges\ApplicationLatte\Template, to mi tedy do hlavy nejde. :-) Imo by Template měla být final a custom View objekt by mela byt jedna z promennych.

David Grudl
Nette Core | 8082
+
0
-

Rýpat snad není potřeba, pokládat otázky je zcela ok. Dědit od té třídy se samozřejmě nemusí. Hledal jsem, jak jsi na to narazil, jde asi o formulaci z odkazovaného vlákna? To bylo myšleno jinak, v návaznosti na update, upravím to.

Petr Parolek
Člen | 455
+
0
-

Ahoj, stále 3.1.0-RC obsahuje bug https://github.com/…n/issues/253 , tato chyba se týká i v3.0.4.

enumag
Člen | 2118
+
0
-

Přesně tak, v odkazovaném vláknu je všude class ArticleTemplate extends Nette\Bridges\ApplicationLatte\Template. Pokud ten objekt nemusí nic dědit ani implementovat tak máš palec nahoru. ;-)

David Grudl
Nette Core | 8082
+
0
-

Musí implementovat Nette\Application\UI\ITemplate. Dědit nemusí, ale pokud chceš používat metody jako $template->addFilter() atd, tak si je pak musíš dopsat.

Tomáš Jacík
Člen | 146
+
0
-

Zatím jsem to zkoušel jen zběžně v mý nejsložitější appce a zdá se, že je všechno ok. Budu ještě zkoušet. Co jsem dneska z toho PoSobota streamu nepochopil je ta DefaultTemplate, můžeš to prosím nějak osvětlit, jak donutit appku, aby použila tu DefaultTemplate, když nemám vytvořenu speciální třídu pro presenter?

Šaman
Člen | 2632
+
+2
-

Tomáš Jacík: Já to pochopil tak, že se použije DefaultTemplate vždy, když apliaci nedonutíš použít něco jiného.
Dnešní přednášky mě taky navnadily, jdu to zkusit na aktuální aplikaci.

Ages
Člen | 127
+
0
-

Chtěl jsem vytvořit BaseTemplate, kterou bych použil jako rodiče a nemohl jsem přijít na to proč mi nefungují kontroly proměnných, až jsem nakonec zjistil, že tato třída nemůže být abstract.
Je toto chování správné?

// Toto nefunguje
abstract class BaseTemplate extends Template
{
	//...
}
// Toto funguje
class BaseTemplate extends Template
{
	//...
}

Editoval Ages (1. 4. 2020 10:09)

Ages
Člen | 127
+
0
-

Pokusil jsem se to ještě jednou vrátit na abstract a nyní to již kontroluje i s abstract.
Popravdě nerozumím tomu, kde mohlo dojít k problému, nic jiného jsem neupravil.

CZechBoY
Člen | 3608
+
0
-

@Ages Nejspíš ti chyběla implementace pro konkrétní template.

Ages
Člen | 127
+
0
-

@CZechBoY právě že ne :(, pokud by se mi to ještě stalo tak dám vědět.

xr
Člen | 94
+
0
-

@DavidGrudl Davide, ved je tam zretelny BC break: Nette\Bridges\ApplicationLatte\TemplateFactory::createTemplate ma parameter naviac, takze podedena trieda nie je kompatibilna… Co takto pouzit rovnaky „trik“ so skrytym parametrom ako si spravil v Control? Nie ze by som mal rad tieto parametre (presne naopak), ale pre zachovanie kompatibility.

Martk
Člen | 651
+
0
-

@xr Souhlasím s tebou, že je to BC break. Ale chyba je už v tom, že tato třída není final. Měla by se u této třídy použít dekorace a ne znásilňovat dědičnost.

xr
Člen | 94
+
0
-

@Martk aby mohla byt final, musela by byt implementacia dostatocne flexibilna, aby neblo nutne kopirovat cely kod sablony kvoli malemu rozsireniu. Pouzivam rozsirenie, kde sa upravuje metoda render sposobom, ktory urcite 99.99% ostatnych uzivatelov nebude potrebovat a pokryvat tento use-case v zakladnej sablone Nette by bolo zbytocne.

@DavidGrudl Dalsi zjavny BC Break je v pripade podedenych sablon – pretoze dedia od Nette\Bridges\ApplicationLatte\Template, a teda nie je dostupna premenna $control, $presenter atd., ktore sa predtym setovali navrdo, v 3.1 sa setuju po kontrole na property_exists.

Takze za mna upravy sablon v 3.1 nie su vobec spatne kompatibilne, pretoze moj balicek rozsirujuci funkcnost sablon po upravach, aby bol kompatibilny s 3.1, nebude spatne kompatibilny s verziou pracujucou s 3.0 == BC Break.

EDIT: David, este nechapem, preco je __toString zrazu reprecated – aky je problem po ~10 rokoch so (string) $template nechapem.

Inak to vyzera, ze to po uprave Template a TemplateFactory slape normalne.

Editoval xr (29. 4. 2020 16:49)

David Grudl
Nette Core | 8082
+
0
-

Hypotetických BC breaků je tam samozřejmě spousta, jde o to podchytit ty reálné. Jestli to dobře chápu, ty dědíš od třídy TemplateFactory a z createTemplate() vracíš objekty Template? Jaký to má důvod?

xr
Člen | 94
+
0
-

TemplateFactory predsa sluzi na vytvaranie Template …

Mam podedenu (Nette\Bridges\ApplicationLatte) TemplateFactory a pouzivam vlastne sablony, ktore dedia od Nette\Bridges\ApplicationLatte\Template.

UPDATE: nejedna sa o hypoteticke bc breaky – teraz som to vyskusal a pisem len, na co som narazil. Su to minutove zalezitosti, ale nie su spatne kompatibilne. Jediny problem mi sposobuje ta uprava __toString.

Editoval xr (29. 4. 2020 16:56)

David Grudl
Nette Core | 8082
+
0
-

A můžeš mi to trošku popsat? Co je cílem tvých modifikací?

xr
Člen | 94
+
0
-

Neviem sice ako to pomoze obohatit situaciu, ale mozem popisat.

TemplateFactory mam upravene tak, ze mi na kazdej vytvaranej sablone zaregistruje filtre, premenne, global providers a spusti genericke dekoratory, ktore si mozu vyvojari zaregistrovat v NEONe.
Jednoducha ale velmi sikovna uprava, ktora umoznuje napriklad plosnu registraciu heleprov bez nutnosti riesit, ci su pritomne v sablonach vytvaranych prezentermi alebo v sablonach, ktore sa vytvaraju pre spracovanie mailerom.

V Template mam upravenu render metodu tak, ze s vystupom od parenta este nieco kontrolujem a pripadne korigujem vystup. Toto je dost okrajovy pripad, bohuzial specificka poziadavka od zakaznika. Ak existuje lepsi sposob pre globalny vystupny filter, neviem o nom.

Ako som pisal, je jednoduche pridat parameter a zopar atributov podla vzoru DefaultTemplate. Akurat chcem uviest na spravnu mieru, ze upravy v 3.1 _nie su kompatibilne_.

A s deprecated __toString mam problem preto, ze pouzivam paralelne aj iny sablonovaci system a teraz budem vsade musiet riesit nejaky instanceof alebo nieco podobne. Pritom jednoduchy (string) typecast nic nepokazi, navyse od 7.4 uz je mozne aj pekne vyhadzovat vynimky.

Šaman
Člen | 2632
+
0
-

xr:

David Grudl napsal(a):

Přes všechny změny v šablonách by nemělo dojít k žádnému porušení zpětné kompatibility. Ale samozřejmě je to potřeba ověřit, obzvlášť pokud nakládáte se šablonou pro mě nečekaným způsobem.

Řekl bych, že nakládáš se šablonou pro něho nečekaným způsobem. Proto zjišťuje k čemu to poutřebuješ.

Jinak nejde to řešit běžným způsobem bez dědění?

<?php
class myTemplateFactory
{

	public class createTemplate(UI\Control $control = null)
	{
		$template = $this->netteApplicationTemplateFactory->createTemplate($control);
		$template->tadySiSNíMohuDělatCoChci();
		return $template;
	}

}
?>
xr
Člen | 94
+
0
-

Ano, urcite je to jednym z rieseni. 👍 S velkou pravdepodobnostou je lepsie tu tovaren poskladat kompozicne ako dedit.

Myslel som, ze je dostatocne zrejme, ked uvediem, ze _dedim_ tu tovaren. Dedenie nefinalnych tried predsa nie je nicim vynimocnym. Nechcem tu robit z toho ziaden „flame“ alebo velku vedu, len som na to chcel upozornit, kedze David chcel feedback. Jedine ten typecast ma trapi.

Mozno je vhodnejsie napisat, ze _pouzitie_ je rovnake ako vo verzii 3.0, spatna kompatibilita vo vyzname semantickeho verzovania tam urcite zachovana nie je.

Felix
Nette Core | 1183
+
0
-

Osobne tez podedivam (no jo) TemplateFactory a registruju tam globalni filtry a makra, pripadne vyplnuju globalni promenne pro vsechny sablony.

Kdyby byla final, pouzival bych spis nejakou formu dekorace. :-)

David Grudl
Nette Core | 8082
+
+2
-

Ptám se jak to používáš, protože prostě rozhoduju, jestli trošku zkomplikuji život tobě teď, nebo v budoucnu sobě.

Vidím to tak, že druhý parametrý parameter createTemplate() asi dám skrytý.

Na __toString už přišly reakce, že se opravdu používá, takže ji rušit nebudu.

Co se týče rozdělení Template / DefaultTemplate, tam je hodně komplikované. Bude výhodné mít pod názvem Nette\Bridges\ApplicationLatte\Template čistou šablonu, od které se teď bude asi dost dědit a ponechat víceméně současné řešení i za cenu BC breaku, který se dá velmi snadno vyřešit. Zvažuju ještě přejmenovat DefaultTemplate na LegacyTemplate.

xr
Člen | 94
+
0
-

Ano, ten BC break je jednoduche vyriesit, akurat to prosim uved do popisu, nech je to zrejme na prvy pohlad 👍

Vidím to tak, že druhý parametrý parameter createTemplate() asi dám skrytý.

^ Za mna, ak to oznacis v dokumentacii, tak to nie je ziaden problem. Navyse, ak prerobim tovaren podla komentara vyssie (nahradim dedicnost za kompoziciu), tak tento problem neexistuje. Jedine je potrebne upravit inicializaciu novej TempalteFactory, ktora po novom prijima Nette\TemplateFactory ako argument konstruktoru.

Na __toString už přišly reakce, že se opravdu používá, takže ji rušit nebudu.

^ Skvele!

Milanov
Člen | 51
+
+1
-

Verzi rc máme zhruba týden nasazenou na https://www.megapixel.cz a bez problémů. Všechno funguje podle očekávání. Trochu nás zaskočila metoda ->add(), kterou jsme měli použitou a zároveň jsme používali makro {templateType} v šabloně. Metoda ->add() už ve vlastní šabloně není, možná bych to přidal do release notes, společně s ostatními proměnnými jako $user, $presenter, na které byli lidé nejspíš zvyklí

David Grudl
Nette Core | 8082
+
0
-

Ona ta metoda add() (a setParameters() jde vlastně proti smyslu properties, proto v Nette\Bridges\ApplicationLatte\Template není, jen v DefaultTemplate.

Pavel Kravčík
Člen | 1180
+
0
-

Pokud dnes aktualizuji Nette s tím, že composer vypadá následovně a dojde jen k aktualizaci desetinkových verzí.

"php": "7.3.*",
"nette/application": "^3.0.6",
"nette/bootstrap": "^3",
"nette/caching": "^3",
"nette/database": "^3",
"nette/di": "^3",
 ...

Nainstaluje se php-generator 3.5 a přestane to na PHP7.3 fungovat kvůli pojmenovaným paramterům v DI.

Řešení je snadné, vynutit si verzi generatoru na 3.4.

"nette/php-generator": "3.4.*",

Spíš mi napadá, jestli někde nedošlo k špatnému popsání composer chainu závislostí.

David Grudl
Nette Core | 8082
+
0
-

To je nějaký bug. Můžeš mi poslat, třeba emailem, nějakou minimální ukázku kodu kdy to havaruje?

Pavel Kravčík
Člen | 1180
+
0
-

Řekl bych, že to bude tady:

public function afterCompile(Code\ClassType $class)
{
	$init = $class->getMethods()['initialize'];
	$config = $this->validateConfig(['name' => 'addDuplicator', 'container' => \Code\Component\Container::class, 'form' => \Code\Component\Form::class]);

	$init->addBody(Duplicator::class . '::register(?*);', [$config]);
}

A výstup: yntax error, unexpected ':', expecting ')' na řádku 4201: name: 'addDuplicator', – asi jde o tu dvojtečku.

Editoval Pavel Kravčík (4. 11. 2020 8:14)

David Grudl
Nette Core | 8082
+
+1
-

Aha, vydal jsem opravu.

Pavel Kravčík
Člen | 1180
+
0
-

Super, díky – funguje to. :)

Václav Pávek
Backer | 96
+
0
-

Na kdy je plánováno vydání v3.1?

dakur
Člen | 493
+
+1
-

@DavidGrudl Spolu s getContext() jsi deprecatnul i unformatPresenterClass(). Je za to někde nějaká náhrada? Máme v routeru helper, který převádí XyzPresenter::class na AbcModule:Xyz notaci.

Marek Bartoš
Nette Blogger | 1146
+
+1
-

deprecatnul i unformatPresenterClass()

Používám též, ze stejného důvodu. Též pomocí této metody generuju navigaci webu pro vývojáře.

David Grudl
Nette Core | 8082
+
0
-

getContext() je deprecated, ale zároveň přestal být final, abyste si ji klidně mohli třeba v BasePresenteru přepsat a bude fungovat i nadále. Point je v tom, že třída UI\Presenter nebude mít kontejner jako závislost, protože ho už devět let nepotřebuje.

unformatPresenterClass() je deprecated, protože jsem přišel na to, že to není úplně spolehlivá a nenašel jsem rychle snadný způsob, jak ji napsat spolehlivou a framework se bez ní obejde.

David Grudl
Nette Core | 8082
+
+5
-

Jinak nette/application 3.1 je venku!

dakur
Člen | 493
+
0
-

David Grudl napsal(a):

unformatPresenterClass() je deprecated, protože jsem přišel na to, že to není úplně spolehlivá a nenašel jsem rychle snadný způsob, jak ji napsat spolehlivou a framework se bez ní obejde.

Jenže zvenku se nedá dostat k $mapping, nemůžu si tedy funkci zkopírovat do svého kódu. Jak to mám řešit?

Editoval dakur (7. 1. 2021 10:15)

Václav Pávek
Backer | 96
+
0
-

David Grudl napsal(a):

unformatPresenterClass() je deprecated, protože jsem přišel na to, že to není úplně spolehlivá a nenašel jsem rychle snadný způsob, jak ji napsat spolehlivou a framework se bez ní obejde.

Mě by zajímalo v čem není tato metoda spolehlivá. Používám ji u routingu a oprávnění.
Řešením by bylo vyčlenit mapping do PresenterMapper jako to má nepada/presenter-mapping.

Editoval Václav Pávek (7. 1. 2021 9:46)

Václav Pávek
Backer | 96
+
0
-

dakur napsal(a):

Jenže zvenku se nedá dostat k $mapping, nemůže si tedy funkci zkopírovat do svého kódu. Jak to mám řešit?

Vlastní PresenterFactory nebo nepada/presenter-mapping.

Martk
Člen | 651
+
0
-

@DavidGrudl Dá se v latte udělat něco jako:

Třída šablony:

class CommentTemplate {

	public function __construct(
		private Service $service,
		private Comment $comment,
	)
	{
	}

	#[LatteFunction] // latte vytvoří funkci
	public function commentAuthor(Comment $comment): ?Account
	{
		return ...;
	}

	#[LatteProperty] // latte pochopí tento getter jako proměnnou $comment
	public function getComment(): Comment
	{
		return $this->comment;
	}

}

Továrna na třídu šablony:

interface CommentTemplateFactory {

	public function create(Comment $comment): CommentTemplate;

}

Použití v php latte:

$template->render('comment.latte', $commentTemplateFactory->create(new Comment()));

Použití v latte:

{$comment} {* vola CommentTemplate->getComment() *}
{commentAuthor(...)} {* vola CommentTemplate->commentAuthor(...) *}

Editoval Martk (7. 1. 2021 12:13)

David Grudl
Nette Core | 8082
+
+1
-

@Martk fungují takto anotace @function a @filter. Nic jako tvé LatteProperty tam není a ani to nemám v plánu.

medhi
Generous Backer | 255
+
0
-

Právě testuji Nette 3.1 na PHP 8.1 a mám problém. Nainstaloval jsem web-project:

~/Sites composer create-project nette/web-project nette-blog
Creating a "nette/web-project" project at "./nette-blog"
Installing nette/web-project (v3.1.7)
  - Downloading nette/web-project (v3.1.7)
  - Installing nette/web-project (v3.1.7): Extracting archive

...

  Problem 1
    - nette/bootstrap is locked to version v3.1.1 and an update of this package was not requested.
    - nette/bootstrap v3.1.1 requires php >=7.2 <8.1 -> your php version (8.1.0) does not satisfy that requirement.
  Problem 2
    - nette/caching is locked to version v3.1.1 and an update of this package was not requested.
    - nette/caching v3.1.1 requires php >=7.2 <8.1 -> your php version (8.1.0) does not satisfy that requirement.
  Problem 3
    - nette/database is locked to version v3.1.3 and an update of this package was not requested.
    - nette/database v3.1.3 requires php >=7.2 <8.1 -> your php version (8.1.0) does not satisfy that requirement.
  Problem 4
    - nette/mail is locked to version v3.1.7 and an update of this package was not requested.
    - nette/mail v3.1.7 requires php >=7.1 <8.1 -> your php version (8.1.0) does not satisfy that requirement.

Podle tabulky kompatibility by Nette 3.1 už mělo být pro PHP 8.1.

Když jsem updatoval Nette na existujícím projektu, dostanu tuto chybu:

Deprecated

Return type of Nette\Application\Routers\RouteList::offsetGet($index) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice

To #[\ReturnTypeWillChange] už je nyní koukám už v kódu někde změněno, ale nevím, jak to nainstalovat composerem. Ve verzi 3.1.4 to je pořád takto.

David Grudl
Nette Core | 8082
+
+1
-

Visela tam nějaká stará verze web-projectu, udělal jsem nový tag a už by to mělo fungovat.