Różny wygląd podstron - alternatywne szablony, arkusze i moduł Views

Pierwotna wersja tekstu została napisana w 2006 roku, a teraz doczekał się on zmian.

Przychodzi taki czas kiedy „rządca” drupalowej strony postanawia całkowicie zmodyfikować wygląd strony głównej lub stworzyć działy tematyczne. Istnieje specjalny moduł umożliwiający serwowanie użytkownikom innej strony głównej, jednak osobiście wolę korzystać z innych rozwiązań.

  • cel: całkowicie inny wygląd strony głównej lub działu strony
  • metoda: tam, gdzie się da, korzystać z wbudowanych w rdzeń Drupala funkcji i uniwersalnych modułów
  • składniki: Drupal, skórka PHPTemplate, moduł Views

Najlepiej przed przystąpieniem do zmian zastanowić się czy będziemy potrzebowali kilku diametralnie różniących się strukturalnie szablonów czy tylko arkuszy stylów. Zależnie od tego stworzymy główny szablon strony oraz kilka „podszablonów” albo jeden szablon z pewnymi modyfikacjami zawartymi wewnątrz niego.

Treść

Poszczególne kategorie artykułów można potraktować jak działy, jednak taki sposób prezentacji tekstów nie daje specjalnych możliwości. Dlatego możemy skorzystać z modułu Views, który oferuje dwa podstawowe „tryby” wyświetlania treści: strona lub blok. Tworzenie stron z listą artykułów przyda się właśnie do stworzenia działu.

Za pomocą filtru (filters) Taxonomy: Terms for Nazwa_kategorii wybierzemy do danego działu artykuły należące do danych kategorii (niekoniecznie jednej), a za pomocą innych filtrów możemy ograniczyć je tylko do konkretnego autora, typu segmentu czy wyświetlić jedynie te, które kazaliśmy opublikować na stronie głównej.

Nie zapomnijmy dodać filtru Node: Distinct, który spowoduje, że ten sam artykuł nie będzie wyświetlany więcej niż raz, oraz filtru Node: Published, który odrzuci nieopublikowane wpisy. Ustawmy także sortowanie (Sort Criteria), a w przypadku bloków z listą artykułów (nie wyświetlających ich treści), także dane, które mają zostać wyświetlone, na przykład tytuł (title).

Po utworzeniu „widoku” (view), jego nazwa zostanie umieszczona w adresie strony. Widok o nazwie Internet będzie miał adres http://example.com/internet, co okaże się później pomocne.

Kiedy mamy już odpowiednio podzieloną (co prawda jedynie „wirtualnie”) treść, możemy przystąpić do zmiany jej wyglądu.

Alternatywne szablony dla różnych stron

Szablony dla adresów standardowych

Inne szablony dla różnych stron witryny uzyskamy, korzystając z wbudowanego w Drupala mechanizmu wykorzystującego nazwy plików. Plik szablonu page.tpl.php będzie domyślnym. W przypadku strony o adresie http://example.com/node/1 Drupal będzie po kolei poszukiwał plików o następujących nazwach:

  1. page-node-1.tpl.php
  2. page-node.tpl.php
  3. page.tpl.php

Jeśli więc chcemy dla takiej strony przygotować osobny szablon strony, umieśćmy go w pliku page-node-1.tpl.php.

W przypadku strony użytkownika od ID równym 1, czyli http://www.example.com/user/1, schemat nazewnictwa będzie wyglądał tak:

  1. page-user-1.tpl.php
  2. page-user.tpl.php
  3. page.tpl.php

Szablon dla strony głównej można natomiast umieścić w pliku page-front.tpl.php.

Warto też przyjrzeć się funkcji arg(), która zwraca odpowiedni fragment adresu, numerując je od zera. Na przykład arg(0) w przypadku strony node/1 zwróci node. Dzięki temu możemy konstruować takie warunki jak:

<?php

switch (arg(0)) {
  case 'node': $inc = 'page-node.tpl.php'; break;
  case 'user': $inc = 'page-user.tpl.php';  break;
  default: $inc = 'page-default.tpl.php';  break;
}

?>

Umieszczając taki kod w miejsce zawartości pliku page.tpl.php, a ją z kolei przenosząc do page-default.tpl.php, możemy uzyskać podobne efekty, jak w przypadku pierwszego rozwiązania. Wybór odpowiedniejszego dla danej witryny należy do użytkownika.

Szablony dla aliasów stron

Powyższe metody zadziałają tylko w przypadku standardowych adresów stron. Nie wystarczą one, jeśli adresowi wpisu nadaliśmy alias oferta. Pamiętając, że alias współistnieje ze standardowym adresem (oferta to jednocześnie na przykład node/25), możemy oczywiście nadal korzystać z tego ostatniego.

Jeśli jednak z jakichś względów wolimy oprzeć dobór szablonów na aliasach, poniższy kod – wstawiony do pliku template.php skórki – nam to umożliwi:

<?php
function _phptemplate_variables($hook, $vars = array()) {
  switch ($hook) {
    case 'page':
      if (module_exists('path')) {
        $alias = drupal_get_path_alias(str_replace('/edit','',$_GET['q']));
        if ($alias != $_GET['q']) {
          $suggestions = array();
          $template_filename = 'page';
          foreach (explode('/', $alias) as $path_part) {
            $template_filename = $template_filename . '-' . $path_part;
            $suggestions[] = $template_filename;
          }
        }
        $vars['template_files'] = $suggestions;
      }
      break;
  }

  return $vars;
}
?>

Powyższa wersja przeznaczona jest dla Drupala 5, a ta poniżej – dla Drupala 6.

<?php
function phptemplate_preprocess_page(&$vars) {
  if (module_exists('path')) {
    $alias = drupal_get_path_alias(str_replace('/edit','',$_GET['q']));
    if ($alias != $_GET['q']) {
      $suggestions = array();
      $template_filename = 'page';
      foreach (explode('/', $alias) as $path_part) {
        $template_filename = $template_filename . '-' . $path_part;
        $suggestions[] = $template_filename;
      }
    }
    $vars['template_files'] = $suggestions;
  }
}
?>

Powracając do naszego przykładu – jeśli alias adresu strony to oferta, możemy teraz umieścić szablon tej podstrony w pliku page-oferta.tpl.php.

Co ze złożonymi adresami, zawierającymi ukośniki? Szablon strony /oferta/szkolenia/biznesowe może się znaleźć w pliku:

  1. page-oferta-szkolenia-biznesowe.tpl.php
  2. page-oferta-szkolenia.tpl.php
  3. page-oferta.tpl.php

Jeżeli adresy wszystkich stron dotyczących szkoleń rozpoczynają się od /oferta/szkolenia możemy je zmodyfikować wszystkie naraz za pomocą pliku o nazwie page-oferta-szkolenia.tpl.php.

Szablony dla sekcji witryny

Ten temat poruszę w osobnym poradniku. Nietrudno się jednak domyślić, że opisane wyżej metody dobrze współpracują z rozwiązaniami oferowanymi przez moduł Pathauto, umożliwiający m.in. automatyczne tworzenie aliasów uwzględniających kategorię, w której znajduje się wpis.

Szablony dla rodzajów segmentów

Rodzaje segmentów to na przykład artykuł, strona, czy wątek. Poniższy kod, umieszczony w template.php, umożliwi tworzenie osobnych szablonów dla segmentów określonego rodzaju.

<?php
function _phptemplate_variables($hook, $vars) {
  switch ($hook) {
    case 'page':
      if (arg(0) == 'node' && is_numeric(arg(1))) {
        $result = db_query('SELECT type  FROM {node} WHERE nid = %d',arg(1));
        $record = db_fetch_object($result);
        $node_type = $record->type;
        $suggestions[] = 'page-nodetype-'. $node_type;
        $vars['template_files'] = $suggestions;
      }
    break;
  }
  return $vars;
}
?>

Szablon dla segmentu typu artykuł (story) powinien się znaleźć w pliku page-nodetype-story.tpl.php.

Co z wyglądem, czyli arkusze stylów

Szablony to nie wszystko. Korzystając z któregoś z powyższych sposobów (lub je łącząc), możemy również zmienić wygląd elementów podstron. Wystarczy, że w danym szablonie, np. page-oferta.tpl.php fragment <?php print $styles ?> zamienimy na print drupal_get_css();, a powyżej dopiszemy co następuje:

<?php drupal_add_css((path_to_theme() . '/style-oferta.css'), 'theme', 'all'); ?>

Reguły stylów (CSS) dla strony oferta należy teraz umieścić w pliku style-oferta.css.

Obszary

Mamy strukturę, mamy style, ale chcielibyśmy jeszcze co nieco poprzestawiać na stronie. Podstawowym ograniczeniem zwykłej konfiguracji Drupala jest na przykład to, że nie można w miejscu listy wpisów (artykułów, stron) umieścić bloków, a jedynie pod lub nad tą listą (zależnie od skórki). Jeśli krępuje nas standardowy układ elementów strony, możemy go całkowicie zmienić powołując do życia własne obszary. W tym celu musimy zastąpić standardową funkcję regions naszą. Otwieramy lub tworzymy plik template.php i wklejamy:

function skórka_regions() {
  return array(
    'header' => t('header'),
    'notice' => t('notice'),
    'content' => t('content'),
    'frontpage_content' => t('frontpage'),
    'sidebar' => t('right sidebar'),
    'footer' => t('footer')
  );
}

Tradycyjnie, zmieniamy wedle potrzeb, pamiętając o zastąpieniu tekstu skórka nazwą używanej skórki. 'header' oznacza nazwę obszaru używaną wewnątrz szablonu, a t('header') nazwę wyświetlaną na stronach zarządzania (np. w konfiguracji bloków).

W tym przykładzie stworzyłem dwa główne obszary przechowujące podstawową treść strony (normalnie listę wpisów lub same wpisy), czyli content oraz frontpage_content, by móc umieścić inne bloki i wpisy na stronie głównej, a inne na reszcie stron.

Korzystanie z obszarów w szablonach

Kiedy już stworzymy nasz piękny kod HTML, wzbogacony nieco funkcjami PHPTemplate, możemy umieścić w przygotowanych wcześniej warstwach (div) czy innych elementach odwołania do treści danych obszarów:

<?php print $nazwa_obszaru ?>

Wróćmy do kwestii strony głównej. Oto jak wewnątrz szablonu page.tpl.php możemy uzależnić wyświetlanie tej lub innej treści od tego, czy strona jest stroną główną:

<?php
  if ($is_front) { print $frontpage_content; }
  else { print $content; }
?>

Jeśli jest główną, ładowana będzie treść obszaru o nazwie frontpage_content, a w przeciwnym wypadku content (patrz: poprzedni punkt).

Teraz w konfiguracji bloków możemy dla przykładu umieścić w obszarze znajdującym się tylko na stronie głównej jakieś specjalne bloki wygenerowane za pomocą modułu Views. Część z nich może wyświetlać listy wpisów, a część skróconą lub pełną treść wpisów z różnych kategorii. Możliwości jest mnóstwo.

Sposób wyświetlania odpowiedzi

Wybierz preferowany sposób wyświetlania odpowiedzi i kliknij "Zachowaj ustawienia", by wprowadzić zmiany.
Portret użytkownika cyberrus

drobna uwaga do powyższego

drobna uwaga do powyższego tutka — arg(0) nie zwraca całej ścieżki systemowej, tylko jej fragment do pierwszego slasha, więc żeby przypasować odpowiedni szablon do konkretnej ścieżki to trzeba sprawdzać warunek (przy scieżce składającej się z trzech członów): arg(0) . arg(1) . arg(2) == ‚twoja_ścieżka_sys­temowa_bez_slash­y’

Portret użytkownika palik

skorzystałem poniekąd

moderator

dodając jedno z 5 zdjęć w sposób losowy do tła mojego basoofkowego menu :)

zamiast polegać na typie segmentu lub ścieżce dałem $styl=rand(1,5); a potem switch ($styl) …

w sumie można połączyć w jednym obie metody (np. losując tła i kontrolując poszczególne typy segmentów bądź ścieżki..)

w skrócie – przydało mi się :)

-- drupal w akcji? http://palikowski.vel.pl http://basoofka.net

Portret użytkownika palik

jeszcze raz ja

moderator

No więc uzupełniajc wersję 1 można jeszcze zrobić sobie szablon do np. rozmiarów obrazków dopisując kolejny switch tym razem na zmienne przekazywane w adresie:

switch ($_GET['size']) {
  case '_original': $inc = 'page-image-full.tpl.php'; break;
}

-- drupal w akcji? http://palikowski.net http://basoofka.net

Portret użytkownika archetwist

Ciekawe. Może się kiedyś

moderator

Ciekawe. Może się kiedyś przydać.

Portret użytkownika astral

Brak zmian!

Dokonałem zmian wg „Modyfikacji sposób drugi: alternatywne arkusze stylów”, ale niestety nie ma żadnych zmian – wybrane podstrony nie zmieniają się zgodnie z przypisanymi im css-ami, wszystkie podstrony są na podstawowym css-ie. Gdzie może być błąd? Może trzeba zastosować propozycję Cyberrusa? Jeśli tak to bardzo bym prosił o dokładne wyłożenie mi gdzie jaki kod „wklepać”. Podam jeszcze schemat adresu strony głównej www.strona.pl/costam, a podstrona z przypisanymi zmianami www.strona.pl/…/q=podstrona

Proszę o pomoc…