Základ pro single action presentery

Marek Znojil
Člen | 28
+
0
-

Ahoj,

po přečtení diskuse https://forum.nette.org/…ny-do-modulu se mi zalíbila myšlenka presenterů, které by měly pouze jednu akci.

Tak jsem zkusil napsat základní presenter:

<?php
declare(strict_types = 1);

namespace App\Module\Base\Presenters;

use Nette;

abstract class SingleActionBasePresenter extends Nette\Application\UI\Presenter{

    protected function startup(): void{
        parent::startup();

      if($this->action !== parent::DEFAULT_ACTION){
          $this->error();  // Pouze výchozí akce.
      }

        $explodedPathInfo = explode('/', $this->getHttpRequest()->getUrl()->getPathInfo());
      if(count($explodedPathInfo) > 1 AND end($explodedPathInfo) === parent::DEFAULT_ACTION){
          $this->error();  // Výchozí akce nesmí být zadána v url.
      }

        $this->canonicalize();
        $this->changeAction('');
    }

    protected function beforeRender(): void{
        parent::beforeRender();

        $explodedPresenterName = explode(':', $this->getName());
        $presenterName = lcfirst(end($explodedPresenterName));
        $dir = dirname((new \ReflectionClass($this))->getFileName());

        $this->template->setFile(
          $dir . '/../templates/' . $presenterName . '.latte'
        );
    }

}

Rád bych znal váš názor, jestli si myslíte, že je to ok či by bylo potřeba ještě něco doplnit. Struktura souborů šablon by se jistě dala upravit a provést intuitivněji, ale pro začátek toto jako základ určitě stačí.

Také bych jistě uvítal vaše tipy či rady pokud jste třeba již řešili či řešíte podobnou problematiku.

Třeba by zajímalo jak by jste se postavili k problému, kdybych chtěl aby url:
https://www.example.com/product/1 byla ProductPresenter
a
https://www.example.com/product/edit/1 byla ProductEditPresenter

Při aktuálním řešení url vypadají takto:
https://www.example.com/product/1ProductPresenter
https://www.example.com/product-edit/1ProductEditPresenter

Je možné toto vyřešit nějak elegantněji kdybych chtěl aby obě url odkazovaly na presentery s jednou akci aniž bych upravoval router?

Díky,

M.

Editoval Marek Znojil (18. 7. 2020 13:26)

CZechBoY
Člen | 3598
+
+2
-

Ja to treba zase tolik nehrotim a proste pouzivam jen actionDefault. Jeste by slo udelat treba nejaky phpstan pravidlo, ktery by zakazalo jiny akce nez default.

K tem routam: klidne muzes mit product module a v nem presentery add dle libosti.

Editoval CZechBoY (18. 7. 2020 18:06)

Felix
Nette Core | 1072
+
+1
-

Jestli by jsi chtel misto actionDefault treba jenom action nebo jenom default, tak by stacilo prepsat metody formatActionMethod a formatRenderMethod.

public static function formatActionMethod($action)
{
    return 'action';
}

public static function formatRenderMethod($action)
{
    return 'render';
}

Teoreticky by jsi tam mohl i vyhazovat exception, pokud action neni default.

public static function formatActionMethod($action)
{
    if ($action !== 'default') $this->error('Only default actions are allowed');
    return 'action';
}

Pokud by se ti to nelibilo validovat primo v techto metodach, tak by to slo i ve startup metode.

public function startup()
{
    parent::startup();

    if ($this->view !== 'default') $this->error('Only default actions are allowed');
}

Hledani sablon se da upravit v metode formatTemplateFiles.

public function formatTemplateFiles()
{
    $presenterReflection = new ReflectionClass(static::class);
    $presenterDir = dirname($presenterReflection->getFileName());

    return [
        $presenterDir . '/templates/' . $this->view . '.latte',
        $presenterDir . '/' . $this->view . '.latte',
    ];
}

To bude hledat default.latte primo u presenteru nebo ve slozce templates. V beforeRender bych to osobne neresil, to uz muze byt nekdy pozde.

Ukazky na API schvalne odkazuji na Nette 2.4, protoze tam je jeste pouzity Apigen.

Marek Znojil
Člen | 28
+
0
-

CZechBoY napsal(a):

K tem routam: klidne muzes mit product module a v nem presentery add dle libosti.

Také mě to napadlo, ale chtěl bych se pokusit dodržet pouze Front a Admin module + Base, kde mám třeba error presenter, výchozí šablony i presentery.

V tomto případě by to mohlo nabobtnat, ale i tak, zajímavá myšlenka.

Felix:

Jestli by jsi chtel misto actionDefault treba jenom action nebo jenom default, tak by stacilo prepsat metody formatActionMethod a formatRenderMethod.

Hmm, to mě nenapadlo, vyzkouším.

Hledani sablon se da upravit v metode formatTemplateFiles.

Ano, původně jsem to takto zamýšlel, ale chtěl jsem obejít https://api.nette.org/…ter.php.html#456 a natvrdo přímo poslat šablonu.

V beforeRender bych to osobne neresil, to uz muze byt nekdy pozde.

V jaké situaci by to mohlo třeba nastat?