Slug & id v url – kontrola slugu?
- greeny
- Člen | 405
Zdravím,
používám typický IN-OUT filter na překlad entita ↔ url, takže mi odkazy fungují takhle:
<a n:href="Post:detail $post">{$post->name}</a>
Vygeneruje např localhost/post/detail/3-my-awesome-post
(<id>-<slug>)
Slug nemám nikde uložený (vzniká webalize($name)
, v IN
filtru se vytáhne post podle IDčka:
list($id,) = explode('-', $urlPart, 2);
$post = $postRepository->find($id);
Moje otázka zní – uživatel může takhle zadat jakoukoliv url, např:
localhost/post/detail/3-not-so-awesome-post
localhost/post/detail/3-duplicate-url
...
Je to problém? Měl bych kontrolovat i jestli slug odpovídá webalizovanému jménu? Nebo to nemá cenu a budu spoléhat na to, že uživatele nenapadne přepisovat URL? A nebo přesměrovat na správný tvar? (což v IN/OUT filtru asi nepůjde)
Jaký je best practise ohledně slugů?
- Azathoth
- Člen | 495
Můj osobní názor: validovat v routeru a vracet 404, pokud je špatný
slug.
Protože potom, pokud se nepletu, google indexuje stránky jako
mySite.com/post/detail/3-child-porn-two-girls-one-cup, když na to někdo
odkáže.
A asi nikdo nechce, aby v googlu vyskakoval odkaz na jeho server, kde je
v url například
mySite.com/post/detail/3-i-hate-black-people-hitler-did-nothing-wrong
setkal jsem se s tím, že google indexoval výsledky hledání na jedné stránce a když tam někdo zadal do vyhledávání dotaz ve kterém byla gramatická chyba, tak jiný zákazník stránku s tímhle dotazem v get parametru našel při googlení a dost hlasitě se pohoršoval nad tou stránkou, že tam mají gramatickou chybu i když za to stránka nemohla.
- David Matějka
- Moderator | 6445
V pripade, ze se to neshoduje, tak presmeruj na spravnou verzi. Vracet 404, jak radi @Azathoth , neni idealni – pokud treba zmenis nazev clanku, tak by stare odkazy na clanek nefungovaly.
- greeny
- Člen | 405
David Matějka napsal(a):
V pripade, ze se to neshoduje, tak presmeruj na spravnou verzi. Vracet 404, jak radi @Azathoth , neni idealni – pokud treba zmenis nazev clanku, tak by stare odkazy na clanek nefungovaly.
To dává smysl… Teď už jen řeším, jak přesměrovat. Koukám, že ve filtru/routeru to asi nepůjde, že? Budu to muset dát do presenteru
Editoval greeny (23. 10. 2015 12:01)
- vitkutny
- Člen | 73
@greeny mělo by stačit aby parametr <id> v routeru pokrýval id včetně slugu “123-slug”, “123-slug-duplicate”, ve FILTER_IN slug odsekneš a do aplikace pošleš pouze id a ve FILTER_OUT k id vždy vrátíš id se správným slugem
“123-slug-duplicate” ⇒ FILTER_IN ⇒ 123 ⇒ FILTER_OUT ⇒ “123-slug”
a o přesměrování se ti postará presenter https://api.nette.org/…ter.php.html#…
IMHO lepší řešení je přímo pracovat se slugem, k tomu je třeba si ale vést historii změn slugu, a ve FILTER_IN rozpoznat, že se jedná o starý slug a nahradit jej aktuálním
- greeny
- Člen | 405
@vitkutny já nepoužívám ID, ale přímo entitu, je to IMHO mnohem lepší způsob práce s odkazy.
takže např v actionDetail
dostanu jako parametr přímo
entitu, nemusím jí tahat z db, můžu na ní odkazovat přímo a neřešit
jestli ten daný odkaz bere slug nebo id nebo co… A o všechno se mi pak
postará filtr v routeru. Když změním způsob generování odkazů,
přepíšu jen filtr a všechno dál pojede, nemusím procházet všechny
šablony a hledat kde přepsat např. id na slug nebo vyrábět ONE_WAY routu
kvůli starým odkazům :)
Navíc mně <id> pokrývá id včetně slugu a odsekávám to… Jen místo ID pošlu do aplikace přímo entitu :)
- joe
- Člen | 313
@DavidMatějka Nemyslím si, že to je dobrý nápad. To pořád umožňuje linkovat na web se špatným slugem, i když dojde následně k přesměrování. Lepším řešením by bylo, kdyby nesmyslné odkazy, jako napsal @Azathoth skutečně vracely 404 a odkazy na článek, kterým se změnil v systému slug byly vyřešeny pomocí přesměrování (to už není chyba systému, ale „chyba“ v datech).
- looky
- Člen | 99
U sebe na blogu používám pro články tohle:
/**
* @param int $id
* @param string|NULL $slug
*/
public function renderArticle($id, $slug)
{
$article = $this->articleFacade->getLiveArticleById((int) $id);
if (!$article) {
$this->error();
} elseif ($article->getSlug() !== $slug) {
$this->redirect(IResponse::S301_MOVED_PERMANENTLY, 'this', ['slug' => $article->getSlug()]);
}
$this->template->article = $article;
}
Editoval looky (23. 10. 2015 18:25)
- joe
- Člen | 313
@ali Jsem pro přesměrování, ale jen těch URL, co vznikly v systému. Tím co jsi napsal necháš s klidem roboty indexovat ty adresy, které podle mě nemají být platné, tj. mají vést na 404 (Google bomby apod.), na druhou stranu řešit jen přesměrování je jednodušší, na stranu druhou, URL, která je zaindexovaná by se neměla měnit.
- ali
- Člen | 342
@joe kdyz presmerujes URL s kodem 301, tak robot si zapamatuje tu spravnou URL
$this->redirect(Nette\Http\IResponse::S301_MOVED_PERMANENTLY, "this", [...]);