{"size": 12580, "ext": "js", "max_stars_repo_path": "pages/p/routovani-v-nette-prakticky.js", "max_stars_repo_name": "mrtnzlml/zlml.cz", "max_stars_repo_stars_event_min_datetime": "2015-12-31T15:08:42.000Z", "max_stars_repo_stars_event_max_datetime": "2018-03-06T14:21:38.000Z", "max_issues_repo_path": "pages/p/routovani-v-nette-prakticky.js", "max_issues_repo_name": "mrtnzlml-archive/zlml.cz", "max_issues_repo_issues_event_min_datetime": "2015-12-08T15:14:47.000Z", "max_issues_repo_issues_event_max_datetime": "2018-07-29T08:20:27.000Z", "max_forks_repo_path": "pages/p/routovani-v-nette-prakticky.js", "max_forks_repo_name": "mrtnzlml/zlml.cz", "max_forks_repo_forks_event_min_datetime": "2016-03-23T00:19:09.000Z", "max_forks_repo_forks_event_max_datetime": "2018-03-06T14:20:20.000Z"}
{"max_stars_count": 17, "max_issues_count": 29, "max_forks_count": 7, "avg_line_length": 967.6923076923, "max_line_length": 12345, "alphanum_fraction": 0.6873608903}
// @flow

import WithPost from '../../components/WithPost';

export default WithPost({
  "attributes": {
    "timestamp": 1375611559000,
    "title": "Routování v Nette - prakticky",
    "slug": "routovani-v-nette-prakticky"
  },
  "body": "<div class=\"alert alert-success\">Tento článek byl naposledy revidován, aktualizován a rozšířen <strong>27. června 2014</strong>...</div>\n\n<p>V následujícím článku se budu opírat o teorii napsanou v <a href=\"http://doc.nette.org/cs/routing\">dokumentaci</a>.\nJelikož jsem se však Nette učil sám, tak vím jak je těžké routování pochopit\na zvlášť potom z dokumentace, která spíše ukazuje fičury, než jak na to. A vzhledem k tomu, že mi\npod rukama prošlo velké množství velmi různorodých aplikací, kád bych zde uvedl příklady\nadresářové struktury, rout pro daný praktický problém a vzniklé URL adresy.\nZačíná přehlídka několika možných rout. Myslím si, že celá řada příkladů bude užitečnější, než teorie.</p>\n<p>Základ všeho je porozumět tomu, jak se v Nette vytváří <a href=\"http://doc.nette.org/cs/presenters#toc-vytvareni-odkazu\">odkazy</a>.\nOd toho se velmi podobně sestavují obecné routy tak, aby alespoň jedna seděla svým tvarem na daný odkaz.</p>\n<h2 id=\"prvn-kroky\">První kroky <a href=\"#prvn-kroky\">#</a></h2><p>Začněme jednoduchou statickou stránkou, která má tuto jednoduchou adresářovou strukturu:</p>\n<pre><code class=\"hljs\">app/\n├─── config/\n├─── model/\n├─── presenters/\n│     └── HomepagePresenter.php\n│\n├─── router/\n├─── templates/\n│     ├── Homepage/\n│     │    ├── kontakt.latte   (zde jednotlivé stránky statického webu)\n│     │    └── ...\n│     └── @layout.latte\n│\n└─── bootstrap.php\n</code></pre><p>To znamená, že ne každou stránku se budu odkazovat přibližně jako <code>Homepage:kontakt</code>. Samozřejmě \nvždy se záměnou šablony (v tomto případě kontakt - kontakt.latte). To je dost triviální a stačilo by například:</p>\n<pre><code class=\"hljs lang-php\">$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'&lt;presenter&gt;/&lt;action&gt;[/&lt;id&gt;]'</span>, <span class=\"hljs-string\">'Homepage:default'</span>);\n</code></pre>\n<p>To je sice funkční, bohužel je to spíše teoretická routa, protože výsledek je otřesný:</p>\n<pre><code class=\"hljs\">http://zlml.cz/homepage/kontakt\n</code></pre><p>Tuto routu píšu téměř všude. Je to routa velmi obecná a říká přibližně následující:\nBude-li se někdo odkazovat v obecném tvaru <code>Presenter:view</code>, pochop <code>Presenter</code> jako název presenteru (např. <strong>Homepage</strong>Presenter) a hledej tedy soubor <code>HomepagePresenter.php</code>\na <code>view</code> bude šablona presenteru, hledej ji tedy ve složce <code>Presenter/view.latte</code> a sestav URL která bude přesně v tomto tvaru.\nHomepage:default pouze říká co je výchozí hodnota a co se má hledat, pokud nebude specifikována konkrétní šablona.</p>\n<p>Pro takto malý web je mnohem lepší specifikovat konkrétnější routu, která přijde <strong>před</strong> onu obecnou:</p>\n<pre><code class=\"hljs lang-php\">$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'&lt;action&gt;'</span>, <span class=\"hljs-string\">'Homepage:default'</span>);\n</code></pre>\n<p>Což udělá téměř to samé, jen vypustí z URL nadbytečnou informaci o presenteru. Vždy používáme HomepagePresenter, jen\nse mění cílová šablona podle URL:</p>\n<pre><code class=\"hljs\">http://zlml.cz/kontakt\n</code></pre><p>Výsledná sada rout pro takovouto malou statickou stránku by tedy mohla vypadat takto:</p>\n<pre><code class=\"hljs lang-php\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> <span class=\"hljs-title\">createRouter</span><span class=\"hljs-params\">()</span> </span>{\n    $router = <span class=\"hljs-keyword\">new</span> RouteList();\n    $router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'&lt;action&gt;'</span>, <span class=\"hljs-string\">'Homepage:default'</span>);\n    $router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'&lt;presenter&gt;/&lt;action&gt;[/&lt;id&gt;]'</span>, <span class=\"hljs-string\">'Homepage:default'</span>);\n    <span class=\"hljs-keyword\">return</span> $router;\n}\n</code></pre>\n<p>Dále je vhodné používat např. soubor <code>sitemap.xml</code>. Pokud ho také umístím do stejného adresáře jako šablony, routa je opět jednoduchá:</p>\n<pre><code class=\"hljs lang-php\">$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'sitemap.xml'</span>, <span class=\"hljs-string\">'Homepage:sitemap'</span>);\n</code></pre>\n<p>Hledá se šablona <code>sitemap.latte</code>. Přečtěte si jak vytvořit tuto šablonu v článku <a href=\"rss-a-sitemap-jednoduse-a-rychle\">RSS a Sitemap jednoduše a rychle</a>. Výsledná URL je tak jak má být:</p>\n<pre><code class=\"hljs\">http://zlml.cz/sitemap.xml\n</code></pre><p>To samé lze udělal pro RSS.</p>\n<h2 id=\"jdeme-do-hloubky\">Jdeme do hloubky <a href=\"#jdeme-do-hloubky\">#</a></h2><p>Trošku složitější routování přichází vždy když chcete udělat něco speciálního.\nNapříklad to, aby číslo za URL udávalo číslo stránky v paginatoru:</p>\n<pre><code class=\"hljs\">http://zlml.cz/2\n</code></pre><pre><code class=\"hljs lang-php\">$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">\"[&lt;paginator-page [1](2)&gt;]\"</span>, <span class=\"hljs-keyword\">array</span>(\n    <span class=\"hljs-string\">'presenter'</span> =&gt; <span class=\"hljs-string\">'Homepage'</span>,\n    <span class=\"hljs-string\">'action'</span> =&gt; <span class=\"hljs-string\">'default'</span>,\n    <span class=\"hljs-string\">'paginator-page'</span> =&gt; <span class=\"hljs-number\">1</span>\n));\n</code></pre>\n<p>Zde už je nutné druhý parametr rozepsat a více specifikovat. Toto akceptuje pouze konkrétní čísla.\na jako druhou specialitu lze napsat takovou routu, která bude tvořit URL z názvů článků:</p>\n<pre><code class=\"hljs\">http://zlml.cz/using-fulltext-searching-with-innodb\n</code></pre><pre><code class=\"hljs lang-php\">$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'&lt;id&gt;'</span>, <span class=\"hljs-keyword\">array</span>(\n    <span class=\"hljs-string\">'presenter'</span> =&gt; <span class=\"hljs-string\">'Single'</span>,\n    <span class=\"hljs-string\">'action'</span> =&gt; <span class=\"hljs-string\">'article'</span>,\n    <span class=\"hljs-string\">'id'</span> =&gt; <span class=\"hljs-keyword\">array</span>(\n        Route::FILTER_IN =&gt; <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> <span class=\"hljs-params\">($url)</span> </span>{\n            <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">$this</span>-&gt;posts-&gt;getIdByUrl($url);\n        },\n        Route::FILTER_OUT =&gt; <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> <span class=\"hljs-params\">($id)</span> </span>{\n            <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">$this</span>-&gt;posts-&gt;getUrlById($id);\n        },\n    ),\n));\n</code></pre>\n<p>A není úplně na škodu vytvořit routu, která bude řešit napríklad vyhledávání:</p>\n<pre><code class=\"hljs\">http://zlml.cz/search/fio%20api\n</code></pre><pre><code class=\"hljs lang-php\">$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'search[/&lt;search&gt;]'</span>, <span class=\"hljs-string\">'Search:default'</span>);\n</code></pre>\n<p>Toto jsou jednoduché routy pro jednoduchou adresářovou strukturu. Lehce složitější jsou pro\nmodulární strukturu, kdy je zapotřebí specifikovat modul:</p>\n<pre><code class=\"hljs\">http://zlml.cz/rss.xml\n</code></pre><pre><code class=\"hljs lang-php\">$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'rss.xml'</span>, <span class=\"hljs-string\">'Front:Blog:rss'</span>);\n</code></pre>\n<p>Chová se to stejně jako u předchozího příkladu se <code>sitemap.xml</code>, v tomto příkladu však routa hledá <code>BlogPresenter.php</code> ve složce <code>FrontModule</code> a šablonu <code>rss.latte</code>, také v tomto modulu. U rout pro modulární aplikace již raději rozepisuji druhý parametr, protože je to přehlednější. Následující routa zvládne jazykové mutace pro FrontModul, jinak je to opět ta nejobecnější routa vůbec:</p>\n<pre><code class=\"hljs\">http://zlml.cz/en/site/kontakt\n</code></pre><pre><code class=\"hljs lang-php\">$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'[&lt;lang cs|sk|en&gt;/]&lt;presenter&gt;/&lt;action&gt;[/&lt;id&gt;]'</span>, <span class=\"hljs-keyword\">array</span>(\n    <span class=\"hljs-string\">'module'</span> =&gt; <span class=\"hljs-string\">'Front'</span>,\n    <span class=\"hljs-string\">'presenter'</span> =&gt; <span class=\"hljs-string\">'Homepage'</span>,\n    <span class=\"hljs-string\">'action'</span> =&gt; <span class=\"hljs-string\">'default'</span>,\n));\n</code></pre>\n<p>To samé, ale opět o trošku náročnější. Tentokrát pro UserModule, který je na jiné URL, než FrontModule:</p>\n<pre><code class=\"hljs\">http://zlml.cz/user/en/setting/password\n</code></pre><pre><code class=\"hljs lang-php\">$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'user/[&lt;lang cs|sk|en&gt;/]&lt;presenter&gt;/&lt;action&gt;[/&lt;id [0-9]+&gt;]'</span>, <span class=\"hljs-keyword\">array</span>(\n    <span class=\"hljs-string\">'module'</span> =&gt; <span class=\"hljs-string\">'User'</span>,\n    <span class=\"hljs-string\">'presenter'</span> =&gt; <span class=\"hljs-string\">'Board'</span>,\n    <span class=\"hljs-string\">'action'</span> =&gt; <span class=\"hljs-string\">'default'</span>,\n));\n</code></pre>\n<p>A na závěr ještě poslední přehled možných rout jako příklady toho co je možné.</p>\n<pre><code class=\"hljs lang-php\">$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'sitemap.xml'</span>, <span class=\"hljs-string\">'Front:Export:sitemap'</span>);\n$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'kategorie/&lt;category&gt;'</span>, <span class=\"hljs-string\">'Front:Product:default'</span>);\n$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'produkt/&lt;product&gt;'</span>, <span class=\"hljs-string\">'Front:Product:detail'</span>);\n$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">''</span>, <span class=\"hljs-string\">'Front:Product:default'</span>);\n$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'admin/sign-&lt;action&gt;'</span>, <span class=\"hljs-string\">'Admin:Sign:'</span>);\n$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'registrace/'</span>, <span class=\"hljs-string\">'Front:Register:new'</span>);\n$router[] = <span class=\"hljs-keyword\">new</span> Route(<span class=\"hljs-string\">'index.php'</span>, <span class=\"hljs-string\">'Homepage:default'</span>, Route::ONE_WAY);\n$router[] = <span class=\"hljs-keyword\">new</span> CliRouter(<span class=\"hljs-keyword\">array</span>(<span class=\"hljs-string\">'action'</span> =&gt; <span class=\"hljs-string\">'Cli:Cli:cron'</span>));\n$router[] = <span class=\"hljs-keyword\">new</span> \\App\\RestRouter(<span class=\"hljs-string\">'api[/&lt;presenter&gt;[/&lt;id&gt;]]'</span>, <span class=\"hljs-keyword\">array</span>( <span class=\"hljs-comment\">//vyžaduje speciální objekt (není součástí Nette)</span>\n    <span class=\"hljs-string\">'module'</span> =&gt; <span class=\"hljs-string\">'Rest'</span>,\n    <span class=\"hljs-string\">'presenter'</span> =&gt; <span class=\"hljs-string\">'Resource'</span>,\n    <span class=\"hljs-string\">'action'</span> =&gt; <span class=\"hljs-string\">'get'</span>,\n), \\App\\RestRouter::RESTFUL);\n</code></pre>\n<p>Je zcela zřejmé, že se všechny konstrukce stále opakují, proto považuji za opravdu důležité\nperfektně pochopit tvorbu odkazů a následně je to možná trochu o experimentování, ale s\ntouto sadou příkladů bude myslím jednoduché najít podobnou routu, jaká je zrovna potřeba.</p>\n<p>Jak na v posledním příkladu zmíněný CLI router se dočtete v článku <a href=\"nette-2-1-dev-clirouter\">Nette 2.1-dev CliRouter</a>.</p>\n<p>Máte nějakou zajímavou routu? Podělte se o ni... (-:</p>\n"
});
