Routing – zjednodušení route a překlad definovaných na základní URL

Hedgexu
Člen | 12
+
0
-

Snažím se zprovoznit routování.

<?php

class RouterFactory
{
	use Nette\StaticClass;

	public static function createRouter()
	{


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

		$router[] = new Route('profile/<profileId>', 'Profile:show');
		$router[] = new Route('profile/<profileId>/edit', 'Profile:edit');
		...

		$router[] = new Route('service/<serviceId>', 'Service:show');
		$router[] = new Route('service/new', 'Service:create');
		$router[] = new Route('service/<serviceId>/edit', 'Service:edit');
		...

		$router[] = new Route('reservation/<reservationId>', 'Reservation:show');
		$router[] = new Route('reservation/new', 'Reservation:create');
		$router[] = new Route('reservation/<reservationId>/edit', 'Reservation:edit');
		...

		return $router;
	}

}
?>

Takže bych měl 2 dotazy.

  1. Je možné napsat uvedené routy i nějak inteligentněji? V současné době mám route pro každou akci presenteru (kromě default).
  2. Aplikace preferuje odkazy v defaultním formátu. Například do adresního řádku napíšu ./www/profile/3/edit a adresa se přeloží na ./www/profile/edit?profileId=3, nicméně můj cíl je aby adresa zůstala jak jsem jí zadal. Podobný problém je i u automaticky generovaných odkazů. Generují také variantu ../www/profile/edit?profileId=3 a můj cíl je ./www/profile/3/edit. Jak na to?

Pokud mi unikla nějaká zásadní informace o dané problematice tak se omlouvám.

Editoval Hedgexu (8. 5. 2017 19:28)

Hedgexu
Člen | 12
+
0
-

Bod 2. FIXED

Stačílo přehodit následující route na konec

<?php
$router[] = new Route('<presenter>/<action>', 'Homepage:default');
?>
David Matějka
Moderator | 6445
+
0
-

1. vzhledem k rozdilne pojmenovanym ID parametrum by to bylo slozitejsi (ale taky by to slo). v pripadne, ze by to vsude bylo jen id, tak by to mohlo vypadat treba takhle:

$router[] = new Route('<presenter>/<id>', ['action' => 'show']);
$router[] = new Route('<presenter>/new', ['action' => 'create']);
$router[] = new Route('<presenter>/<id>/edit', ['action' => 'create']);

pokud bys chtel zachovat serviceId apod., tak by to slo pres globalni filtry
2. viz doc

Je důležité, v jakém pořadí jsou routy definovány, protože se zkouší postupně odshora dolů. Platí pravidlo, že routy deklarujeme od specifických po obecné.

Jan Mikeš
Člen | 771
+
0
-

Ahoj, odpověď na tvou 2. otázku je přesunout definici $router[] = new Route('<presenter>/<action>', 'Homepage:default'); až nakonec, routy se definují od konkrétních po obecné s tím, že ty dříve nadefinované jsou upředňostnovány.

1. napadá mě, že by se to dalo sloučit podle typu (nelze jednoduše napsat routu společnou pro všechny, protože máš vždy jiný název parametru). Pokud by jsi zvolil společný parametr, např. id pak by to vypadalo takto

		$router[] = new Route('<presenter=Reservation>/[<id [0-9+]>/][<action=show>]', [
			'action' => [
				Route::FILTER_TABLE => [
					'new' => 'create'
				],
			],
		]);

S trochou hackování by to šlo i s různými názvy parametrů, s tím se mi popravdě ale teď nechce hrát :-). S použitím tohoto kódu se ti podaří alespoň dát 3 routy do jedné:

	private function createMyRoute(string $presenterName): Route
	{
		$presenter = strtolower($presenterName);
		$parameterName = $presenter . 'Id';

		return new Route("$presenter/[<$parameterName [0-9]+>/][<action=show>]", [
			'presenter' => $presenterName,
			'action' => [
				Route::FILTER_TABLE => [
					'new' => 'create'
				],
			],
		]);
	}

	///
	$router[] = $this->createMyRoute('Reservation');
	$router[] = $this->createMyRoute('Service');

Editoval Jan Mikeš (8. 5. 2017 20:04)

Hedgexu
Člen | 12
+
0
-

Funkční verze po nahrazení $profileId, $serviceId a $reservationId za $id

<?php

$router = new RouteList;

$router[] = new Route('<presenter>/new', ['action' => 'create']);
$router[] = new Route('<presenter>/<id>', ['action' => 'show']);
$router[] = new Route('<presenter>/<id>/edit', ['action' => 'edit']);
$router[] = new Route('<presenter>/<id>/newservice', ['action' => 'addadministration']);
$router[] = new Route('<presenter>/<id>/newmanager', ['action' => 'addadmin']);
$router[] = new Route('<presenter>/<id>/type', ['action' => 'changetype']);
$router[] = new Route('<presenter>/<id>/delete', ['action' => 'delete']);
$router[] = new Route('<presenter>/<serviceId>/removemanager/<profileId>', ['action' => 'removeadmin']);
$router[] = new Route('<presenter>/<id>/cancle', ['action' => 'cancle']);
$router[] = new Route('<presenter>/<id>/close', ['action' => 'close']);
$router[] = new Route('<presenter>/<id>/state', ['action' => 'editState']);

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

?>

create muselo být první protože jinak se dávalo id new :D

Stále platí, že pro každou akci mám vlastní routu, ale to není takový problém.

Děkuji za rychlou odpověď

EDIT: Bylo by možné napsat všechny události nějak jednotně u sebe když je to tak podobné?

Editoval Hedgexu (8. 5. 2017 20:30)

CZechBoY
Člen | 3608
+
0
-

No můžeš to sloučit tak, že použiješ <action> místo těch názvů.

$router[] = new Route('<presenter>/new', ['action' => 'create']);
$router[] = new Route('<presenter>/<id>/<action>');
$router[] = new Route('<presenter>/<id>', ['action' => 'show']);

Kdybys sloučit i názvy akcí s url tak ti stačí tyto 3. Jinak můžeš udělat v presenteru forward, ale to je celkem hnus.

Editoval CZechBoY (8. 5. 2017 21:01)

Jan Mikeš
Člen | 771
+
0
-

@Hedgexu proč? Přečti so mojí odpověď. Díky <id [0-9+]> dokážeš vše sloučit do jedné routy, minimálně stejného presenteru.

Navíc všechny ty routy co jsi napsal nahoře jdou napsat jednou routou, pomocí FILTER_TABLE

Editoval Jan Mikeš (8. 5. 2017 21:10)

Hedgexu
Člen | 12
+
0
-

@JanMikeš když jsem to viděl prvně byla to pro mě trošku vyšší dívčí než jsem to pochopil

Co říkáte co tuto verzi? Vše sloučené do 5 + 1 a podporují i jazykové mutace

<?php
$router[] = new Route('[<lang [a-z]{2}>/]sign/<action>', ['presenter' => 'Sign', 'lang' => 'en']);
$router[] = new Route('[<lang [a-z]{2}>/]<presenter>', ['action' => 'default', 'lang' => 'en']);
$router[] = new Route('[<lang [a-z]{2}>/]<presenter>/new', ['action' => 'create', 'lang' => 'en']);
$router[] = new Route('[<lang [a-z]{2}>/]<presenter>/<id>/<action>', ['action' => 'show', 'lang' => 'en']);
$router[] = new Route('[<lang [a-z]{2}>/]<presenter>/<serviceId>/removemanager/<profileId>', ['action' => 'removeadmin', 'lang' => 'en']);
$router[] = new Route('<presenter>/<action>', 'Homepage:default')
?>