Invenzzia » Zasoby / Artykuły / OPT: szybki start

Szybki start z OPT

  • Opublikowany: 1 kwietnia 2009 09:28:00 GMT, aktualizacja ponad 3 lat temu przez Tomasz Jędrzejewski
  • en

Z tego artykułu dowiesz się, jak szybko rozpocząć korzystanie z Open Power Template 2 oraz jakie są jego podstawowe możliwości.

Open Power Template jest wolnodostępnym systemem szablonów dla PHP5. Jest częścią większego projektu, Open Power Libs, którego celem jest stworzenie zestawu zaawansowanych bibliotek dla frameworków oraz innych sieciowych aplikacji. W przeciwieństwie do wielu innych popularnych rozwiązań, OPT nie jest jedynie trywialną reimplementacją PHP ze zmienioną składnią, lecz udostępnia dobrze zaprojektowane i przemyślane narzędzia, które faktycznie upraszczają pracę z szablonami.

Czym są szablony?

Mieszanie kodu HTML z logiką skryptu przetwarzającą dane nie jest uważane za dobrą praktykę. W każdym większym projekcie zakłada się istnienie dwóch oddzielnych części: jednej odpowiedzialnej za przetwarzanie danych (zwanej warstwą logiki) oraz drugiej odpowiedzialnej za ich wyświetlanie (warstwa prezentacji). Najczęstszym rozwiązaniem oddzielenia ich od siebie jest użycie szablonów, prostych plików HTML z dodatkowym kodem osadzającym wygenerowane dane w odpowiednich miejscach. Dodatkową biblioteką zarządzającą szablonami jest system szablonów.

Szablony mogą być pisane w czystym PHP lub w specjalnym, dodatkowym język. W tym drugim przypadku system szablonów musi dodatkowo zapewnić parser do jego przetworzenia. Open Power Template należy do tej drugiej grupy systemów.

Szablony OPT i programowanie deklaratywne

PHP jest językiem imperatywnym. Oznacza to, że każde zadanie musisz dokładnie zaprogramować krok po kroku przy użyciu funkcji, pętli oraz wyrażeń. Programista ma pełną kontrolę nad przebiegiem wykonania programu/skryptu, lecz musi też dokładnie wiedzieć, jak dana czynność powinna być zrealizowana. Implementując wydajny algorytm czy framework, jest to pożądana właściwość, lecz przy pracy z prostymi szablonami sprawia nie lada kłopoty. Szablony najczęściej wymagają jedynie niedużej liczby dość prostych algorytmów, które jednak są dość uciążliwe w pisaniu za każdym razem, gdy chcemy je wykorzystać. Innym rozwiązaniem jest opakowanie ich w zaawansowany zestaw klas i funkcji za cenę mniejszej kontroli nad generowanym kodem PHP - wystarczy spojrzeć na frameworki, aby się o tym przekonać.

OPT promuje zupełnie inne podejście i styl programowania określany mianem deklaratywnego. Tutaj programista po prostu informuje parser, co chce osiągnąć i nic poza tym. Przykładami języków deklaratywnych jest HTML oraz SQL. Zauważmy, że jest to też bardzo wygodne przy pracy z szablonami. Pisząc je, nie musimy w ogóle martwić się o to, jak wszystko ma działać, innymi słowy, nie musimy martwić się o implementację. Przykładowo, chcąc wyświetlić listę, definiujemy jedynie, w którym miejscu ma się ona znaleźć i nadajemy jej jakąś unikalną nazwę. Podczas wykonywania szablonów OPT samodzielnie sprawdzi na podstawie danych ze skryptu, czm ta lista faktycznie jest, czy skrypt przypisał w ogóle jakieś dane do niej oraz co zrobić, by została ona poprawnie wyświetlona.

Język szablonów OPT został w pełni oparty o XML i jest właściwie zestawem dodatkowych znaczników i atrybutów. Ma on dzięki temu jeszcze jedną przewagę nad PHP - system szablonów rozumie Twój kod HTML. Jest on w stanie sprawdzić jego składnię i poinformować o wszelkich źle domkniętych znacznikach, zanim kod w ogóle opuści serwer oraz Twój dysk twardy. Wykorzystany parser szablonów jest bardzo elastyczny i pozwala na szczegółowe kontrolowanie poziomu zgodności z XML-em; od pełnej zgodności aż do tzw. "trybu tekstowego", gdzie wszystko poza znacznikami OPT traktowane jest jako statyczny tekst. Przydaje się to do generowania treści nieopartych na języku XML.

Krok 1: struktura katalogowa

OPT jest częścią serii bibliotek OPL i do pracy potrzebuje specjalnego komponentu zwanego OPL core. Wszystko, co jest niezbędne do pracy, jest dołączone do archiwum z OPT. Utwórz folder /opl gdzieś w drzewie katalogowym Twojego projektu i skopiuj tam zawartość katalogu /opt-2.x.x/lib ze ściągniętego archiwum. Powinieneś uzyskać strukturę podobną do poniższej:

/opl
/opl/Opl
/opl/Opl/Debug
/opl/Opt
/opl/Opt/Compiler
/opl/Opt/Format
/opl/Opt/Xml
/opl/Opt/Instruction
/opl/Opt/Output

/opl/Opl nie jest pomyłką. W tym katalogu zlokalizowane jest jądro bibliotek OPL.

Jeśli chcesz użyć w projekcie kolejnej biblioteki z serii OPL, po prostu skopiuj jej katalog do /opl. Zauważ, że tamta biblioteka najprawdopodobniej także będzie dostarczona z własną wersją jądra OPL. W większości przypadków nie powinno się nic stać, jeśli nadpiszesz już istniejące jądro, gdyż pomiędzy poszczególnymi wersjami nie ma aż tak dużych różnic. O wszelkich niekompatybilnościach możesz dowiedzieć się ze strony Invenzzia.

Open Power Template wymaga jeszcze dwóch dodatkowych katalogów. Załóżmy, że będą one nazywać się /templates oraz /templates_c, lecz możesz wybrać dla nich dowolną inną nazwę.

PHP musi posiadać prawa zapisu do drugiego z katalogów.

Krok 2: inicjacja OPL

Kolejnym krokiem jest załadowanie i zainicjowanie jądra OPL. Może to być zrobione poniższym kodem PHP:

require('/sciezka/do/opl/Opl/Base.php');
Opl_Loader::setDirectory('/sciezka/do/opl/');
Opl_Loader::register();

OPL korzysta z własnego autoloadera do zarządzania plikami PHP. Nazwy klas tworzone są według następującej konwencji: Opx_Costam_Jeszcze. Autoloader potrafi odróżnić "swoje" klasy od klas bibliotek innych twórców, które korzystają z tej samej konwencji (np. Zend Framework, Doctrine). Jednak pamiętaj, że nie możesz go pominąć - tamte autoloadery nie są w stanie znaleźć niektórych klas projektu.

Krok 3: inicjacja OPT

Możemy teraz zainicjować właściwy system szablonów. Można to zrobić za pomocą poniższego kodu PHP:

$tpl = new Opt_Class;
$tpl->sourceDir = './templates/';   // sciezka do /templates
$tpl->compileDir = './templates_c/';    // sciezka do /templates_c
$tpl->setup();

Jest to podstawowa konfiguracja biblioteki, lecz dostępnych opcji jest znacznie więcej. Można je ustawić w identyczny sposób, lub wczytać je z pliku INI lub tablicy przekazanych jako argument do metody setup().

OPT zgłasza błędy za pomocą wyjątków. Zalecane jest umieszczenie całego kodu korzystającego z OPT w bloku try...catch, który łapie wyjątki Opt_Exception. Możesz wykorzystać domyślny system obsługi błędów zapewniający dodatkowe informacje o każdym z komunikatów, które pomagają rozwiązać problem, lub też napisać swój własny:

catch(Opt_Exception $exception)
{
    $handler = new Opt_ErrorHandler;
    $handler->display($exception);
}

Krok 4: stwórz główny szablon

Pora na stworzenie kilku szablonów. Będziemy je zapisywać w katalogu /templates. Pierwszym z nich będzie szablon z ogólną strukturą kodu HTML:

<?xml version="1.0" ?>
<!-- layout.tpl -->
<opt:root>
<opt:prolog />
<opt:dtd template="xhtml10transitional"/>
<html>
<head>
    <meta http-equiv="Content-Type" parse:content="$contentType" />
    <title>{$title}</title>
</head>
<body>
<div id="header">
    <h1>Witaj na mojej stronie!</h1>
</div>
<div id="content">
    <opt:section name="modules">
        <opt:include from="modules">
            <p class="error">Przepraszamy, ten moduł nie może zostać załadowany</p>
        </opt:include>
    </opt:section>  
</div>
<div id="footer">
    <p>To jest przykładowy szablon OPT.</p>
</div>
</body>  
</html>
</opt:root>

Komentarz na początku pliku jest konwencją stosowaną w tym artykule do zaznaczenia nazwy szablonu. Możesz go pominąć u siebie. Pamiętaj także, aby wszystkie szablony zapisywać w folderze /templates

Poniżej możesz znaleźć objaśnienie poszczególnych konstrukcji:

  1. opt:root - poza znacznikiem <html> mamy kilka dodatkowych instrukcji, lecz XML zezwala na istnienie tylko jednego znacznika głównego w dokumencie. opt:root pomaga rozwiązać ten problem.
  2. opt:prolog - generuje prolog dla przeglądarki (w domyślnych ustawieniach prolog szablonu nie jest umieszczany w dokumencie wynikowym!)
  3. opt:dtd - generuje blok DOCTYPE dla XHTML 1.0 transitional.
  4. parse:content="$contentType" - poprzez zmianę przestrzeni nazw możemy powiadomić OPT, że wartość tego atrybutu musi być zbudowana dynamicznie przez skrypt. $contentType jest zwykłą zmienną, o identycznych właściwościach, jak w językach programowania.
  5. {$title} - jest to wygodny sposób na osadzanie zmiennych i wyrażeń w statycznym tekście. Alternatywne rozwiązanie to użycie instrukcji opt:put.
  6. opt:section - sekcje służą do tworzenia list. Ta definiuje listę nazwaną "modules".
  7. opt:include - dołącza i wyświetla w tym miejscu inny szablon. Dane dotyczące szablonu importowane są z elementów sekcji "modules". Jeśli dany szablon nie może być znaleziony, zostanie wyświetlona treść wewnątrz znacznika opt:include.

Przyjrzyjmy się bliżej sekcji:

<opt:section name="modules">
    <opt:include from="modules">
        <p class="error">Sorry, the requested module view could not be loaded.</p>
    </opt:include>
</opt:section>

Jak wspomnieliśmy, wszystkie "porządne" listy w OPT powinny być tworzone przy pomocy sekcji. Są to instrukcje deklaratywne, tak więc dokładna implementacja listy nie powinna nas w ogóle interesować. W obrębie znacznika opt:section definiujemy, jak powinien wyglądać pojedynczy element listy. W naszym przypadku, chcemy zwyczajnie zinterpretować go jako szablon do załadowania, tak więc korzystamy z opt:include. OPT wybierze odpowiednią implementację dla sekcji na podstawie informacji o formacie danych dostarczonych przez skrypt PHP.

Krok 5: utwórz kilka szablonów treści

Stwórzmy teraz kilka szablonów do wyświetlania konkretnej treści na naszej stronie:

<?xml version="1.0" ?>
<!-- template1.tpl -->
<opt:root>
    <h2>Moduł 1</h2>
    <p>Hej, jestem modułem 1.</p>
    <p>Dziś jest: {$date}</p>
</opt:root>
 
<!-- template2.tpl -->
<?xml version="1.0" ?>
<opt:root>
    <h2>Moduł 2</h2>
    <p>Jestem modułem 2</p>
    <p>Motto na dziś to: {$motto}</p>
</opt:root>

Krok 6: utwórz widoki i systemy wyjścia

W tym miejscu musimy się na chwilę zatrzymać, aby opisać, jak OPT parsuje szablony.

OPT model

Powyższy diagram ukazuje drogę, jaką przebywają dane, aby zostać w pełni wyświetlone. Na samej górze widoczna jest klasa Opt_Class. W innych systemach szablonów jest ona "klasą do wszystkiego", jednak w OPT jej rola zredukowana jest do zarządzania konfiguracją oraz ładowania wtyczek. Główna robota wykonywana jest przez tzw. widoki. Widok, reprezentowany przez obiekt klasy Opt_View składa się z danych ze skryptu oraz skojarzonego z nimi szablonu. Domyślnie, dane jednego widoku nie są widoczne przez inne, dzięki czemu nie musimy obawiać się przypadkowego nadpisania zmiennej przeznaczonej dla innego szablonu.

Na końcu drogi stoi obiekt systemu wyjścia OPT. Uruchamia on przetwarzanie danego widoku, umieszczając dane w szablonie i produkując kompletny dokument XML, a następnie wysyła go w jakieś miejsce. OPT dostarcza dwa podstawowe systemy wyjścia: Opt_Output_Http, który wysyła wyniki do przeglądarki i przy okazji zarządza nagłówkami HTTP, oraz Opt_Output_Return, który zwraca wynik z powrotem do skryptu.

Poniższy skrypt pokazuje, jak stworzyć widoki dla naszych szablonów i jak je poprawnie przetworzyć.

// Widok pojedynczego modułu
$moduleView = new Opt_View('template1.tpl');
$moduleView->date = date('d.m.Y');
 
// Widok szablolu głównego
$layoutView = new Opt_View('layout.tpl');
$layoutView->title = 'Some title';
$layoutView->contentType = 'text/html; charset=UTF-8';
$layoutView->modules = array(0 =>
    array('view' => $moduleView)
);

Konstruktor widoku pobiera za argument nazwę szablonu. Dane mogą być przypisane do zmiennych szablonu bardzo prosto, jako pola obiektu: $widok->nazwaZmiennej, ale mamy także kilka dodatkowych metod, które pozwalają np. przypisać im wartość poprzez referencję. Każdy szablon powinien otrzymać swój własny widok i to jest to, co powyższy skrypt robi. Tutaj stworzyliśmy widok dla jednego z modułów i przypisaliśmy wartość zmiennej date użytej w jego szablonie. Następnie utworzyliśmy widok dla szablonu głównego, gdzie zdefiniowaliśmy tytuł, informację o typie dokumentu dla znacznika <meta>, zaś na końcu przygotowaliśmy dane dla listy "modules". Zwróćmy uwagę, że do elementu listy pakujemy cały obiekt widoku. Gdybyśmy chcieli wyświetlić na stronie dwa moduły, kod powinien wyglądać następująco:

$layoutView->modules = array(0 =>
    array('view' => $module1View),
    array('view' => $module2View)
);

Nie wolno zapomnieć o umieszczeniu obiektu widoku w elemencie tablicy o nazwie view! Każdy element listy może składać się z kilku zmiennych, a instrukcja opt:include wymaga, aby widok zapisany był właśnie w zmiennej o nazwie "view".

Gdy widoki są gotowe, powinniśmy stworzyć obiekt systemu wyjścia i wysłać wszystko do przeglądarki:

$out = new Opt_Output_Http;
$out->setContentType(Opt_Output_Http::XHTML, 'utf-8');
$out->render($layoutView);

Zwróćmy uwagę, że ten system pomaga także w generacji poprawnych nagłówków HTTP.

Zakończenie

Zachęcamy do dalszego poznawania i poszerzania swojej wiedzy ponad napisany tutaj kod. Open Power Template promuje podejście niespotykane w innych systemach szablonów, jednak kiedy już odkryjesz, o co tak naprawdę w tym chodzi, odkryjesz, że praca z nim jest o wiele łatwiejsza.

Open Power Template 2.0 projects tutorial

Ten tekst udostępniony jest na licencji Creative Commons Uznanie autorstwa-Użycie niekomercyjne-Bez utworów zależnych 2.5 Polska.

Dodaj komentarz

Piszesz odpowiedź na komentarz

  • Nie będzie opublikowany | Gravatar obsługiwany
  • Wpisz tutaj nazwę naszej grupy.

Komentarze