Pierwsze starcie

Po poprawnym zainstalowaniu Kohany możemy czuć się trochę zdezorientowani. Nie wiadomo od czego zacząć, jak to ugryźć, a naszym oczom wyświetla się tylko hello,world!
Postaram się trochę rozjaśnić. Naszym zadaniem będzie stworzenie prostego szablonu. Szkielet strony będzie zawierał u góry top, po lewej menu, po prawej treści które będą się zmieniać w zależności od podstrony i stopkę. Do dzieła.
Myślę, że nie trzeba wyjaśniać co to jest Model, Widok, Kontroler, ale tak pokrótce: W modelu mamy operacje na bazie danych (w tym poradniku nie będziemy używać), w kontrolerach mamy wszystkie operacje jak sprawdzanie czy formularz został wysłany czy wczytywanie widoków, natomiast w widokach to co będzie wyświetlane (strona główna, podstrony).

Zalecam stosować angielskie nazwy kontrolerów w liczbie pojedynczej, np. Article. Nazwy plików muszą być takie jak nazwa kontrolera, tyle że z małej litery.

Zacznijmy od stworzenia głównego kontrolera, który będzie obsługiwał szablon strony. Nazwijmy go default. Nazwa pliku powinna być taka jak nazwa kontrolera. Z racji iż będzie to kontroler szablonu to będzie on rozszerzał kontroler Template:

class Controller_Default extends Controller_Template

Deklarujemy zmienną template i przypisujemy do niej widok default. W tym widoku będzie szablon strony (kod HTML)

public $template = 'default';

W funkcji before umieszczamy to co będzie przed wczytaniem kontrolera, natomiast w funkcji after, to co po wczytaniu. W naszym szablonie w before zadeklarujemy odpowiednie zmienne ze stylami i skryptami, a w after przypiszemy (załadujemy) do nich pliki. Dodatkowo pokazałem jak powinien wyglądać konstruktor (była zmiana od wersji 3.1.X), w nim też możemy wykonywać pewne czynności, ale tu zostanie pusty (można go usunąć).
Ostatnią rzeczą jest wczytanie w akcji index do szablonu default podwidoku home, wyświetlającego stronę główną w dynamicznej części po prawej stronie naszego szablonu i ustawienie odpowiedniego tytułu. Akcja index to akcja defaultowa wywoływana po wpisaniu w przeglądarce /kohana/kontroler lub /kohana/kontroler/index, nasz deflautowy kontroler i akcja index będzie wyświetlany po wpisaniu http://kohana (jeśli mamy ustawiony host virtualny o nazwie kohana).

Kontroler default: /application/classes/controller/default.php

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Default extends Controller_Template {

    public $template = 'default';

    public function  __construct(Request $request, Response $response) {
        parent::__construct($request, $response);
    }

    public function before() {
      parent::before();

        if ($this->auto_render)
        {
            // Initialize empty values
            $this->template->title = '';
            $this->template->description = '';
            $this->template->content = '';

            $this->template->styles = array();
            $this->template->scripts = array();
            $this->template->top_tab = '';
        }
    }

    public function after() {
        if ($this->auto_render)
        {
                $styles = array(
                        'media/css/style.css' => 'screen',
                );

                $scripts = array(
                        'media/js/jquery-1.5.1.min.js',
                );

                $this->template->styles = array_merge( $this->template->styles, $styles );
                $this->template->scripts = array_merge( $this->template->scripts, $scripts );
        }
        parent::after();
    }

    public function action_index() {
        $this->template->title = __('Home');
        $this->template->content='home';
    }
}

Zmienna top_tab w before to przykładowa zmienna. Aby ją wyświetlić w widoku wystarczy dać echo $top_tab; Do widoków możemy przesyłać także obiekty i odwoływać się w widoku do atrybutów: $top_tab->atrybut, albo przesyłać tablice i w pętli foreach listować dane.
Tytuł Home w takim dziwnym nawiasie, oznacza, że będzie można go przetłumaczyć na inne języki, jeśli będziemy mieć tylko pl, to przypisujemy =’Tytuł’;
Możemy ustawić jeszcze opis strony w tagach meta description (Ważne do pozycjonowania), taki opis powinien mieć długość do ~170znaków. Dodajemy do akcji index.

$this->template->description = 'Opis strony';

Pora na stworzenie widoku default. Będzie w nim szkielet strony HTML. Trzeba pamiętać, aby w kontrolerze w akcji przesłać wszystkie zmienne, które występują w widoku, w naszym przypadku musi to być $content, gdyż pozostałe zostały defaultowo zadeklarowene z pustą wartością.

Widok default: /application/views/default.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Content-Language" content="pl"/>
    <meta name="robots" content="index, follow" />
    <meta name="description" content="<?php echo $description?>" />
    <link type="image/x-icon" href="/media/img/favicon.ico" rel="shortcut icon" />
    <title><?php echo 'Kohana - '.$title ?></title>
    <?php foreach ($styles as $file => $type) echo HTML::style($file, array('media' => $type)), "\n" ?>
    <?php foreach ($scripts as $file) echo HTML::script($file), "\n" ?>

  </head>
  <body>
      <div id="top">
          <div class="w1000 ofh">
              <h1><a href="/" title="Title">Title</a></h1>
          </div>
      </div>
      <div class="w100 bg-white">
          <div class="w1000 ofh mh600">
              <div class="w30 fll mh600 bg-dadada">
                  <h2>Menu:</h2>
                  <a href="/">Home</a><br />
                  <a href="/article">Articles</a><br />
              </div>
              <div class="w70 fll mh600 bg-f1f1f1">
                  <?php include Kohana::find_file('views', $content);?>
              </div>
          </div>
      </div>
      <div class="w1000 ofh">
          <div id="footer">Footer &copy; 2011 </div>
      </div>
  </body>
</html>

Musimy jeszcze stworzyć katalogi z css, js, img. Przechodzimy do głównego folderu w którym jest Kohana i tworzymy folder /media a w nim 3 foldery: /css, /js i /img. Do js wrzucamy np. plik z biblioteką jquery: jquery-1.5.1.min.js, do img np. logo strony, a do css nasz styl:
Styl style.css: /media/css/style.css

root {
    display: block;
}

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
    font-family:tahoma,verdana,arial,sans-serif;
    font-size:11px;
    line-height: 1.3;
    color: #333333;
    background-color: yellow;
}
img {border: 0;}
p {margin-top: 0}
a {text-decoration:none;}
a:hover {text-decoration:none;}

.w1000{
    margin: 0px auto;
    width: 1000px;
}

#top{
    width: 100%;
    background: blue;
    height: 40px;
    padding-top: 10px;
}
#top h1 a, h1 a:hover {color: #fff;text-decoration:none;}

#footer{
    width:60%;
    height: 20px;
    margin: 0px auto;
    padding-top: 10px;;
    text-align: center;
    color: #808080;
}
#footer a {color: #808080}
#footer a:hover {color: #333}

.center{
    margin: 0px auto;
    text-align: center;
}
.green {color: green;}
.red{color: red;}
.black {color: black;}
.white{color: white;}
.gray{color: gray;}
.bg-white{background: #fff}
.bg-dadada{background: #dadada}
.bg-f1f1f1{background: #f1f1f1}

h1 { margin: 0px; font-size:22px;}
h2 { margin: 0px; font-size:18px; }
h3 { margin: 0px; font-size:14px;}
h4 { margin: 0px; font-size:12px;}
h5 { margin: 0px; font-size:11px;}
h6 { margin: 0px; font-size:10px;}

.mrg20t{margin-top: 20px}
.mrg10l{margin-left: 10px;}
.mrg10r{margin-right: 10px;}
.mrg10t{margin-top: 10px;}
.mrg10b{margin-bottom: 10px;}
.mrg10{margin: 10px;}
.mrg5l{margin-left: 5px;}
.mrg5r{margin-right: 5px;}
.mrg5t{margin-top: 5px;}
.mrg5b{margin-bottom: 5px;}
.mrg5{margin: 5px;}
.pad5{padding: 5px;}
.fll{float: left}
.flr{float: right}
.in_w{
    float: none;
    left: auto;
    width: auto;
}
.w10{width: 10%;} .ml10{margin-left: 10%}
.w15{width: 15%;} .ml15{margin-left: 15%}
.w20{width: 20%;} .ml20{margin-left: 20%}
.w25{width: 25%;} .ml25{margin-left: 25%}
.w30{width: 30%;} .ml30{margin-left: 30%}
.w35{width: 35%;} .ml35{margin-left: 35%}
.w40{width: 40%;} .ml40{margin-left: 40%}
.w45{width: 45%;} .ml45{margin-left: 45%}
.w50{width: 50%;} .ml50{margin-left: 50%}
.w55{width: 55%;} .ml55{margin-left: 55%}
.w60{width: 60%;} .ml60{margin-left: 60%}
.w65{width: 65%;}
.w70{width: 70%;}
.w75{width: 75%;}
.w80{width: 80%;}
.w85{width: 85%;}
.w90{width: 90%;}
.w100{width: 100%;}
.ofh{overflow: hidden}
.mh600{min-height: 600px}
.mhinherit{min-height: inherit}
.dispin{display: inline}

Następnie edytujemy /application/bootstrap.php aby standardowo wczytywał się kontroler defautl (zmieniamy Route::set), przy okazji usuwamy index.php z linku (dodajemy w Kohana::init)

Kohana::init(array(
	'base_url'   => '/',
        'index_file' => FALSE,
));

Route::set('default', '(<controller>(/<action>(/<id>)))')
	->defaults(array(
		'controller' => 'default',
		'action'     => 'index',
	));

Tworzymy widok ładowany do dynamicznej części na stronę główną
Widok home: /application/views/home.php

<h1>Home</h1>
<p>Lorem ipsum dolor sit amet</p>

Po tych czynnościach po wywołaniu naszej strony /kohana naszym oczom powinna się ukazać strona:

Stwórzmy jeszcze drugi kontroler article do obsługi artykułów, aby wywołać jego akcję index wystarczy w przeglądarce wywołać /kohana/article. Kontroler Article będzie teraz rozszerzał kontroler Default.

Kontroler article: /application/classes/controller/article.php

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Article extends Controller_Default {
     public function action_index() {
        $this->template->title = __('Article');
        $this->template->content='article';
    }

    public function action_add() {
        $this->template->title = __('Add article');
        $this->template->content='article_add';
    }
}
?>

Kontroler ten posiada 2 akcje, po wywołaniu index – /kohana/article dzięki nadpisaniu content ($this->template->content=’article’;) wyświetlimy po prawej nowy widok

Widok article: /application/views/article.php

<h1><?php echo $title?></h1>
<p><a href="/article/add">Add article</a></p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>

A po wywołaniu /kohana/article/add, wykona się akcja add i wyświetli się widok article_add
Widok article_add: /application/views/article_add.php

<h1><?php echo $title?></h1>
<p>Lorem ipsum dolor sit amet. Lorem ipsum.</p>

Tak oto stworzyliśmy prosty szablon strony z ładowanymi widokami!
Style.css zawiera dodatkowe, niewykorzystane w tym przykładzie style.
Szablon ten (folder application i media) można pobrać: Szablon ko3.1.2 (595)

20 Odpowiedzi :“Pierwsze starcie”

  1. W napisał:

    Archiwum szablonu jest uszkodzone, nie idzie rozpakować.

  2. Mariusz napisał:

    Poprawiłem plik, coś z kompresją gz na serwerze nie tak, bo na innej domenie też miałem z tym rozszerzeniem problemy.

  3. fajnie napisał:

    fajnie, szkoda że nie od ‚podstaw podstaw’ bo tak czy siak aby się połapać trzeba już w tym siedzieć, a miałem nadzieje na coś aktualnego jeśli chodzi o wersji i dla wszystkich

  4. Mariusz napisał:

    Moim zdaniem warto spróbować przez praktykę w przypadku Kohany. Na początku polecałbym dodać do powyższego przykładu jakiś własny kontroler z akcjami, a w nich załadować tylko nowe widoki (analogicznie jak w przykładzie). Później zmodyfikować układ strony w widoku default łącznie z css. Później w jednej akcji można dodać jakiś warunek i odpowiednie widoki np. w zależności od wartości z linku.

  5. fajnie napisał:

    nie do końca mnie zrozumiałeś, chodzi mi o to, że jak trafiłem tutaj myślałem, że jestem w 7 niebie, bo od podstaw cała nauka kohany na wersji najnowszej 3.1x …., a to jest juz dla kogos kto robil w kohanie …

  6. Mariusz napisał:

    To __construct() to jest konstruktor, można przy tworzeniu obiektu wykonać w nim pewne czynności (jak utworzenie sesji czy przechowywanie danych o zalogowanym użytkowniku) i tutaj jest tylko po to, aby pokazać jak powinien wyglądać w kohanie bo od wersji 3.1.X była zmiana, nic w nim nie ma więc nic nie powoduje, można go usunąć albo zakomentować.

    $this->template->title = __('Home'); 
    

    Oznacza, że do szablonu przesyłamy zmienną $title o wartości Home, ten zapis __(”) oznacza, że to co jest w środku można będzie przetłumaczyć za pomocą plików językowych. Jeśli mamy tylko 1 język, np. PL to tak należy przypisać do zmiennej treść:

    $this->template->title = 'Strona główna';
    
  7. fajnie napisał:

    po za tym moglbys komentowac kod, co co robi itd.

    na czym polega to public function __construct(Request $request, Response $response) {
    parent::__construct($request, $response);
    }

    dlaczego później sie odwołujesz tam przez __(home) itp
    to chodzi, ze klasa dziedziczy po straszej ?
    duzo neijasnosni

  8. Też Mariusz napisał:

    Świetny blog – dużo mi pomógł.
    Poproszę o kolejne notki :)

  9. Mariusz napisał:

    Cieszy mnie to, że na coś się przydał :)
    Ostatnio cierpię na deficyty czasu… to praca, to studia, to pisanie pracy mgr. Jak znajdę wolną chwilę to na pewno coś się pojawi.

  10. Czuję nie dosyt. Z chęcią bym przeczytał jak utworzyć system użytkowników w tym logowanie i wylogowanie uprawnienia oraz panel admina

  11. Mariusz napisał:

    To już wiem o czym będzie następny wpis… Najpierw chciałem pokazać jak posługiwać się akcjami i widokami czy stworzyć własny szablon. Takie podstawy pozwalają tworzyć np. strony firmowe. Bardziej rozbudowane przykłady będą się ciągle pojawiać.

  12. Wiesz co by było fajnie zobaczyć. Zrobienie tutorialu powiedzmy zwykłego bloga, ale tak żeby było na tip top z panelem admina, obsługą userów itp. Chodzi mi to o uzyskanie tutoriala na wzór jaki SENSIO LABS zrobili dla Symfony – Jobeet.

  13. Mariusz napisał:

    OK, to na razie dodam jeszcze logowanie/rejestrację i moduł panelu admina. Potem zbiorę to wszystko ‚do kupy’ i zrobię takiego bloga tak aby zebrać wiedzę z kilku wpisów w jednym.

  14. Podoba mi się :)

  15. Kiedy będzie coś nowego?:)

  16. Mariusz napisał:

    Brakuje mi czasu obecnie, ale na dniach postaram się coś skrobnąć :)

  17. Mógłbyś wytłumaczyć, po co w metodach before() i after() stosuje się if($this->auto_render) ?

  18. Mariusz napisał:

    auto_render w kontrolerze Template odpowiada za automatyczne ładowanie szablonu, a dzięki automatycznemu ładowaniu nie trzeba używać $this->response->body(), wystarczy np. nadpisać zmienną template, aby wczytać nowy widok.
    Wen wpis sprawdza, czy jest ustawione automatyczne ładowanie, jeśli tak, to w after() i before() są deklarowane zmienne i przypisywane do nich wartości. Gdy nie nadpisujemy tych zmiennych nie musimy zatem pamiętać o przesłaniu ich do widoku (występują w głównym szablonie, zatem i w każdym podrzędnym).
    Jeśli nie byłoby włączonego automatycznego ładowania w Template, nie wysyłałoby przy każdym wyświetleniu strony defaultowych zmiennych.

  19. Pablo napisał:

    Świetnie!! Najlepszy blog o Kohanie!

    „Wiesz co by było fajnie zobaczyć. Zrobienie tutorialu powiedzmy zwykłego bloga, ale tak żeby było na tip top z panelem admina, obsługą userów itp. Chodzi mi to o uzyskanie tutoriala na wzór jaki SENSIO LABS zrobili dla Symfony – Jobeet.”

    Świetny pomysł. Dziękuje!
    Fajnie że wszystko jest od podstaw

    Pozdrawiam i czekam na kolejne wpisy

Dodaj komentarz

Dodając kod PHP używaj tagów: [php][/php]

*