Dažnai pasitaiko situacijų, kai reikia greitai ir paprastai realizuoti kokių nors elementų puslapiavimą. Yra daugybė įvairių būdų kaip galima išvesti pasiekiamų puslapių sąrašą: tiesiog išvesti iš eilės visus numerius, pateikti vartotojui drop-down’ą, rodyti mygtukus “Next” ir “Previous” ir kt. Šiame straipsnyje apžvelgsiu kelis puslapiavimo variantus ir pasirinksiu bei realizuosiu mano nuomone efektyviausią/patogiausią/user-friendliškiausią.

Puslapių išvedimas iš eilės

Išvedami skaičiai nuo 1 iki N, kur N – bendras puslapių skaičius; arba elementų intervalas [m-n], kuriame nurodoma kurie elementai bus rodomi. Toks puslapiavimas atrodo gražus ir patogus – bet kuriuo momentu galima pereiti į bet kurį puslapį ir iškarto pamatyti jo turinį. Eilinis internautas kasdien susiduria su tokiu puslapiavimu. Problema atsiranda tada, kai puslapių skaičius yra labai didelis. Visa puslapių eilė nebetelpa į vieną eilutę, reikalauja daug vietos tinklapyje. Tarp tokio didelio puslapių numerių skaičiaus lengva pasiklysti, nebelieka jokio navigacijos patogumo. Taigi šis puslapiavimo būdas tinka tada, kai esate įsitikinę, jog puslapių skaičius nepataps ant tiek didelis, kad sugadintų visą svetainės vaizdą.

Drop-down sąrašas

Toks puslapiavimo būdas išpsrendžia vieną 1-ojo būdo problemą – vietos trūkumas. Drop-down’as užima labai mažai vietos, kiek puslapių numerių bereikėtų atvaizduoti. Ir taip pat bet kuriuo momentu galima įjungti bet kurį vartotoją dominantį puslapį. Vizualiai puslapių numeriai išdėstyti vertikaliai, kas turėtų būti patogu vartotojui. Tačiau vėl gi, jeigu puslapių skaičius būtų gan didelis, į tokį drop-down sąrašą būna įterpiamas scroll-bar’as, arba blogiausiu atveju puslapių numerių, kurie yra žemiau matomos srities tiesiog nesimato. Kas liečia patogumą – taip pat lengva pasiklysti tarp didelio numerių skaičiaus. Sprendimas galėtų būtų koks nors puslapių grupavimas, pavyzdžiui, kas dešimtą elementą ryškinti, atskirti linija ar pan., tačiau tokių puslapiavimo realizacijų dažnai matyti netekdavo.

Pasirinktų numerių išvedimas

Mano nuomone optimalus ir patogiausias puslapių numerių išvedimo būdas. Tai toks puslapiavimas, kai vartotojui rodomi keli puslapių numeriai aplink aktyvų puslapį, o tie numeriai, kurie yra kiek nutolę nuo dabartinio, rodomi ne visi, bet tik kai kurie (pavyzdžiui, kas 10-as arba 20-as puslapis). Google’as nepadėjo susirasti konkretaus tokio puslapiavimo būdo pavadinimo, todėl daviau jam pravardę “pasirinktų numerių” :) jei kažkas iš skaitytojų žino jo pavadinimą, praneškite komentaruose.

Keičiant tokio puslapiavimo parametrus galima nustatyti kiek maksimaliai vietos jis galės užimti. Pavyzdžiui, rodyti tik 3 labiau nutolusius numerius dešimtimis, rodyti po 5 puslapius aplink dabartinį ir pan. Dažnai paliekami mygtukai, kad bet kuriuo momentu vienu mygtuko paspaudimu būtų galima pasiekti pirmą ir paskutinį puslapį. Yra sukurta nemažai bibliotekų ir turinio valdymo sistemų išplėtimų tokiam puslapiavimo išvedimui. Tačiau tokios bibliotekos, skirtos šio paprasto funkcionalumo įgyvendinimui būna didelės su daug naudingų, bet retai naudojamų funkcijų – jų pritaikymui reikia sugaišti laiko, tad pasidalinsiu savo paprasta PHP puslapiavimo funkciją.

<?php
    /**
     * @desc Generates paging links. 
     * @example print generate_paging_links('http://www.example.com/?page=%page_number%', 40);
     * 
     * @param string $url_structure URL structure for page link. %page_number% placeholder is replaced with page number
     * @param int $total_pages Total pages count 
     * @param array $settings (optional) Associative array of settings. Acceptable keys:
     *	current_page => 1,
     *	current_class => current,
     *	show_around => 5,
     *	tens => 10,
     *	dots => ...
     * @return string HTML string of <a> elements
     */
     function generate_paging_links($url_structure, $total_pages, $settings = array() ) {
    	// setting default values
    	$defaults = array(
    		'current_page' => 1, 
			'current_class' => 'active', 
			'show_around' => 5, 
			'tens' => 10, 
			'dots' => '...',
			'previous_page' => '&lt;',
			'next_page' => '&gt;'
    	);
    	$settings = array_merge($defaults, $settings);
		if (intval($settings['tens']) < 1) $settings['tens'] = 1;

    	$html = "";
    	$printed_dots = false;

    	// add `previous page` button if needed
    	if ($settings['current_page'] != 1) {
    		$html = '<a href="'.str_ireplace('%page_number%', ($settings['current_page'] - 1), $url_structure).'">'.$settings['previous_page'].'</a> ';
    	}
    	foreach (range(1, $total_pages) as $p) {

    		$have_to_place = false;

			/* conditions when have to output page number */

    		// when it's very first or last page
    		if ($p == 1 || $p == $total_pages)
    			$have_to_place = true;

    		// when it's close enough to current page (by show_around)
    		if (abs($settings['current_page'] - $p) <= $settings['show_around']) 
    			$have_to_place = true;

			// when have to show tens
			if ($p % $settings['tens'] == 0)
				$have_to_place = true;

    		if ($have_to_place) {
    			$html .= '<a href="'.str_ireplace('%page_number%', $p, $url_structure).'"'.(($p == $settings['current_page']) ? ' class="'.$settings['current_class'].'"' : '').'>'.$p.'</a> ';
    			$printed_dots = false;
    		} elseif (!$printed_dots) {
    			$html .= $settings['dots'];
    			$printed_dots = true;
    		}
    	}
		// add `next page` button if needed
		if ($settings['current_page'] != $total_pages) {
			$html .= '<a href="'.str_ireplace('%page_number%', ($settings['current_page'] + 1), $url_structure).'">'.$settings['next_page'].'</a>';
    	}

    	return $html;
    }
?>

Funkcija yra be galo paprasta, bet naudinga. Pirmu argumentu paduodama puslapių peržiūros URL struktūra, kur žodelis %page_number% pakeičiamas atitinkamu puslapio numeriu. Antras argumentas – bendras puslapių skaičius, o trečias – atvaizdavimo ir kiti nustatymai:

  • current_page – aktyvus puslapis, kurio <a> elementui bus priskirta current_page nustatyme nurodyta CSS klasė;
  • show_around – kiek elementų aplink aktyvų puslapį bus rodoma;
  • tens – kas kiek nutolusių elementų rodyti (pvz. esant reikšmei 10 bus rodomi nutolę puslapiai: 10, 20, 30 ir t.t.);
  • dots – tekstas arba HTML kodas, kurį naudoti išvedant tarpus tarp nutolusių puslapių;
  • previous_page ir next_page – HTML kodas, kuris bus talpinamas navigacijos į sekantį ir prieš tai einantį puslapį nuorodose, atitinkamai.