Picture

Zdravím, jmenuji se Emil Cieslar.

Jsem programátor se zaměřením na frontend pomocí AngularJS. Backend mi také není cizí, na něj používám Nette (občas NodeJS). Stále se učím nové věci, které rád sdílím s ostatními. Žiji svým vlastním tempem ve společnosti Webkreativ, s.r.o., která má stejné zaměření jako já.

Více o mne →

 (Emil & Web)

Nette web s moduly

Jak nastavit nette aplikaci, aby měla moduly pro běžného uživatele a pro admina

  • Nette
  • PHP

Při svých začátcích v Nette jsem nemohl najít článek o tom, jak postavit nette aplikaci na modulech pro běžného uživatele a pro administrátora, který by nebyl tzv. ‘out of date’, jednoduše řečeno starý. Proto jsem se rozhodl napsat jednoduchý návod, jak začít.

Nette moduly

Hezký, ale až moc zjednodušený přehled o modulech nabízí přímo dokumentace nette, ale jednak mi tento úsek příjde trochu neaktualizovaný (např. složka templates už v nette 2.3 je standardně součástí presenters), druhak je až moc zjednodušený a všeobecný pro začátečníky, kteří nerozumí ještě úplně struktuře nette. Proto blíže nastíním, jak tyto moduly zprovoznit.

Struktura

Důležitá je adresářová struktura ve složce app:

├── AdminModule/
│   ├── presenters/
│   │   ├── templates/
│   │   ├── @layout.latte
├── FrontModule/
│   ├── presenters/
│   │   ├── templates/
│   │   ├── @layout.latte
...

Jednotlivé presentery v modulech

Na co je třeba dát velký pozor jsou namespacy jednotlivých presenterů v modulech. Co tím myslím? Tak kupříkladu takto by mohl vypadat ukázkový BasePresenter.php ve FrontModule:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

namespace FrontModule; // FrontModule !!!!!

use Nette;

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

  public function __construct()
  {

  }

}

Nejdůležitější je řádek 3, namespace FrontModule;. Tento řádek musí být v KAŽDÉM presenteru ve FrontModulu. Možná už tušíte, že naopak v AdminModule tento řádek bude namespace AdminModule;. Na tyto detaily je třeba dát pozor, protože jinak vás bude bolet hlava z chyb, se kterými se setkáte.

Config

Dále nesmíme opomenout na application mapping v config souboru. Defaultně máme nastaveno následovně.

application:
	errorPresenter: Error
	mapping:
		*: App\*Module\Presenters\*Presenter

Config ale změníme takto:

application:
	errorPresenter: Error
	mapping:
		*: *Module\*Presenter

Touto malou, ale důležitou úpravou zajistíme, že se moduly budou správně načítat. Dejte pozor také na konfiguraci errorPresenter, který momentálně směřuje do slepé uličky vzhledem k tomu, že máme nakonfigurované moduly. Pokud chceme mít společný errorPresenter v jednom modulu (např. ve FrontModule), změníme konfiguraci následovně.

application:
	errorPresenter: Front:Error
	mapping:
		*: *Module\*Presenter

Na nette foru můžete nalézt i řešení errorPresenteru pro každý modul zvlášť, to už ale nechám na vás.

RouterFactory

Poslední věcí je routování. Abychom byli schopni nasměrovat uživatele na dané moduly (a jejich presentery), potřebujeme několik úprav v našich routách. Následující kód ukazuje, jak by naše routy mohly vypadat.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php

namespace App;

use Nette;
use Nette\Application\Routers\RouteList; // Nezapomeňte přidat RouteList!!!
use Nette\Application\Routers\Route;


class RouterFactory
{

	/**
	 * @return Nette\Application\IRouter
	 */
	public static function createRouter()
	{
		$router = new RouteList;

		$admin = new RouteList('Admin');
		$admin[] = new Route('admin/<presenter>/<action>[/<id>]', 'Homepage:default');

		$front = new RouteList('Front');
		$front[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');

		$router[] = $admin;
		$router[] = $front;

		$router[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');

		return $router;
	}

}

V podstatě si vytvoříme dvě různé RouteListy, jednu pro Admina a druhou pro Front (zákazníka) a pak je přidáme do routeru. Nakonec ještě přidáme tzv. fallback route, jinými slovy, kdyby nic neklaplo, tak to půjde do Homepage:default. Malý detail na dovysvětlenou, pomocí new RouteList(‘Admin’) specifikujeme název modulu. Takže module se musí jmenovat AdminModule, pokud ho chceme v RouterListu specifikovat jako Admin. Nemůžeme ho pojmenovat například ModuleAdmin nebo AdminM, prostě AdminModule. V začátcích jsem si totiž hrál s myšlenkou pojmenovávat moduly např. ModuleAdmin a ModuleFront, aby to hezky šlo v abecedě za sebou v adresářové struktuře, to byla ale zásadní chyba.

Bonus

Abych vám ušetřil čas, tak jsem připravil boilerplate (který naleznete na mém githubu) pro aplikaci s moduly. Je to ale spíše pro mé potřeby, takže to neušetří čas každému. Obsahuje totiž nejen nette, ale přidal jsem Foundation for Sites a AngularJS. Foundation mám rád, protože šetří hodně času. Na rozdíl od Bootstrapu je čistější a je i menší (a taky přístupěnější). Neobsahuje tolik stylů, takže se hodí spíše pro projekty, kdy nechcete přepisovat tisíc předdefinovaných stylů od bootstrapu, ale potřebujete nadesignovat web app podle svých představ od začátku. Stačí vytvořit nový projekt pomocí příkazu git clone:

git clone https://github.com/emilcieslar/nette-and-foundation-for-sites.git

Reference

  1. Nette dokumentace
  2. Jak na nette s funkčními moduly
  3. Nette forum

Komentáře