Kohana Framework – Paginacja + ORM

Znając już zagadnienia związane z modelami ORM w Kohana Framework oraz wiążącymi je relacjami możemy pójść o krok dalej. Dzisiaj omówimy prosty sposób na stronicowanie wyników z bazy danych, inaczej nazywając – paginacje. W przypadku małej ilości wyników np: 10-20 problemu nie ma ponieważ nie burzy to wizualnego układu naszej strony. Schody zaczynają się gdy mamy w bazie dużą ilość rekordów: >100. Jest na to znane wszystkim rozwiązanie zwane paginacją/stronicowaniem.

Czym jest paginacja?

Paginacja jest niczym innym jak podziałem rekordów na wiele stron, zawierających jednakową ilość wyników. Biorąc pod uwagę, że mamy 100 rekordów w bazie danych a limit naszej paginacji wynosi 10 elementów na stronę, musimy wygenerować 10 stron, po 10 wyników na każdej. Pod listą elementów musimy umieścić specjalne odnośniki pozwalające przechodzić pomiędzy stronami: [1][2][3]…[10] itd.

Co tak naprawdę robi paginacja?

Działanie mechanizmu jest bardzo proste, poprzez parametr w adresie (może to być query_string lub parametr routingu) operujemy na aktualnie wyświetlanej stronie.
Znając numer strony, wartość limitu elementów na jedną stronę oraz ilość wszystkich elementów możemy modyfikować zapytanie do bazy danych dodając warunki OFFSET oraz LIMIT.

Co na to SEO ?

Nie jestem specjalistą od SEO marketingu lecz podstawowe kwestie optymalizacyjne powinien znać każdy szanujący się webmaster. Zgodnie z wytycznymi prezentowanymi przez Google aby wskazać robotowi i jednocześnie połączyć ze sobą wyniki wyszukiwania, dobrze jest użyć atrybutów rel="next" oraz rel="prev" wskazujących na następną oraz poprzednią stronę. Robot wiąże w ten sposób listę elementów, które mają być traktowane jako jeden ciągły wynik.

W przypadku gdy jesteśmy na pierwszej stronie, w sekcji należy umieścić wyłącznie atrybut „next”

W przypadku gdy numer strony jest większy niż 1 np, ?page=2 oraz mniejszy niż ostatnia wartość strony należy umieścić oba atrybuty wskazujące analogicznie na poprzednią i następną stronę z paginacji

Jeśli w paginacji dobrniemy do ostatniej strony, przykładowo 100, to w <head> musi być wyłącznie atrybut powrotni czyli rel="prev"

Piszemy mechanizm paginacji

Są do tego gotowe moduły, ale nie o to nam chyba chodzi 🙂 Chciałbym aby każdy zrozumiał zasadę działania takiej paginacji więc napiszemy podstawową wersję mechanizmu.

Zaczynamy od przygotowania testowej struktury bazy danych (tabela o nazwie „elements”) oraz wypełnienie jej przykładową treścią.

Następnie tworzymy model o nazwie Element

Czas na kontroler, nazwijmy go Elements:

Utwórzmy również widok dla naszej strony wyników, niech to będzie plik /application/views/elements.php

Piszemy mechanizm paginacji

Jakie informacje będą nam potrzebne?

  • Aktualnie wybrana strona.
  • Ilość elementów na 1 stronę.
  • Ilość wszystkich elementów.
  • Ilość wszystkich wygenerowanych stron, zgodnie z działaniem (ilość wszystkich elementów / ilość elementów na 1 stronę) zaokrąglamy w górę.
  • Musimy obliczyć również „offset” czyli przesunięcie, które dodane do zapytania wybierze odpowiednie wyniki.

Wewnątrz akcji index kontrolera Elements umieszczamy następujący kod zgodnie z listą zapotrzebowań wyżej.

Następnie we wcześniej utworzonym widoku umieszczamy kod generujący listę elementów oraz paginację.

Gotowe, nasza paginacja powinna działać 🙂

Konkluzja

Utworzyliśmy dzisiaj mechanizm paginacji. Jak widać kod jest bardzo prosty, a całość łatwo opakować w osobny moduł, dopracowując szczegóły i dodając plik konfiguracyjny. Użyta funkcja ceil ma za zadanie zaokrąglać w górę liczbę stron naszej paginacji, tak aby dla minimum 1 dodatkowego elementu utworzyć kolejną stronę.

Dzięki warunkowi OFFSET nasz system generował zapytanie zmieniając przesunięcie wraz ze zmianą kolejnych podstron paginacji:
Strona 1 – SELECT * FROM elements ORDER BY id ASC LIMIT 10 OFFSET 0
Strona 2 – SELECT * FROM elements ORDER BY id ASC LIMIT 10 OFFSET 10
Strona 5 – SELECT * FROM elements ORDER BY id ASC LIMIT 10 OFFSET 40

Jak można rozbudować ten system paginacji? W przypadku gdy mamy bardzo dużą ilość stron (50-100 lub więcej), nasza paginacja raczej nie zmieści się w obrębie strony i popsuje widok. Za pomocą instrukcji warunkowej IF można wygenerować dynamiczną paginację w postaci [1][2][3][4][5] ... [99][100][101][102], której widoczny zakres stron będzie aktualizowany wraz z przejściem do wyższej/niższej podstrony.

W razie pytań lub problemów zapraszam do dyskusji na naszym forum lub proszę zadać pytanie w komentarzu.

Programista, administrator - miłośnik nowych technologii. Jak każdy fachowiec w branży nie oprę się porannej kawie w towarzystwie świeżej prasy. Hobbystycznie fotografuję, psuję, naprawiam, lutuję. Czego nie lubię? Nieskromnych ludzi i brzydkiego kodu.

Send this to a friend