Slug & id v url – kontrola slugu?

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

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
+
0
-

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
+
+5
-

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
+
0
-

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
+
0
-

@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
+
0
-

@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
+
0
-

@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).

Aurielle
Člen | 1281
+
0
-

@greeny přesměrovávat ti bude presenter stále, stačí jen napsat správně filtry. S entitami můžeš pracovat pořád, mělo by to fungovat :)

ali
Člen | 342
+
+1
-

@joe redirect je lepsi reseni, kvuli toho, ze vyhledavace maji vzdy spravny odkaz a kdyz narazi na 404, tak to zahodi..

looky
Člen | 99
+
0
-

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
+
0
-

@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
+
0
-

@joe kdyz presmerujes URL s kodem 301, tak robot si zapamatuje tu spravnou URL

$this->redirect(Nette\Http\IResponse::S301_MOVED_PERMANENTLY, "this", [...]);

https://support.google.com/…answer/93633?…