Nekonečná routa pro kategorie

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
batko
Člen | 219
+
0
-

Ahoj,

snažím se docílit napsání nekonečného routeru pro kategorie… Ale bohužel mi to vůbec nefunguje.

Nette routu vůbec nebere v potaz.

example.com/categorie/sport/hokej/helmy

<?php

    $frontRouter[] = new Route('kategorie/<node>', array(
        "id" => array(
            Route::FILTER_OUT => function ($node) use ($container) {
        //vrací URL
    },
            Route::FILTER_IN => function ($node) use ($container) {
         //vrací ID
    },
        ),
        "presenter" => "Category",
        "action" => "detail",
    ));

?>
enumag
Člen | 2118
+
0
-

Myslím že by to mělo být <node .+>. Nette jinak v $node neumožní lomítko.

batko
Člen | 219
+
0
-

enumag napsal(a):

Myslím že by to mělo být <node .+>. Nette jinak v $node neumožní lomítko.

<?php

 $frontRouter[] = new Route('kategorie/<node .+>', array(
        "node" => array(
            Route::FILTER_OUT => function ($node) use ($container) {

        $data = $container->categoryRepository->findBy(array("id" => $node))->fetch();
        return $data["url"];
    },
            Route::FILTER_IN => function ($node) use ($container) {
        dump($node);
        $data = $container->categoryRepository->findBy(array("url" => $node))->fetch();
        return $data["id"];
    }
        ),
        "presenter" => "Category",
        "action" => "detail",
    ));

?>

Bohužel, to routu stále ignoruje

enumag
Člen | 2118
+
0
-

No v té url máš „categorie“ a v routě „kategorie“…

batko
Člen | 219
+
0
-

enumag napsal(a):

No v té url máš „categorie“ a v routě „kategorie“…

to přeci nevadí…

url je kategorie/…

ale jde to na presenter Category

bazo
Člen | 620
+
0
-

ale vadi, to kategorie je tam napevno. zmen si v url categorie za kategorie

batko
Člen | 219
+
0
-

asi se nechápeme, můžete mi prosím prozradit jakou částkodu upravit?

děkuji

<?php

    $frontRouter[] = new Route('kategorie/<node .+>', array(
        "presenter" => "Category",
        "action" => "detail",
        "node" => array(
            Route::FILTER_OUT => function ($node) use ($container) {
                // dump($node);
                $data = $container->categoryRepository->findBy(array("id" => $node))->fetch();

                return $data["url"];
            },
            Route::FILTER_IN => function ($node) use ($container) {
                //   dump($node);
                $data = $container->categoryRepository->findBy(array("url" => $node))->fetch();

                return $data["id"];
            }
        ),
    ));

?>
Twista
Člen | 48
+
0
-

v případě, že máš url jak jsi psal v prvním příspěvku
example.com/categorie/sport/hokej/helmy

pak ti routa, která má masku
kategorie/<node .+>‘

nikdy nemůže matchnout

batko
Člen | 219
+
0
-

Twista napsal(a):

v případě, že máš url jak jsi psal v prvním příspěvku
example.com/categorie/sport/hokej/helmy

pak ti routa, která má masku
kategorie/<node .+>‘

nikdy nemůže matchnout

ne tohle mám správně

kategorie/

ale spíše mi nefunguje ten node, mám tam <node .+> a to taky nejde…

možná to mám špatně řešené, poradí někdo?

děkuji moc

Editoval batko (29. 10. 2013 16:08)

frosty22
Člen | 373
+
0
-

A generují se ti odkazy korektně, případně pokud máš v debugbaru ten tab s routy, tak zda-li tam tuhle masku vidíš? Já tedy jen zda-li máš tu routu správně připojenou.

Případně na debugování tedy rout přes debugbar by mělo stačit (ale nvm od jaké verze nette) přidat do konfigu:

<?php
	nette:
		routing:
			debugger: true
?>

A potom se podívat do toho debuggeru, zda-li v tom výpisu rout se nematchne nějaká nad ní, případně zda-li tam vůbec je.

Editoval frosty22 (29. 10. 2013 16:43)

batko
Člen | 219
+
0
-

Routa připojena je. V debugbaru ji normálně vidím, ale vezme to tu klasickou obecnou která je pod ní.

Já si myslím, že pes bude zakopán v použitíí <node .+> ale bohužel nevím kde přesně.

kategorie/<node .+>
<presenter>/<action>[/<id>]

japlavaren
Člen | 404
+
0
-

skus kategorie[/<node…>]

batko
Člen | 219
+
0
-

To bohužel nic neřeší.

batko
Člen | 219
+
0
-

tak mi to nedalo a zde je fungující výsledek

<?php
  $frontRouter[] = new Route('kategorie/<id .*>', array(
        "id" => array(
            Route::FILTER_OUT => function ($id) use ($container) {
        $url = NULL;

        $x = $container->categoryRepository->findBy(array("id" => $id))->fetch();
        $url = $x["url"];

        if ($x["parent"] != NULL) {
            do {
                $x = $container->categoryRepository->findBy(array("id" => $x["parent"]))->fetch();
                $url = $x["url"] . "/" . $url;
            } while ($x["parent"] != NULL);
        }

        return $url;
    },
            Route::FILTER_IN => function ($id) use ($container) {
        $arr = explode("/", $id);
        $id = end($arr);

        $data = $container->categoryRepository->findBy(array("url" => $id))->fetch();

        return $data["id"];
    }
        ),
        "presenter" => "Category",
        "action" => "detail",
    ));
?>
enumag
Člen | 2118
+
0
-

@batko:

Aha, takže celý problém byl zřejmě v tom že ten parametr se v presenteru nejmenoval $node ale $id.

Mimochodem schválně si vyzkoušej co ti to udělá když id v databázi nebude. Pokud se nemýlím tak fetch ti vrátí FALSE a $data["id"] nebude definováno, což ti způsobí nepěknou chybu.

batko
Člen | 219
+
0
-

enumag napsal(a):

@batko:

Aha, takže celý problém byl zřejmě v tom že ten parametr se v presenteru nejmenoval $node ale $id.

Mimochodem schválně si vyzkoušej co ti to udělá když id v databázi nebude. Pokud se nemýlím tak fetch ti vrátí FALSE a $data["id"] nebude definováno, což ti způsobí nepěknou chybu.

Pravdu máš. Klasická věc které jsem si nevšiml.

Jak by si to ošetřil to id?

enumag
Člen | 2118
+
0
-
return $data ? $data["id"] : NULL;

Vrácení NULL z filtru způsobí že routa nematchne.

batko
Člen | 219
+
0
-

Děkuji za rady…

Casper
Člen | 253
+
0
-

Mít v routě v callbacku Route::FILTER_OUT nějaké dotazování do databáze je dost nevhodné (A ještě k tomu v cyklu!). Za každý link, který na stránce vytvoříš se budeš [několikrát] dotazovat do databáze. A u kategorií docela předpokládám, že asi nebudeš vypisovat jednu, ale celou sadu.

Doporučuji nějaké cachování – tedy callbackem volat metody nějaké třídy, která si uvnitř sebe bude držet hodnoty z databáze (buď opravdu cachované nebo získané jen pro daný request).

batko
Člen | 219
+
0
-

Tohle zkusím dnes vyřešit, mě zde spíše šlo o funkcionalitu té routy. Ono je to na tu DB dosti náročné to vím.

Děkuji za upozornění. Až to budu řešit tak dám výsledek…

Jan Suchánek
Člen | 404
+
0
-

@batko: Budeš dělat i cachování? Jsem zvědav zda to budem mít podobné.

Editoval jenicek (30. 10. 2013 15:45)

batko
Člen | 219
+
0
-

jenicek napsal(a):

@batko: Budeš dělat i cachování? Jsem zvědav zda to budem mít podobné.

Rád bych :-) ale musít to lehce nastudovat :-) vecer na to vletim…Tak pak hodime vysledky