Wiemy już jak utworzyć i wyświetlić prosty widok, pora przejść do bardziej złożonych zagadnień.

Fabryka widoków

Poza tworzeniem obiektów poprzez operator new istnieje alternatywna metoda. Jest to wzorzec projektowy nazywany fabryką abstrakcyjną. Więcej o tym wzorcu możesz przeczytać na Wikipedii, my natomiast skupimy się na tym co nam daje takie rozwiązanie w przypadku widoków.

Sam obiekt tworzymy wywołując statyczną metodę factory() z podobnymi parametrami co konstruktor:

1
$view = View::factory('home');

Zastanawiasz się pewnie czym to się różni od operatora new, bo przecież oba tworzą i zwracają obiekt klasy View. Oczywiście jest tak, z jedną różnicą. Wywołanie metody fabryki pozwala na łańcuchowanie (chaining) metod tej klasy bezpośrednio po jej utworzeniu.

Tradycyjną metodą:

1
2
3
$view = new View('home');
$view->set('title', 'Strona główna');
$view->bind('news', $news);

To samo z użyciem fabryki:

1
2
3
$view = View::factory('home')
	->set('title', 'Strona główna')
	->bind('news', $news);

Jak widzisz drugi zapis jest krótszy i bardziej czytelny.

Rozszerzone dodawanie zmiennych

Metoda set()

W poprzednim artykule zmienne lokalne przekazywaliśmy w poniższy sposób:

1
$view->title = 'Witaj!';

Podobne działanie posiada metoda set(), której zapis jest następujący:

1
2
3
4
$view->set('title', 'Witaj!');
// lub
$msg = 'Witaj!';
$view->set('title', $msg);

Jako pierwszy parametr podajemy nazwę zmiennej, której będziemy używać wewnątrz widoku, natomiast drugi parametr jest jej wartością przekazaną bezpośrednio bądź poprzez zmienną.

Metoda set_global()

Jak sama nazwa wskazuje, widok otrzymuje zmienną o zasięgu globalnym, przez co może być wykorzystywana zarówno w widoku głównym jednocześnie poprzez jego podwidoki.

1
$view->set_global('zmienna_widoku', $zmienna);

Więcej na temat zasięgu zmiennych przeczytasz w dalszej części artykułu.

Metoda bind()

Podobnie jak metoda set, bind działa w obrębie widoku, w którym został wywołany. Różnica polega jednak na tym, że zamiast wartości, przekazywana jest referencja do zmiennej. Co to oznacza w praktyce? Spójrz na poniższy przykład:

1
2
3
4
5
6
7
$sample_var = 10;
$view = View::factory('sample')
	->set('sample_set', $sample_var)
	->bind('sample_bind', $sample_var);
$sample_var = 20;
$view->render(true);
$sample_var = 30;

Widok:

1
2
Set = <?php echo $sample_set ?><br />
Bind = <?php echo $sample_bind ?>

Wynikiem powyższego będzie:

Set = 10
Bind = 20

W obu przypadkach przekazana została zmienna $sample_var, której wartość początkowa wynosi 10. Metoda set przekazała aktualną w danym momencie wartość zmiennej $sample_var i na tym skończyła się jej rola. Bind natomiast dała wskazanie na samą zmienną, co oznacza, że wszystkie operacje wykonane na $sample_var po przypisaniu jej do widoku ale przed wywołaniem metody render zostaną uwzględnione a wyświetlona będzie ostatnia zmiana. Można to wykorzystać na przykład w przypadku gdy zmienna jeszcze nie została zainicjowana.

1
2
$view->bind('sample_bind', $sample_var);
$sample_var = 20;

Widoki, podwidoki

Większość witryn składa się z elementów, które powtarzają się na każdej z podstron: nagłówek z logo, menu, stopka. Natomiast zmianom ulega tylko środkowa część prezentacji. Aby uniknąć ciągłego przepisywania tej samej zawartości do wszystkich widoków, możliwe jest stworzenie widoku głównego, szablonowego, do którego jako zmienna przekazywany jest kolejny widok. Zobrazuję to na przykładowym kodzie:

1
2
3
$view = new View('template');
$view->content = new View('home');
$view->render(true);

Można to również zapisać następująco:

1
2
3
4
$view = new View('template');
$home = new View('home');
$view->content = $home;
$view->render(true);

Pamiętaj jednak, że metodę render stosujemy tylko dla widoku bazowego, który jest najwyżej w hierarchii, pozostałe będą przetwarzane automatyczne.

Przykładowe pliki widoków wyglądają następująco:

1
2
3
4
5
6
<!-- application/views/template.php -->
<html>
<body>
	<?php echo $content ?>
</body>
</html>
1
2
<!-- application/views/home.php -->
Witaj, jestem Kohany(m) widokiem!

Efektem powyższych operacji będzie następujący kod html postaci:

1
2
3
4
5
6
7
<!-- application/views/template.php -->
<html>
<body>
	<!-- application/views/home.php -->
	Witaj, jestem Kohany(m) widokiem!
</body>
</html>

Co w oknie przeglądarki przełoży się na napis znany już z poprzedniej części kursu:

Witaj, jestem Kohany(m) widokiem!

Zasięg zmiennych

Lokalne

Zmienna ustawiona poprzez metodę set() bądź poprzez bezpośrednie przypisanie zmiennej do obiektu działa tylko w obrębie danego widoku i nie jest widoczny poza niego. Czyli jeśli utworzymy dwa widoki, np. widok1 oraz widok2 i w obu przypiszemy zmienną o tej samej nazwie, np. $zmienna, to będą to dwie odseparowane od siebie wartości.

1
2
3
4
5
6
7
$view1 = View::factory('widok1')
	->set('zmienna', 'pierwszy')
	->render(true);
 
$view2 = View::factory('widok2')
	->set('zmienna', 'drugi')
	->render(true);

Globalne

W przypadku użycia metody set_global() zmienna ustawiona będzie dostępna w każdym widoku.
Przykładowo mamy w kontrolerze widok $view i dla niego przypisaną zmienną globalną $test_var

1
2
3
4
5
$view = View::factory('view_test')
	->set_global('test_var', 'Test!')
	->set('test1', View::factory('test1'))
	->set('test2', View::factory('test2'))
	->render(TRUE);

Oraz widoki:

1
2
3
4
<!-- application/views/view_test.php -->
	<?php echo $test_var ?><br />	<!-- wyświetla zmienną w widoku głównym -->
	<?php echo $test1 ?><br />	<!-- wyświetla podwidok test1 -->
	<?php echo $test2 ?><br />	<!-- wyświetla podwidok test2 -->
1
2
<!-- application/views/test1.php -->
<?php echo $test_var ?>
1
2
<!-- application/views/test2.php -->
<?php echo $test_var ?>

Efektem tych poleceń jest wyświetlenie 3 razy tej samej zmiennej $test_var.

Test!
Test!
Test!

Dostęp poprzez $this

Widoki w Kohanie są tak skonstruowane, że zawierają się w tej samej przestrzeni nazw co kontroler je wykonujący. Daje to nam dostęp do pól i metod tego kontrolera poprzez zmienną $this.

Przykładowo mamy kontroler test:

1
2
3
4
5
6
7
8
class Test_Controller extends Controller {
	public $sample_var = 'Hello!';
 
	public function index()
	{
		$view = View::factory('test')->render(true);
	}
}

Oraz widok test.php:

1
Zmienna sample_var = <?php echo $this->sample_var ?>

Wykonanie powyższego kontrolera da nam wynik:

Zmienna sample var = Hello!

Ta metoda dostępu do danych nie jest zalecani można ją powodzeniem zastąpić wcześniej wymienionymi metodami: set(), set_global(), bind().

Pozostałe operacje na widokach

Metoda set_filename()

Metoda set_filename() pozwala na przypisanie pliku do widoku w przypadku gdy nie został on podany w momencie tworzenia obiektu, bądź zmianę wcześniej przypisanej nazwy.

1
2
3
4
5
$view = View::factory()
	->set('title', 'Witaj!');
...
$view->set_filename('template');
$view->render(TRUE);
1
2
3
4
5
$view = View::factory('template')
	->set('title', 'Witaj!');
...
$view->set_filename('another_template');
$view->render(TRUE);

Wszystkie zmienne przypisane do widoku będą użyte w ostatnio przypisanej nazwie pliku i ten plik widoku zostanie wyświetlony.

Z powyższej metody można korzystać na przykład w przypadku sprawdzania czy jest ktoś zalogowany. Jeśli warunek będzie spełniony zostanie utworzony widok z interesującymi nas danymi. W przeciwnym wypadku nazwa pliku zostanie zmieniona na widok z komunikatem błędu.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$view = View::factory('template');
// sprawdź czy użytkownik jest zalogowany
if ($logged_in)
// jeśli tak, wykonaj operacje na widoku
{
	$view->set('title', 'Tajne dane');
	...
}
else
// jeśli nie, pokaż komunikat błędu
{
	$view->set_filename('not_logged');
}
$view->render(TRUE);

Metoda is_set()

Jeśli nie masz pewności czy dana zmienna została przypisana już do widoku, to można to sprawdzić właśnie za pomocą metody is_set(). Wystarczy podać jako parametr nazwę zmiennej a funkcja sprawdzi czy jest zmienną lokalną danego widoku bądź też globalną dla wszystkich. Jako wynik otrzymasz wartość logiczną.

1
2
3
4
5
6
7
8
9
10
11
$view = View::factory('sample_view')
	->set('sample_var', 'Kohana');
 
if ($view->is_set('sample_var'))
{
	echo 'Zmienna istnieje!';
}
else
{
	echo 'Zmienna nie istnieje!';
}

Ponieważ wcześniej zadeklarowaliśmy zmienną sample_var, to metoda is_set() zwróci wartość logiczną true, w wyniku czego otrzymamy komunikat:

Zmienna istnieje!

Możliwe jest też sprawdzenie kilku zmiennych na raz, wtedy jako parametr podajemy tablicę z ich nazwami

1
2
3
4
$view = View::factory('sample_view')
	->set('sample_var', 'Kohana');
 
echo Kohana::debug($view->is_set(array('sample_var', 'another_var')));

Wynik:

(array) Array
(
[sample_var] => 1
[another_var] =>
)

Jak widać powyżej metoda is_set() zwróci tablicę, gdzie kluczem jest nazwa zmiennej, któremu przypisana będzie wartość logiczna mówiąca o istnieniu danej zmiennej.