Prosím o otestování Latte 3.0.5 – možný BC break

David Grudl
Nette Core | 8227
+
+7
-

Prosím o otestování Latte 3.0.5 RC a Forms 3.1.9 RC

composer require latte/latte:^3.0.5-RC1 nette/forms:^3.1.9-RC

Latte

Krom opravy celé řady chybek obsahuje nová verze jeden záměrný BC break – upozorní, pokud vaše vlastní značka (třída Node) neobsahuje metodu getIterator(). To může představovat vážné bezpečnostní riziko. Vysvětlení je tady.

Další změnou je, že uvnitř elementu <script type=unknown>...</script> se neescapuje HTML (nyní se tak děje pouze u type=text/html). Tím unknown myslím typ, který Latte nepodporuje, tj. není to JavaScript, JSON, text/html, nebo text/plain. Pokud používáte nějaký speciální typ a HTML escapování očekáváte, napište sem prosím.

Pokud používáte Latte samostatně, novinkou je TracyExtension. Použití viz dokumentace. Nahrazuje třídy BlueScreenPanel a LattePanel.

A nakonec, přidal jsem experimentální feature, kdy |noescape v určitých situacích nevypne escapování úplně, ale jen částečně. Ukázka:

<p title="{$title|noescape}"> ... </p>
<script> {$js|noescape} </script>

V prvním případě se bude stále escapovat znak ", ve druhém sekvence </script>. Tedy aby nebylo možné uniknout z kontextu atributu resp. elementu <script>. Programátor může totiž v těchto místech použít |noescape třeba proto, že $title obsahuje HTML entity, $js obsahuje JavaScript, ale už mu nedojde, že tím může narušit stránku. Tedy |noescape by mělo být bezpečnější.

Formuláře

  • lepší chybové zprávy místo dřívějších end(): Argument #1 must be of type array ...
  • oprava parsování {label} a {input}
  • {inputError} bez argumentu upozorní na chybějící argument
mskocik
Člen | 62
+
0
-

Po update dotavam nasledovny error: Includujem block z danej sablony

Latte\RuntimeException
Including block m_create_tags with content type HTML into incompatible type HTML/RAW+TEXT.
<div v-show="currentStep == 0" class="tb-step-wrap">
  {include #m_create_tags, form => $form}
</div>

{define m_create_tags}
<form action="" data-noajax @submit.prevent="goForward">
    {var $renderer = $form->getRenderer()}
    {$renderer->renderPair($form['channel'])|noescape}
    {$renderer->renderPair($form['subids'])|noescape}
    <div class="form-group row pt-3">
...

Vo verzii 3.0.4 vsetko funguje.

Editoval mskocik (2. 1. 2023 14:26)

David Grudl
Nette Core | 8227
+
0
-

@mskocik takovou chybu nemůžu vyvolat, asi je tva ukázka zjednodušená přiliš moc.

mskocik
Člen | 62
+
0
-

@DavidGrudl aha… tak to bude tým, že mám celú šablónu obalenú <script type="text/x-template" id="target-builder-tpl">.

V mojom use case definujem Vue šablónu a využívam automatický nette form rendering.

Marek Bartoš
Nette Blogger | 1274
+
+1
-

Zkusil jsem prohledat internet a najít <script> tagy kombinující html a custom template jazyky

  • VueJS – text/x-template a x-template
  • mustache.js – x-tmpl-mustache a text/x-mustache-template
  • JsViews – text/x-jsrender
  • Template7 – text/template7
  • časté bylo text/template
m.brecher
Generous Backer | 871
+
0
-

Ahoj,

našel jsem ve formulářích pár drobností (které tam asi budou už delší dobu) a tak jsem se chtěl zeptat, zda je zvykem psát poznámky z testů do tohoto vlákna nebo na github ?

David Grudl
Nette Core | 8227
+
0
-

@mskocik jo, přesně na takovou věc jsem potřeboval narazit, zahrnu typ text/template a podobné pod HTML

@MarekBartoš je mi trošku záhadou, proč po osmi letech existence značky <template> se stále používá zcela nevhodný <script> 🤦‍♂️

@mbrecher pokud to souvisí přímo s připravovanou verzí, piš sem

m.brecher
Generous Backer | 871
+
0
-

Ahoj,

úprava form inputu Email

navrhuji doplnit do formulářového prvku Email stejné parametry jako má prvek TextInput – $cols a $maxLength, myslím, že není důvod, aby tam tyto parametry chyběly:

\vendor\nette\forms\src\Forms\Container.php

namespace Nette\Forms;

.......

class Container extends Nette\ComponentModel\Container implements \ArrayAccess
{
    ......
    ......

	// stávající kód
    public function addEmail(string $name, $label = null): Controls\TextInput
    {
        return $this[$name] = (new Controls\TextInput($label))
            ->addRule(Form::EMAIL);
    }

    // nový kód
    public function addEmail(string $name, $label = null, ?int $cols = null, ?int $maxLength = null): Controls\TextInput
    {
        return $this[$name] = (new Controls\TextInput($label, $maxLength))
            ->setHtmlAttribute('size', $cols)
            ->addRule(Form::EMAIL);
    }

    ....
    ....
}

Editoval m.brecher (6. 1. 2023 19:48)

mskocik
Člen | 62
+
0
-

David Grudl napsal(a):

@MarekBartoš je mi trošku záhadou, proč po osmi letech existence značky <template> se stále používá zcela nevhodný <script> 🤦‍♂️

@DavidGrudl povedal by som, že to bude tým, že zo <script> sa dá jednoducho dostať textový obsah.

Možno by stálo za to aj mať možnosť override priamo z latte, ak by niekto vyslovene potreboval použiť nejaký „unknown“ type. Hoci viem, že sa to dá vždy napísať ručne takto:

{= $this->renderBlock('m_create_tags', ['form' => $form] + get_defined_vars(), 'html')} // html namiesto html/raw+text

Editoval mskocik (7. 1. 2023 13:10)

David Grudl
Nette Core | 8227
+
+1
-

Prosím o otestování Latte 3.0.5-RC2

Věci kolem elementu <script> jsem vyčlenil až do příští verze. Naopak jsem doplnil novou značku {exitIf} https://github.com/…e/issues/287

composer require latte/latte:^3.0.5-RC2
kukulich
Člen | 58
+
0
-

David Grudl napsal(a):

Prosím o otestování Latte 3.0.5-RC2

Věci kolem elementu <script> jsem vyčlenil až do příští verze. Naopak jsem doplnil novou značku {exitIf} https://github.com/…e/issues/287

composer require latte/latte:^3.0.5-RC2

V 3.0.4 tohle fungovalo:

"type": {=\Slevomat\SpreadsheetExport\SpreadsheetExportTuningBackgroundExportTask::class|escapeJs},

V 3.0.5 to vyhazuje chybu:

Keyword 'class' is not supported in Latte (in '.../Product/Dashboard.default.latte' on line 152 at column 76)
David Grudl
Nette Core | 8227
+
0
-

@kukulich mělo by to být opravené

kukulich
Člen | 58
+
0
-

David Grudl napsal(a):

@kukulich mělo by to být opravené

Potvrzuju.

Teď jsem se dostal na jinou chybu:

Keyword 'for' cannot be used in Latte

Kód:

{label $cancelIntervalInputName, for => 'js-cancel-interval' /}

Je to správně? Dá se to jednoduše opravit, když tam dám 'for', ale nevím, zda je to stejně cílené.

m.brecher
Generous Backer | 871
+
0
-

Narazil jsem na to, že cachování překladů statických textů v latte šablonách – tag {translate} nefunguje, detailně popsáno zde:

https://forum.nette.org/…latte-v3-0-4

David Grudl
Nette Core | 8227
+
0
-

@kukulich uff, chtěl jsem vylepšit chybové hlášky, kdyby se někdo snažil používat if vytvářet v Latte třídy.

Vyřešil jsem to nakonec tak, že se bude kontrolovat jen první token v {do ...} nebo {php ...}. Takže už to snad je ok :)

@mbrecher a zkoušel jsi tuhle vývojářskou verzi? Pokud ne, tak ji pls zkus.

m.brecher
Generous Backer | 871
+
+2
-

@DavidGrudl

verze latte/latte:^3.0.5-RC1 na Windows – cachování překladů šablon FUNGUJE !!

Super ;)

Editoval m.brecher (16. 1. 2023 20:56)

kukulich
Člen | 58
+
0
-

@DavidGrudl

David Grudl napsal(a):

@kukulich uff, chtěl jsem vylepšit chybové hlášky, kdyby se někdo snažil používat if vytvářet v Latte třídy.

Vyřešil jsem to nakonec tak, že se bude kontrolovat jen první token v {do ...} nebo {php ...}. Takže už to snad je ok :)

Jo, teď vše prošlo!

m.brecher
Generous Backer | 871
+
+1
-

@DavidGrudl

Před cca 24 hodinami jsem nastavoval více proměnných v latte {var}, kde mě štvalo, že nejde napsat jednoduše:

{var
   $class1 = $item->value1,
   $class2 = $item->value1,
   $class3 = match($item->state){
      'state1' => 'class3',
      'state2' => 'class4'
   }
}

Ale musíte psát komplikovaně:

{var
   $class1 = $item->value1,
   $class2 = $item->value1,
}
{do
   $class3 = match($item->state){
      'state1' => 'class3',
      'state2' => 'class4'
      default => null
   }

Říkal jsem si, že bych někdy podal návrh na vylepšení Latte – implementovat match() v tagu {var} a volbu default, která je v šablonách nadbytečná učinit nepovinnou !!

Včera jsem si instaloval zkušební verzi Latte 3.0.5 RC1 a nevěřím svým očím ! Ono je to tam:

{var
   $class3 = match($item->state){   // ve verzi Latte 3.0.5 RC1 funguje !!
      'state1' => 'class3',
      'state2' => 'class4'
   }
}

Tak jsem si říkal, že tohle je možné snad jedině v Nette Frameworku – jenom si myslíte nějaké přání jak software vylepšit a do 24 hodin to máte tam :).

m.brecher
Generous Backer | 871
+
0
-

Při nastavování proměnných v tagu {var} v latte šabloně dělá určité potíže trailing comma, na kterou už si člověk zvyknul, že od PHP 7.2 už může všude být:

{var
    $class1 = $var1,
    $class2 = $var1,   // Latte vyhodí kvůli čárce CompileException
}

Navrhuji v tagu {var} trailing comma tolerovat stejně jako je to v polích PHP

Editoval m.brecher (17. 1. 2023 20:09)

David Grudl
Nette Core | 8227
+
+3
-

Doplním.

m.brecher
Generous Backer | 871
+
-4
-

nette/forms:^3.1.9-RC:

Zástupný řetězec %label v chybových hláškách validace formulářů není optimálně vyřešen. Formuláře ho nahrazují popiskou prvku (bez dvojtečky na konci), ale neřeší se upper/lower – case prvního písmena popisky. Záleží totiž, zda zástupný řetězec %label použijeme na začátku chybové hlášky nebo uprostřed/na konci.

$form->addText('title', 'Nadpis', ...)
    ->setRequired('%label musí být vyplněn!')    // hláška:  'Nadpis musí být vyplněn!'

$form->addText('title', 'Nadpis', ...)
    ->setRequired('Vyplňte %label!')    // hláška:  'Vyplňte Nadpis!'

    // hlášky bychom ale raději měli takto:
    //  'Nadpis musí být vyplněn!'   - pro počáteční písmeno zachovat (vynutit) uppercase
    //  'Vyplňte nadpis!'            - pro počáteční písmeno použít lowercase

Navrhuji změnu vyhodnocení zástupného řetězce %label takto:

  • je-li %label na začátku chybové zprávy – konvertovat první písmeno popisky prvku na UPPERCASE
  • je-li %label jinde než na začátku chybové zprávy – konvertovat první písmeno popisky prvku na LOWERCASER
MajklNajt
Člen | 498
+
0
-

m.brecher napsal(a):

nette/forms:^3.1.9-RC:

Zástupný řetězec %label v chybových hláškách validace formulářů není optimálně vyřešen. Formuláře ho nahrazují popiskou prvku (bez dvojtečky na konci), ale neřeší se upper/lower – case prvního písmena popisky. Záleží totiž, zda zástupný řetězec %label použijeme na začátku chybové hlášky nebo uprostřed/na konci.

$form->addText('title', 'Nadpis', ...)
    ->setRequired('%label musí být vyplněn!')    // hláška:  'Nadpis musí být vyplněn!'

$form->addText('title', 'Nadpis', ...)
    ->setRequired('Vyplňte %label!')    // hláška:  'Vyplňte Nadpis!'

    // hlášky bychom ale raději měli takto:
    //  'Nadpis musí být vyplněn!'   - pro počáteční písmeno zachovat (vynutit) uppercase
    //  'Vyplňte nadpis!'            - pro počáteční písmeno použít lowercase

Navrhuji změnu vyhodnocení zástupného řetězce %label takto:

  • je-li %label na začátku chybové zprávy – konvertovat první písmeno popisky prvku na UPPERCASE
  • je-li %label jinde než na začátku chybové zprávy – konvertovat první písmeno popisky prvku na LOWERCASER

…a potom budem dostávať 'Vyplňte dIČ!'

David Grudl
Nette Core | 8227
+
0
-

@mbrecher prosím, na nesouvisející věci vytvářej samostatné vlakna

m.brecher
Generous Backer | 871
+
0
-

Objevila se chyba při vykreslování formulářů v šabloně Latte – a sice partial rendering checkbox. Když je checkbox v těle formuláře tak šablona vykresluje, když je checkbox v kontejneru tak dojde k chybě v latte.

Podrobná dokumentace:

    protected function createComponentForm(): Form
    {
        $form = new Form;

        $form->addCheckbox('test', 'Test');  // tenhle checkbox šablona vykreslí

        $columns = $form->addContainer('pricelist_column');
        foreach ([1,2,3] as $id){
            $column = $columns->addContainer($id);
            $column->addCheckbox('test_checkbox_'.$id, 'Test');  // zde dojde v latte k chybě
        }

        bdump($form->getComponents());   // tady všechny checkboxy jsou

        return $form;
    }

Šablona:

// stručný extrakt ze složité šablony, otestováno
{form form}
    {foreach $form->getControls() as $input}
        {if $input->getOption(type) === checkbox}
            <label n:name="$input:" class="input-label">{$input->caption}</label>
            {input $input->name:}  // tento řádek Tracy zvýrazní
        {/if}
    {/foreach}
{/form}

Chybová hláška:

Nette\InvalidArgumentException
Component with name 'test_checkbox_1' does not exist.

Testoval jsem ještě vykreslení textInputu v kontejenru a to funguje, další prvky jsem netestoval.

Mám nainstalované obě testovací verze – jak forms, tak latte.

Editoval m.brecher (20. 1. 2023 2:38)

m.brecher
Generous Backer | 871
+
0
-

V dokumentaci k vykreslování formulářů jsem objevil doporučovaný způsob pro partial rendering:

https://doc.nette.org/…ms/rendering#…

{form form}
    {foreach $form->getControls() as $input}
        {if $input->getOption(type) === checkbox}
            {dump $input}
            <label n:name="$input:" class="input-label">{$input->caption}</label>
            {$input->getControlPart()}  // přepsáno podle dokumentace - OK
        {/if}
    {/foreach}
{/form}

A ten se vykresluje bez problémů. Výše uvedený nefunkční způsob mě někdo poradil, v dokumentaci není, takže je to asi OK.

David Grudl
Nette Core | 8227
+
0
-

@mbrecher prosím, na nesouvisející věci vytvářej samostatné vlakna