Drupal: kategorie i podkategorie na podstawie Taxonomy, Pathauto i Views
05 lipca 2008
W nowej pracy od dwóch miesięcy uczę się wszystkiego na temat Drupala ponieważ to właśnie na tym systemie CMS ma być oparta większość naszych projektów. Ostatnio trafiliśmy na mały problem i znalezienie rozwiązania trochę mi zajęło czasu więc teraz postanowiłem, że pokaże jak sobie poradziłem. Może komuś się przyda.
Aby zrozumieć problem i jego rozwiązanie wymagana jest przynajmniej podstawowa znajomość Drupala i wymienionych w tytule modułów.
Budujemy w tej chwili niewielki, mało skomplikowany sklep Internetowy a raczej całą sieć sklepów. Potrzebne były nam między innymi takie funkcjonalności:
- każdy produkt można przypisać do jednej kategorii
- - struktura kategorii wygląda tak, że są kategorie główne w których mogą znajdować się podkategorie
- po wejściu do kategorii powinny wyświetlić się dostępne produkty z tej kategorii oraz ze wszystkich podkategorii dla tej kategorii
- linki powinny być SEO friendly
I tu dochodzimy do sedna problemu. Jak sprawić aby działały linki (wygenerowane przy pomocy modułu Pathauto) www.example.com/produkty/kategoria-1/ oraz www.example.com/produkty/kategoria-1/podkategoria-1/ i aby pod pierwszym linkiem pojawiły się produkty nie tylko z tej kategorii ale również ze wszystkich podkategorii?
Doszliśmy do wniosku, że działanie trzeba oprzeć na module Views. Można w nim dodawać argumenty. W skrócie polega to na tym, że każdy widok zapisany jako strona (a nie blok) powinien mieć swój adres. Jednak po tym podstawowym adresie można podawać kolejne "elementy" adresu, które potem możemy "obsłużyć".
A więc w naszym przypadku adresem widoku jest "produkty". W pierwszym przykładzie argumentem jest "kategoria-1" natomiast w drugim przykładzie w adresie z podkategorią są już dwa argumenty: "kategoria-1" i "podkategoria-1".
Możemy podpowiedzieć modułowi Views co te argumenty oznaczają i jak je obsłużyć. Upraszczając: zależnie od adresu możemy wyświetlić co innego obsługując to jednym widokiem.
I tak podczas dodawania argumentu są trzy możliwości dotyczące modułu Taxonomy (na którym są oparte kategorie, jest to jeden z podstawowych modułów Drupala, dostarczany wraz z plikami instalacyjnymi):
- Taxonomy: Term ID
- Taxonomy: Term Name
- Taxonomy: Vocabulary ID
Z racji tego, że korzystamy z Pathauto do generowania ładnych adresów w których użyte są nazwy kategorii uznałem za logiczne, że należy wybrać "Term Name". Niestety przy takich ustawieniach widok nie radził sobie z rozpoznawaniem z czym tak naprawdę ma do czynienia. Odczytywał oczywiście argument "kategoria-1" ale nie potrafił automatycznie zamienić tego na ID kategorii.
Po ręcznej zamianie adresu z "kategoria-1" na "kategoria 1" (bo tak się właśnie nazywała ta kategoria) widok wiedział już co wyświetlić ale mała to pociecha
Dodatkowo nadal pozostawał problem pokazania również produktów z podkategorii.
Z drugiej strony gdy wybierzemy "Term ID" zamiast "Term Name" to w polu "Option" możemy ustalić jak głęboko ma być zagnieżdżone wyszukiwanie w podkategoriach. Czyli w naszym wypadku trzeba wstawić wartość "1" i w ten sposób wyświetlą się produkty z kategorii i podkategorii. Niestety aby skorzystać z tego dobrodziejstwa to w adresie musiałyby być przekazywane numery ID zamiast nazw kategorii a nam przecież zależy na przyjaznych linkach. Chyba, że....
Moduł Views daje nam jeszcze jedną możliwość. Możemy napisać dowolny kod PHP, który "obsłuży" argumenty.
A więc budujemy widok. Nadajemy mu jakąś nazwę, zaznaczamy opcję "Provide Page View" i wypełniamy pole "URL". W naszym przypadku wartość to "produkty". Oczywiście można jeszcze zastosować jakieś filtry, sortowanie itd. ale to już każdy sam zdecyduje co potrzebuje.
Następnie przechodzimy do argumentów. Dodajemy "Taxonomy: Term ID". W polu "Default" wybieramy co kto potrzebuje (ja wybrałem "Display All Values") a w polu "Option" wstawiamy "1". Ja mam tylko kategorie i podkategorie ale jeżeli Ty masz jeszcze głębsze zagnieżdżanie to pamiętaj aby wstawić tu odpowiednio dużą liczbę.
No dobrze, pierwszy argument (czyli kategorie) obsłużony. Teraz czas na podkategorie. Ponownie dodajemy argument "Taxonomy: Term ID" i ustawiamy pole "Default". Już nie muszę się martwić o pole "Option" ponieważ kategorie nie są głębiej zagnieżdżane w moim sklepie.
Przy takich ustawieniach nasza strona działa tak jak chcieliśmy za wyjątkiem przyjaznych adresów. Można wyświetlić zarówno produkty z kategorii jak i podkategorii i w pierwszym przypadku będą brane pod uwagę również produkty ze wszystkich podkategorii ale w adresach trzeba podawać numery ID kategorii a nie ich nazwy.
I tu z pomocą przychodzi wcześniej wspomniany kod PHP. W pole "Argument Code:" wklejamy poniższy kod:
Co robi ten kod? W skrócie zamienia nazwę kategorii, która jest przekazana przez adres na jej numer ID. A dalej działa już nasz wcześniej stworzony mechanizm oparty o "Term ID". Przy czym należy usunąć drugi argument w panelu widoku. Wcześniej był potrzebny aby podkategorie działały ale teraz nasz kod PHP zawsze przekazuje numer naszej kategorii/podkategorii jako pierwszy argument ($args[0]) bez względu na ilość zagnieżdżeń dlatego w panelu widoku powinien być dodany tylko jeden argument.
Mam nadzieję, że ktoś coś z tego zrozumiał
Niestety trzeba mieć już jakąś wiedzę na temat Drupala i konfiguracji wymienionych wtyczek aby pojąć jak to wszystko działa. Dociekliwym zalecam przeanalizowanie tego krótkiego kodu PHP aby wiedzieli na przyszłość jak sobie w takich przypadkach radzić.
Dodam tylko, że normalnie koniec zapytania powinien wyglądać tak: "LIKE '%s'" ale najwidoczniej moduł Views ma pod tym względem jakieś specjalne wymagania/ograniczenia bo taka konstrukcja nie działa i koniecznym było dodanie po dwa znaki procentów przed i po "%s".
Nie wiem czemu ale mam nieodparte wrażenie, że efekt, którego potrzebowałem da się osiągnąć w jakiś prostszy sposób
Niestety nie mogłem znaleźć innego rozwiązania. Może źle szukałem
Gdyby ktoś znał prostszy sposób to chętnie go wysłucham
W końcu cały czas się uczę Drupala
Można się bawić z aliasami. Ustawiać je ręcznie lub napisać mały moduł, który podczas dodawania nowej kategorii sam zaopiekuje się stworzeniem aliasu. Tylko, że to raczej gorsze metody
Pierwsza w moim przypadku w ogóle nie wchodzi w grę, na takie coś można sobie pozwolić na malutkiej stronce a nie w oprogramowaniu na którym ma stać kilkanaście połączonych sklepów Internetowych. Druga też jest kłopotliwa.
PS
Rozwiązanie zastosowane w Drupalu 5.7. Nie sprawdzałem jak sprawa wygląda w 6.2, która jest w tej chwili najnowszą wersją.
Blog przede wszystkim o Internecie i mojej pasji jaką jest tworzenie stron www. Ale nie ograniczam się do jednej tematyki, piszę o wszystkim o czym mam ochotę :-)
virusxd napisał: 27.07.09 o godzinie 1:31
W Drupal’u 6 i nowej wersji Views 6.x-2.6 problem został naprawiony. Pozdrawiam.