Ubercart catalog + custom Views

Zainstalowałem ostatnio moduł Ubercart umożliwiający prowadzenie e-comerce w oparciu o Drupala. Ubercart dla Drupala 7 na dzień dzisiejszy nie jest dopracowany (sypie błędami po instalacji) więc postanowiłem działać poki na wersji dla Drupala 6. Tworząc własny template dla mojego wyimaginowanego sklepu z warzywami, postanowiłem zmodyfikować sposób generowania widoków produktów w zależności od wybranej kategorii.

Jak jest i jak być powinno

Ubercart wykorzystuje hierarchie produktów utworzone za pomocą modułu taxonomy Drupala. Na podstawie wybranej taksonomii submoduł catalog generuje menu umożliwiające użytkownikowi filtrowanie wyświetlanych produktów. Schody zaczynają się w momencie gdy chcemy stworzyć wielopoziomowe drzewo kategorii. Powiedzmy, że mamy taki układ kategorii:

1. OWOCE
   1.1 zielone
   1.2 pomarańczowe
   1.3 niebieskie
2. WARZYWA
   2.1 kwaśne
   2.2 gorzkie
   2.3 słodkie

Standardowo jest tak, że w momencie wybrania pozycji "1.1 zielone" wyświetlone zostaną tylko produkty należące do tej kategorii. Jednak w przypadku wybrania poyzcji "OWOCE" spodziewany przeze mnie efekt to wyświetlenie produktów należących do wszytkich kategorii owoców. Tymczasem w Ubercart po wybraniu pozycji "OWOCE" zamiast listy produktów wyświetlany jest grid zawierający kategorie niższego poziomu. Dopiero po wybraniu jednej z nich otrzymujemy listę produktów. Możliwe, że jest to dobre rozwiązanie i szukam dziury w całym jednak postanowiłem dostosować system do siebie i przy okazji się czegoś nauczyć.

Rozwiązanie

Najwygodniejszym rozwiązaniem jakie znalazłem przeszukując Internet jest zastąpienie widoków generowanych przez Ubercart catalog własnymi widokami utworzonymi za pomocą modułu Views. Utworzony views jako argument powinien otrzymywać wybraną przez użytkownika kategorię produktu, tak aby było wiadomo w jaki sposób przeprowadzić filtrowanie. Filtrowanie na podstawie wielopoziomowych taksonomii za pomocą Views jest możliwe dzięki opcji "Term ID (with depth)". Jeden view wystarczy do obsługi wszystkich list produktów. Zakładam że:

  • zainstalowany jest Drupal w wersji 6.20
  • zainstalowany jest i włączony moduł Views w wersji 6.x-2.12
  • zainstalowany jest i włączony moduł Ubercart w wersji 6.x-2.4 oraz wszystkie jego zależności
  • dodane są przykładowe produkty, tak aby było można testować działanie systemu
  • można też zainstalować URL Aliases - umożliwia on generowanie ładnych ścieżek w katalogu produktów.

Utworzenie własnego widoku

Zacznijmy od ustawienia domyślnego display view naszego widoku. Oto najwazniejsze ustawienia:

Basic settings
   Style: HTML List
   Row style: Node
Arguments
   Taxonomy: Term ID (with depth)
Filters
   Node: Is a product True
   Node: Published Yes

W ustawieniach Row style można ustawić opcję Build mode na Teaser. Najważniejsze jest jednak prawidłowe ustawienie sekcji Arguments. Należy dodać pozycję "Taxonomy: Term ID (with depth)" a następnie ustawić w niej wartosć depth na większą niż 1. Wartość ta decyduje o ilości poziomów potomnych kategorii, z których utworzona zostanie lista wyświetlonych node'ów.

Modyfikacja zachowania menu produktów

W samym menu właściwie nie ma potrzeby nic zmieniać, chcemy jedynie zmienić sposób generowania widoku. Można to zrobić poprzez utworzenie własnej implementacji funkcji theme_uc_catalog_browse submodułu Ubercart o nazwie catalog. Funkcja znajduje się w pliku uc_catalog.pages.inc w folderze modules/ubercart/uc_catalog. Wewnątrz naszej wersji funkcji wykorzystamy wcześniej utworzony widok dlatego trzeba znać jego id. Sam kod właściwie nie wymaga komentarza. MYTHEME należy zastąpić nazwą swojego thema oraz "produkty" nazwą id wcześniej utworzonego widoku modułu Views.

// w pliku template.php...
function MYTHEME_uc_catalog_browse($tid = -1)
{  
   $view_name = 'produkty';
   $display_id = 'default';
   $args = array();
  
   if ($tid > -1)
   {
      $args[] = $tid;
   }
 
   $output = '';
               
   $view = views_get_view($view_name);             
   $view->set_display($display_id);
   $view->set_arguments($args);
   
   $output = $view->preview($display_id, $args);             
   $view->destroy();
               
   return $output;  
}

Napisz komentarz