Ja niedawno coś takiego robiłem. To w zasadzie nieco inaczej przemyślany routing. Ogólnie przyjąłem założenia że:
1) kategorie i subkategorie nie mają _ w nazwie
2) jedyne dozwolone znaki to a-z 0-9 , _ - gdzie:
a) a-z 0-9 to standardowe konwersje do nice url znaków alfanumerycznych
b) , służy do oddzielenia id w sytuacji gdy jakiś parametr wymaga identyfikatora
c) _ służy do oddzielenia pary klucz-wartość, przy czym wartość jako jedyna może mieć identyfikator oddzielony przecinkiem
d) - zastępuje znaki niedozwolone i puste, przy czym nie może wystąpić więcej niż taki jeden znak obok siebie. Jeśli jest inaczej, skaracam te kilka znaków do jednego -
W efekcie mój "router" przyjmuje przykładowy adres w postaci /kategoria/subkategoria/subkategoria2/parametr_wartosc/parametr2_wartosc-jakas,98/
Jest tak przemyślany, że sprawdza wystepowanie subkategorii i ustawia je w url po kolei oraz sprawdza czy subkategoria występuje w "rodzicu" ją poprzedzającym i jeśli nie, usuwa z url ją oraz te będące jej potomkami. Efekt?
/kategoria/subkategoria1/parametr_wartosc/subkategoria2/parametr2_wartosc-jakas,98/
podlega wstępnej konwersji do
/kategoria/subkategoria1/subkategoria2/parametr_wartosc/parametr2_wartosc-jakas,98/
i teraz zależnie czy subkategorie są dziećmi swoich rodziców (i o ile występują takie w spisie kategorii/subkategorii!) adres może przyjąć kilka wariantów:
/kategoria/subkategoria1/subkategoria2/parametr_wartosc/parametr2_wartosc-jakas,98/
/kategoria/subkategoria1/parametr_wartosc/parametr2_wartosc-jakas,98/
/kategoria/parametr_wartosc/parametr2_wartosc-jakas,98/
/parametr_wartosc/parametr2_wartosc-jakas,98/
Parametry także są sprawdzane i one także mogą być pozostawione lub usunięte. Dodatkowo nad całością czuwa konfig, który ustawia mi kolejność parametrów w url i jeśli przyjda w zmienionej kolejności, ustawia je prawidłowo. Nie wspomniałem także, że pewne parametry, podobnie jak kategorie mogą być zależne i owe zalezności też są sprawdzane. Przykład? Jesli ktoś spróbuje na pałę wpisać miasto, to podczas routowania wyłapuje miasto i dopisuję do adresu województwo tego miasta. W przypadku niejednoznaczności kieruję do strony, która informuje o tym fakcie i każe doprecyzować z jakiego województwa ma to być miasto (poda w jakich województwach to miasto jest i zwyczajnie da link do kliknięcia ;) ). A jeśli nadal nie jest to jednoznaczne, to każe wybrać dodatkowo powiat w obrębie województwa. A by było jeszcze weselej, to może w przypadku błedu zasugerować miasto inne , którego częścią nazwy jest wpisana fraza. Kolejny przykład... wpisując Biała... Znajdzie zarówno miejscowości Bia, ale jeli takowej nie ma to poszuka takie, które zaczynają się od Bia, czyli choćby Białystok czy Biała-Podlaska.
Całość drzewka kategorii i ich zależności zaś dla wydajności, trzymam sobie w cache'u serwera ;) Wtedy idąc od roota, wiem na jakim poziomie ktoś się rypnął i zostaję na ostatnim prawidłowym. Jesli już pierwsza jest walnięta, usuwam wszystkie kategorie i pozostają mi jedynie dodatkowe parametry do zlookania.
EDIT: takie podejście sprawia, że moge mieć teoretycznie nieskończenie zagłębione kategorie, podobnie jak ilość parametrów może być nielimitowana.
EDIT2: zaznaczam, że to jest tylko szkic logiczny, algorytm ogólny, gdyż kodu nie udostępniam. Bazuje on na fw Kohana 3.X i używa klas stworzonych dla niego na potrzeby firmy :) A te nie będą siła rzeczy udostępniane i tym samym kod bez nich nie ruszy.
Zapomniałem dodać, że w takim wypadku jak napisałem kategoria słuzy jako odpowiednik article w przykładzie by_ikar'a inie jest stricte kategorią, ale znakiem rozpoznawczym dla routingu, w jaki route ma się pchać. By ciutkę to ułatwić, podam nieco zmienioną regułkę :)
Kod
Route::set('glowna', 'kategoria(/<slug>)(/<pagination>)', array('slug' => '([a-żA-Ż-,]{1,}[0-9]{0,}/{0,1})+', 'pagination' => '[0-9]+'))
Kategoria służy jedynie tu do określenia, że mamy do czynienia z czymś, co trzeba mieć by mój router rzucił operacje na kawał kodu odpowiedzialny za kategorie i subkategorie. Jeśli go nie będzie to poleci na kolejne reguły w routes. Uzywam tego jako bardziej inteligentnej wyszukiwarki, która tworzy SEO-friendly adresy url z zapytania wysłanego POSTem. Określasz warunki, a ona sobie przetwarza dane, tworzy url i kieruje do niego. Póki co nigdzie to jeszcze nie stoi i jest w fazie developingu, ale uproszczone wersje w kilku serwisach firmy już działają i sprawują się porządnie.