Diskuze – Lekce 6 - Jednoduchý redakční systém v Nette - Výpis článku
ZpětUpozorňujeme, že diskuze pod našimi online kurzy jsou nemoderované a primárně slouží k získávání zpětné vazby pro budoucí vylepšení kurzů. Pro studenty našich rekvalifikačních kurzů nabízíme možnost přímého kontaktu s lektory a studijním referentem pro osobní konzultace a podporu v rámci jejich studia. Toto je exkluzivní služba, která zajišťuje kvalitní a cílenou pomoc v případě jakýchkoli dotazů nebo projektů.


Ahoj, mám problém nejspíše s routy v applikaci.
Administrace článků bezchybně funguje.
Úplně stejným způsobem chci udělat administraci referencí.
Udělal jsem stejně presenter, model i šablony, ale mám problém s napsáním
routy.
Přidal zdroje i oprávnění.
RouteFactory vypadá takto (VIZ NÍŽE):
po spuštění mi to vytvoří odkazy
<li><a n:href=":Core:Article:list">Seznam
článků</a></li>
<li><a n:href=":Core:Reference:list">Seznam
referencí</a></li>
odkazy:
http://localhost/…znam-clanku/
http://localhost/…m-referenci/
po kliknutí na Seznam referencí se mi stránka přesměruje na chybovou stránku s textem stránka nebyla nalezena, na kterou je applikace přesměrována, když je odkazneexistující.
Podle tracy neexistuje url pro seznam referencí
.Myslím si, že problém je v těch routách, ale nevim, jak je mám
upravit.
Podle všeho se to přesměruje na výpis článků, kde hledá v databázi
stránku výpis referencí.
- Může to být tím, že prezenter i model je duplikován jen přejmenován a upraven na reference?
I funkce se jmenujou stejně.
Prosím o radu, jak tuto applikaci opravit a zprovoznit
class RouterFactory
{
/**
* Vytváří router pro aplikaci.
* @return RouteList výsledný router pro aplikaci
*/
public static function createRouter()
{
$router = new RouteList();
$router[] = new Route('kontakt/', 'Core:Contact:default');
$router[] = new Route('<action>/', array(
'presenter' => 'Core:Administration',
'action' => array(
// řetězec v URL => akce presenteru
Route::FILTER_TABLE => array(
'administrace' => 'default',
'prihlaseni' => 'login',
'odhlasit' => 'logout',
'registrace' => 'register'
),
Route::FILTER_STRICT => true
)
));
$router[] = new Route('[<action>/][<url>]', array(
'presenter' => 'Core:Article',
'action' => array(
Route::VALUE => 'default',
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-clanku' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
$router[] = new Route('[<url>]', 'Core:Article:default');
$router[] = new Route('[<action>/][<url>]', array(
'presenter' => 'Core:Reference',
'action' => array(
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-referenci' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
return $router;
}
}
Děkuji za jakoukoli pomoc, jelikož jsem z toho už zoufalý. Pročítal jsem dokumentace i příklady a známí co mají app v nette routy niak neupravují a aplikace jim běží.
Jindřich Máca:9.10.2016 22:47
Zdravím,
v uvedeném routeru rozhodně vidím chybu, která s největší pravděpodobností způsobuje popsané chování. Jedná se o řádek
$router[] = new Route('[<url>]', 'Core:Article:default');
, který musí rozhodně být až na konci routeru, neboť "spolkne" jakoukoliv URL.
Pro bližší vysvětlení, router funguje tak, že testuje danou URL vůči vzoru a je použita první odpovídající routa v pořadí. Jelikož ale vzor [<url>] odpovídá jakékoliv URL, router se vždy zastaví zde a spustí vyhledávání článku s danou URL. To ale v tomto případě nebyl záměr, čili takový článek neexistuje, a proto nastává již zmíněná chyba.
Z předchozího již logicky vyplývá, že jakákoliv následující routa po tomto vzoru nikdy nemůže být použita. Řešení je tedy přesunout tento nejobecnější vzor na konec routeru.
Doufám, že jsem to dostatečně objasnil, případně očekávám další dotazy nebo doporučuji přečíst komentáře u tohoto článku od začátku, protože zrovna routování se zde již jednou řešilo...
danhosek:10.10.2016 14:40
Díky moc. Je to logické a hloupé si toho nevšimnout.
Nyní mi nastal problém, stím, že reference nelze editovat, odstraňovat ani
vytvářet po kluknutí na odkazy
<h2><a n:href=":Core:Reference:editor">Nová
reference</a></h2>
<a n:href=":Core:Reference:editor
$reference->url">Editovat</a>
<a n:href=":Core:Reference:remove $reference->url">Odstranit
referenci</a>
jsem přesměrován na administraci článků.
Odzkoušel jsem, že záleží na pořadí rout v RouterFactory, který
momentálně vypadá takto:
public static function createRouter()
{
$router = new RouteList();
$router[] = new Route('kontakt/', 'Core:Contact:default');
$router[] = new Route('<action>/', array(
'presenter' => 'Core:Administration',
'action' => array(
// řetězec v URL => akce presenteru
Route::FILTER_TABLE => array(
'administrace' => 'default',
'prihlaseni' => 'login',
'odhlasit' => 'logout',
'registrace' => 'register'
),
Route::FILTER_STRICT => true
)
));
$router[] = new Route('[<action>/][<url>]', array(
'presenter' => 'Core:Article',
'action' => array(
Route::VALUE => 'default',
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-clanku' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
$router[] = new Route('[<action>/][<url>]', array(
'presenter' => 'Core:Reference',
'action' => array(
Route::VALUE => 'default',
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-referenci' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
$router[] = new Route('[<url>]', 'Core:Reference:default');
$router[] = new Route('[<url>]', 'Core:Reference:default');
return $router;
}
Jak to mám odlišit?
Napadlo mě řešení, že pro article zůstane editor a pro reference např:
editor_ref
ale nevím, kde všude to bude potřeba upravit. (routa,funkce v
referencepresenter, název šablony v templates/reference)
Jindřich Máca:10.10.2016 17:17
Není zač.
V aktuálním kódu routeru máš na konci další chybu:
$router[] = new Route('[<url>]', 'Core:Reference:default');
$router[] = new Route('[<url>]', 'Core:Reference:default');
Tohle je přeci to samé, jedno mělo pravděpodobně být:
$router[] = new Route('[<url>]', 'Core:Article:default');
Pozn.: To je naneštěstí taky špatně, viz. dále.
To ale není ten problém. Hlavní chyba je v tom, uvědomit si, že routování je dvousměrná záležitost. Zase se to pokusím trochu objasnit:
- V první fázi, při generování stránky, se Ti odkaz :Core:Reference:editor překládá na URL. Předpokládejme, že je to např. http://localhost/…ette/editor/. Zde vše proběhne v pořádku a podle očekávání.
- V dalším kroku, klikneme na odkaz a router má rozhodnout, co se vykoná podle dané URL. Zde ale nastává onen problém. V návaznosti na můj předchozí komentář bude první shoda v pořadí na následující akci, která se pak také provede:
$router[] = new Route('[<action>/][<url>]', array(
'presenter' => 'Core:Article',
'action' => array(
Route::VALUE => 'default',
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-clanku' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
Z předchozího jasně vyplývá, že je potřeba generování URL explicitně rozlišit. Přeci jen webová adresa má být unikátní identifikátor dané akce. Tohoto se dá poměrně jednoduše docílit pouhou úpravou pravidel v routeru. Klidně můžeš aplikovat svoje řešení a editor referencí odlišit pomocí např. editor_ref.
Nesmíš ale zapomenout na to, že takhle je potřeba odlišit
všechny adresy, které mají duplicitní výstupy s akcemi článků.
danhosek:10.10.2016 22:32
Upravil jsem odkazy na editor_ref
<a n:href=":Core:Reference:editor_ref $reference->url">Editovat</a>
<a n:href=":Core:Reference:remove_ref $reference->url">Odstranit referenci</a>
a routy:
public static function createRouter()
{
$router = new RouteList();
$router[] = new Route('kontakt/', 'Core:Contact:default');
$router[] = new Route('<action>/', array(
'presenter' => 'Core:Administration',
'action' => array(
// řetězec v URL => akce presenteru
Route::FILTER_TABLE => array(
'administrace' => 'default',
'prihlaseni' => 'login',
'odhlasit' => 'logout',
'registrace' => 'register'
),
Route::FILTER_STRICT => true
)
));
$router[] = new Route('[<action>/][<url>]', array(
'presenter' => 'Core:Article',
'action' => array(
Route::VALUE => 'default',
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-clanku' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
$router[] = new Route('[<action>/][<url>]', array(
'presenter' => 'Core:Reference',
'action' => array(
Route::VALUE => 'default',
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-referenci' => 'list',
'editor_ref' => 'editor',
'odstranit_ref' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
$router[] = new Route('[<url>]', 'Core:Reference:default');
$router[] = new Route('[<url>]', 'Core:Article:default');
return $router;
}
ale nyní výpis referencí hlásí:
Invalid link: Unable to pass parameters to action 'Core:Reference:editor_ref',
missing corresponding method.
stačí pozměnit pouze routu, nebo musím přejmenovat celou funkci
editor?
A dále ještě musím odlišit poslední nejobecnější routy, ale nemám
žádný nápad. dal bych před nebo za url reference např. _ , ale nedaří se
mi to applikovat.
Jindřich Máca:10.10.2016 22:52
Špatně jsi mě pochopil... Já jsem to myslel tak, že přímo do toho vzoru doplníš to _ref, aby se to tak automaticky překládalo. Asi nějak takto:
$router[] = new Route('<action>_ref/[<url>]', array(
'presenter' => 'Core:Reference',
'action' => array(
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-clanku' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
Tohle řešení by mělo fungovat právě jenom s touto drobnou změnou v
routeru.
P.S.: U toho Tvého by jsi musel opravdu přejmenovat i ty funkce.
danhosek:11.10.2016 0:21
upravil jsem na
$router[] = new Route('<action>_ref/[<url>]', array(
'presenter' => 'Core:Reference',
'action' => array(
Route::VALUE => 'default',
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
ale nevím, jak udělat ten odkaz správně. Odzkoušel jsem spoustu
možností.
mapř
<a n:href=":Core:Reference:editor _ref
$reference->url">Editovat</a>
Pro vypis-referenci jsem udělal routu zvlast a po uspěšném vyzkoušení
bych je sloučil.
Ale mam problem s tím odkazem na editor z administrace vytvoří to odkaz
/ediror_ref/
ale asi to neveme ten _ref jako zvlast,aby to mohlo splnit tuto podmínku
$router[] = new Route('<action>_ref/[<url>]', array(
Jindřich Máca:11.10.2016 15:02
Opět jsi to špatně pochopil... Takže ještě jednou polopatě. Když máš toto původní pravidlo:
$router[] = new Route('[<action>/][<url>]', array(
'presenter' => 'Core:Reference',
'action' => array(
Route::VALUE => 'default',
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-clanku' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
, tak se odkazy interpretují takto:
:Core:Reference:editor -> http://localhost/eshop-nette/editor/
Když změníš pravidlo na:
$router[] = new Route('<action>_ref/[<url>]', array(
'presenter' => 'Core:Reference',
'action' => array(
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-clanku' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
, tak se odkazy automaticky začnou interpretovat takto:
:Core:Reference:editor -> http://localhost/eshop-nette/editor_ref/
Není potřeba měnit nic dalšího.
Už je to jasné?
danhosek:11.10.2016 15:24
mysli, že jsem přesně toto zkoušel, ale po kliknutí najakýkoliv odkaz
mimo úvod , kontakt a výpis článků je nefunkční včetně editace
článků a referencí :
Stránka localhost nefunguje
Web localhost vás přesměroval příliš mnohokrát.
Zkuste vymazat soubory cookie.
ERR_TOO_MANY_REDIRECTS
zkusil jsem i upravit na
$router[] = new Route('[<action>]_ref/[<url>]', array(
a všechny odkazy referencí jsou směrovány na stránka nebyla nalezena
$router[] = new Route('[<action>/][<url>]', array(
'presenter' => 'Core:Article',
'action' => array(
Route::VALUE => 'default',
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-clanku' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
$router[] = new Route('<action>_ref/[<url>]', array(
'presenter' => 'Core:Reference',
'action' => array(
Route::VALUE => 'default',
Route::FILTER_TABLE => array(
// řetězec v URL => akce presenteru
'seznam-referenci' => 'list',
'editor' => 'editor',
'odstranit' => 'remove'
),
Route::FILTER_STRICT => true
),
'url' => null,
));
Zobrazeno 10 zpráv z 105.