Open Power Template
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Open Power Template

  • 4,026 views
Uploaded on

Autor: Tomasz "Zyx" Jędrzejewski...

Autor: Tomasz "Zyx" Jędrzejewski

Prelekcja składać się będzie z dwóch części. Pierwsza poświęcona będzie problematyce systemów szablonów jako bibliotek budzących wiele kontrowersji. Odpowiemy sobie na pytania, czym te biblioteki naprawdę są, jaki mają potencjał oraz jakie mity o nich pokutują na ich temat nawet wśród dobrych programistów. W drugiej części skupimy się w całości na systemie szablonów Open Power Template, pokazując jego główne założenia, filozofię, najciekawsze rozwiązania oraz przyszłość tego ambitnego projektu. Prelekcja będzie ilustrowana praktycznymi przykładami oraz spostrzeżeniami zgromadzonymi w trakcie wielu lat badania i projektowania tego typu systemów.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
4,026
On Slideshare
3,942
From Embeds
84
Number of Embeds
1

Actions

Shares
Downloads
37
Comments
0
Likes
0

Embeds 84

http://www.slideshare.net 84

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Open Power Template 2 Tomasz Jędrzejewski Grupa Invenzzia PHPCon Polska – 21 maja 2010
  • 2. Czym są systemy szablonów?
    • System szablonów – biblioteka zajmująca się generowaniem kodu HTML w aplikacji WWW.
    • 3. Dane dostarcza aplikacja.
    • 4. Struktura kodu zawarta jest w tzw. szablonach .
    • 5. Szablon mówi, gdzie i jak w kodzie HTML wyświetlić dane.
  • 6. Elementy systemu szablonów
    • Interfejs programisty – zbiór klas oraz interfejsów do współpracy z aplikacją.
    • 7. Język szablonów – narzędzie do pisania szablonów HTML.
  • 8. Dwa podejścia do problemu języka szablonów PHP jako język szablonów Szablony pisane są w tym samym języku, co aplikacja, wzbogaconym o dodatkowe klasy i funkcje do generowania HTML. Przykłady: Savant, Zend_View Dedykowany język szablonów Wprowadzamy nowy język, w założeniu o prostszej składni, lepiej dopasowanej do współpracy z HTML-em. Przykłady: Smarty, Dwoo, PHPTAL
  • 9. Dedykowany język szablonów – czy warto? Dlaczego ludzie tworzą nowe języki szablonów, zamiast użyć PHP? Dlaczego wynaleźli PHP, zamiast pisać aplikacje WWW w C? Niektóre odpowiedzi: Złożoność języka Ograniczenia języka Skomplikowana składnia
  • 10. Wady PHP w szablonach
    • Język imperatywny dostosowany bardziej do budowy aplikacji oraz zapisu algorytmów.
    • 11. Musimy krok po kroku informować komputer, jak wykonać nawet najprostsze operacje.
    • 12. Kod staje się wyjątkowo nieczytelny, gdy osadzimy go w HTML-u.
    • 13. PHP nie rozumie struktury HTML-a.
    • 14. Brak użytecznych funkcji pomocniczych do generowania kodu HTML (chyba że sami je napiszemy).
  • 15. Mity o systemach szablonów Po co mi kolejna warstwa abstrakcji, skoro PHP już jest systemem szablonów? System szablonów jest pewną biblioteką. PHP jest językiem , który poza pętlami i instrukcjami warunkowymi nie udostępnia nic , co nawet przypominałoby API systemów szablonów. Wynika stąd, że i tak będzie trzeba taką warstwę abstrakcji napisać. Frameworki nie używają systemów szablonów, po co nimi zawracać głowę? Cóż jest takiego wyjątkowego w warstwach widoku frameworków, że nie zasługują one na to miano? Jeśli ma skrzydła i kwacze jak kaczka, to jest to kaczka bez względu na to, jak sobie na nią będzie wołać gospodyni.
  • 16. Mity o językach szablonów PHP był pierwotnie opracowywany jako język szablonów. Był , a nie jest . PHP już dawno obrał zupełnie inny kierunek rozwoju. Brak pomocniczych funkcji, brak uproszczeń składniowych do generowania kodu HTML – bez porządnego obudowania autorskim zestawem dodatków jest on ekstremalnie ciężki w użyciu w roli języka szablonów. PHP nie trzeba się uczyć, dedykowanego języka – tak. A co ze wszystkimi helperami i funkcjami pomocniczymi? Złożoność niektórych spotykanych rozwiązań jest bardzo duża. Gdy dana osoba zna podstawy programowania, nauka każdego nowego języka jest łatwiejsza. Tak samo mogli powiedzieć programiści, gdy pojawiła się Java. Nie zrobili tego.
  • 17. Mity o językach szablonów Dodatkowy język to spadek wydajności Nieprawda – 99% systemów szablonów posiada kompilatory, które raz kompilują szablon do kodu PHP, a później tylko wykonują prekompilowaną wersję. Co więcej, PHP musi wszystko rozwiązywać w trakcie wykonywania. Kompilator może część rzeczy przeliczyć już na etapie kompilacji. Kompilator nie musi przejmować się czytelnością kodu wynikowego, może więc automatycznie wdrożyć szereg optymalizacji. Po co w takim razie dodatkowy język, skoro i tak zamieniamy to na PHP? Tworząc nowy język, ogranicza nas jedynie wyobraźnia i zasoby komputera. Po co korzystać z języków programowania, skoro możemy pisać w kodzie maszynowym? To proste – ich składnia i rozwiązania sprawiają, że programy pisze się szybciej, prościej i taniej .
  • 18. Przykładowa lista w szablonie PHP Tak prosty problem, a tymczasem dostajemy klasyczny przykład kodu „napisz i zapomnij” Skomplikowane warunki do sprawdzania czy lista jest pusta. Ręcznie zakodowane algorytmy znajdujące pierwszy element . Opcjonalny atrybut to kłopoty – PHP nie rozumie kodu HTML. Musimy zajmować się escape'owaniem danych, co jeszcze bardziej wydłuża kod. Oraz wiedzieć już na tym etapie, co będzie obiektem, co tablicą itd. <?php if(is_array( $items ) && sizeof( $items ) > 0 ){ ?> <div> <h1>Nasza lista</h1> <ol> <?php $first = 0; foreach( $items as $item ){ ?> <li <?php if( $first == 0 ){ echo ' class=”first”' ; $first = 1 ; } ?> > <?php echo htmlspecialchars( $item [ 'title' ]); ?> </li> <?php } ?> </ol> </div> <?php } ?>
  • 19. Smarty i większość systemów nie wnosi nic nowego Przykład języka, który powtarza błędy PHP i produkuje nowe. Wciąż musimy ręcznie opracowywać każdy możliwy algorytm. Nieuzasadnione wprowadzanie nowej, ezoterycznej składni do zwyczajnych rzeczy (wywołanie funkcji). I dalej musimy sami pamiętać o escape'owaniu. Smarty też nie rozumie HTML-a Dalej musimy znać szczegóły implementacyjne aplikacji. {if $items } <div> <h1>Nasza lista</h1> <ol> {assign var= 'first' value= 0 }{foreach from= $items item= $item } <li {if $first eq 0 } class=”first” {assign var= 'first' value= 1 }{/if} > { $item [ title ]|escape} </li> {/foreach} </ol> </div> {/if}
  • 20. Alternatywa: Open Power Template 2
    • OPT rozumie strukturę HTML-a i robi z tego użytek.
    • 21. Programowanie deklaratywne – powiedz, co chcesz uzyskać, a nie jak to ma działać.
    • 22. Język zorientowany na rozwiązywanie typowych problemów szablonów (wyświetlanie list, formularze itd.)
    • 23. Nowoczesny, obiektowy interfejs programistyczny.
    • 24. Język przenośny – nic nie stoi na przeszkodzie, aby przeportować go na Rubiego, Pythona itd.
  • 25. Fakty: Open Power Template 2
    • Za projekt odpowiadają ludzie z 7-letnim doświadczeniem w tematyce systemów szablonów.
    • 26. Rozwijany od 5 lat; pierwsza stabilna wersja – sierpień 2006.
    • 27. Obszerna dokumentacja oraz tutoriale.
    • 28. Wielokrotnie sprawdził się w praktyce.
    • 29. Wciąż nowe pomysły na rozwój.
    • 30. Projekt open-source.
  • 31. Ten sam przykład w Open Power Template Sekcje, inteligentne pętle, ukrywają wszystkie zbędne szczegóły implementacyjne i techniczne. Parser robi użytek ze znajomości HTML-a. Nie musimy wiedzieć, jak rozpoznać pierwszy element list. OPT zrobi to za nas. Dane są automatycznie escape'owane . A my nie musimy wiedzieć czy to jest tablica, obiekt czy coś innego . < opt:show name = ”items” > < div > < h1 > Nasza lista </ h1 > < ol > < li opt:section = ”items” > < opt:attribute str:name = ”class” str:value = ”first” opt:if =” $system.section.items.first ” /> { $items.title } </ li > </ ol > </ div > </ opt:show >
  • 32. Krótki przewodnik po języku szablonów
  • 33. Sekcje – inteligentne pętle
    • Koniec z ręcznym iterowaniem – niezależne od reprezentacji danych i szczegółów implementacyjnych.
    • 34. Cztery rodzaje: zwykłe listy, selektory, drzewa i widok kolumnowy.
    • 35. Intuicyjne tworzenie zagnieżdżonych list oraz relacji między nimi.
    • 36. Deklaratywna budowa – skup się na wyglądzie.
    • 37. Szczegóły implementacyjne mogą być zmieniane przez skrypt bez przepisywania szablonów.
  • 38. Szablon bloga na sekcjach < opt:section name = ”entries” > < div class= ”entry” > < h1 > { $entries.title } </ h1 > { u : $entries.body } <!-- nie escape'uj treści --> < span class= ”tags” > < opt:section name = ”tags” str:separator = ”, ” > < a parse:href =” url( '/show/tag?tag=' ~ $tags.slug ) ” > { $tags.title } </ a > </ opt:section > </ span > </ div > </ opt:section > < div id= ”pagination” > < opt:selector name = ”paginator” > < opt:page > < a parse:href =” $paginator.url ” > { $paginator.number } </ a > </ opt:page > < opt:active > < span class= ”active” > { $paginator.number } </ span > </ opt:active > < opt:gap > ... </ opt:gap > </ opt:selector > </ div >
  • 39. Dziedziczenie szablonów
    • Sposób modularyzacji i ponownego wykorzystania wspólnego kodu.
    • 40. Zawędrowało do świata PHP z systemów dla Pythona i Perla.
    • 41. Podobieństwa do programowania obiektowego:
      • Zamiast klas, rozszerzamy szablony.
      • 42. Zamiast metod mamy snippety (rodzaj makr OPT).
      • 43. Możliwość przesłaniania snippetów w szablonach potomnych.
  • 44. Dziedziczenie szablonów – szablon bazowy <?xml version=”1.0” ?> < opt:root > < html > < head > < title >< opt:insert snippet = ”title” /></ title > </ head > < body > < div id= ”header” > < opt:insert snippet = ”header” > < h1 > Moja strona </ h1 > <!-- treść domyślna --> </ opt:insert > </ div> < div id= ”content” > < opt:insert snippet = ”content” /> </ div > </ body > </ html > </ opt:root >
  • 45. Dziedziczenie szablonów – szablon potomny <?xml version=”1.0” ?> < opt:extend file = ”base.tpl” > < opt:snippet name = ”title” > Mój tytuł </ opt:snippet > < opt:snippet name = ”header” > < opt:parent />< h2 > Strona główna </ h2 > </ opt:snippet > < opt:snippet name = ”content” > < p > Tutaj trochę treści... </ p > </ opt:snippet > </ opt:root >
  • 46. Wyświetlanie formularzy – ciężki orzech do zgryzienia
    • Jak przechowywać definicję formularza oraz reguły sprawdzania?
    • 47. Jak nie przenosić elementów wyglądu do modelu i kontrolera?
    • 48. Jak zapanować nad wyglądem formularzy, by wykorzystać go wielokrotnie?
    • 49. Jak zachować wolność dawaną przez pracę z czystym HTML-em?
  • 50. Wyświetlanie formularzy – komponenty OPT
    • Prawdopodobnie pierwszy tak elastyczny mechanizm wyświetlania elementów formularzy.
    • 51. Kontrolki podzielone na dwie warstwy:
      • Logika kontrolki (klasa w PHP) – obiekty komponentu
      • 52. Wygląd kontrolki (kod HTML) – porty komponentu
    • System formularzy oddzielony od spraw wyglądu.
    • 53. Bogaty interfejs komunikacyjny między obiema warstwami.
  • 54. Przykładowy formularz – część 1 <!-- statyczne osadzenie, wczytaj wygląd ze snippetu --> < form:input name = ” str: title” template = ”standardLayout” > < opt:set name = ” str: label” value = ” str: Tytuł” /> </ form:input > <!-- specyficzny wygląd pola --> < form:input name = ” str: age” label = ” str: Wiek” > < div opt:component-attributes = ”default” > < label for=” parse: $system.component.id ” > { $system.component.label } </ label > < opt:display /> < opt:on-event name = ”error” > < p class= ”error” > { $system.component.errorMessage } </ p > </ opt:on-event > </ div > </ form:input >
  • 55. Przykładowy formularz – część 2 < opt:snippet name=” standardLayout ” > < div opt:component-attributes = ”default” > < label for=” parse: $system.component.id ” > { $system.component.label } </ label > < opt:display /> < opt:on-event name = ”error” > < p class= ”error” > { $system.component.errorMessage } </ p > </ opt:on-event > </ div > </ opt:snippet > <!-- dynamiczne osadzanie: wczytaj wszystko z sekcji --> < o pt:section name = ”widgets” > < opt:component from =” $widgets.component ” template = ”standardLayout” > <!-- ustawmy jakieś specyficzne parametry --> < opt:set name = ” str: specificParam” value = ” str: Foo” /> </ opt:component > </ opt:section >
  • 56. System wyrażeń
    • Identycznie jak w PHP, możemy tworzyć złożone wyrażenia obliczające jakąś wartość:
    • 57. Dostosowany do użycia w kodzie HTML bez potrzeby stosowania encji.
    • 58. Nie zastępuje dobrze znanych elementów (np. funkcji) przez jakieś egzotyczne struktury.
    • 59. Eliminuje niekonsekwencje PHP w zakresie stylu nazewnictwa i kolejności argumentów funkcji.
    < p > { $foo + ( $bar * 7 )} </ p > < p > { funkcja ( $a , $b , $c ) } </ p > { $a is 'foo' ~ $zmienna }
  • 60. System wyrażeń - kontenery
    • Abstrakcja zbudowana nad złożonymi typami danych: obiektami, tablicami itd.
    • 61. W momencie pisania szablonu nie musimy znać wewnętrznej reprezentacji danych.
    • 62. Można wielokrotnie wykorzystywać te same szablony w różnych projektach bez zmiany kodu – wystarczy odpowiednio skonfigurować skrypt.
    • 63. Kontenery mogą reprezentować także złożoną logikę, np. helpery:
    < h1 > { $article.title } </ h1 > < p > { $article.body } </ p > < title > { $helpers.title } </ title >
  • 64. System wyrażeń – osadzanie w kodzie XML/HTML
    • W obrębie tekstu – przy pomocy zapisu klamerkowego:
    • 65. W atrybutach – specjalna przestrzeń nazw parse: a w OPT 2.1 – prefiks wartości.
    • 66. W atrybutach instrukcji – automatyczne rozpoznanie:
    • 67. OPT automatycznie dba o escaping, jednocześnie pozostawiając nam kontrolę:
    < p > { $foo + ( $bar * 7 )} </ p > < div parse:class= ” $foo ” > ← OPT 2.0 < div class=” parse: $foo ” > ← OPT 2.1 < opt:if test=” $foo eq 7 ” > < h1 > {e: $title } </ h1 > < p > {u: $body } </ p >
  • 68. API biblioteki
  • 69. Wiele systemów szablonów jest obiektowych tylko z nazwy
    • API zredukowane do “klasy do wszystkiego”:
      • Smarty, Dwoo, Savant, PHP-Sugar i wiele innych
    • Mogą odkrywać koło na nowo:
      • Smarty i zasoby kontra strumienie PHP
    • Lub dostarczać “dodatkową”, zakodowaną na sztywno funkcjonalność, która z szablonami ma niewiele wspólnego:
      • Smarty i mechanizm cache
  • 70. Ale nie Open Power Template! Opl_Loader :: setDirectory ( './libs/Opl' ) ; Opl_Loader :: register () ; try { $opt = new Opt_Class ; $opt->sourceDir = './templates/' ; $opt->compileDir = './templates_c/' ; $opt->setup(); $view = new Opt_View ( 'template.tpl' ) ; $view->var1 = 'Foo' ; $view->var2 = array ( 'foo' => 'abc' , 'bar' => 'def' ) ; $view->var3 = new MyObject ; $view->setFormat ( 'var3' , 'Objective' ) ; $output = new Opt_Output_Http ; $output->setContentType ( Opt_Output_Http ::XHTML, 'utf-8' ) ; $output->render ( $view ) ; } catch ( Opt_Exception $exception ) ... Wspólne jądro dla bibliotek z serii OPL Klasa do zarządzania konfiguracją. Widok:: dane + szablon. Formaty danych: określ szczegóły implementacyjne. System wyjścia: co zrobić z przetworzonym szablonem. Wyjątki.
  • 71. Formaty danych
    • To one odpowiadają za tę wielokrotnie wspominaną niezależność od “szczegółów implementacyjnych”.
    • 72. Współpracują z instrukcjami XML, dostarczając konkretnych kawałków kodu PHP do obsługi danej funkcjonalności.
    • 73. Obsługują dekorowanie.
    • 74. Formaty danych wybiera skrypt, zależnie od potrzeb:
    $view->setFormat ( 'foo' , 'Objective' ) ; $view->setFormat ( 'sekcja' , 'RuntimeGenerator/Array' ) ;
  • 75. Wydajność
    • OPT nieco wolniejszy od konkurencji dla najmniejszych i najprostszych szablonów, gdzie znaczenie ma czas ładowania biblioteki.
    • 76. OPT przyspiesza przy większych szablonach dzięki wydajnemu kodowi wynikowemu.
    • 77. OPT jest szybszy niż Smarty (2 i 3), a nawet czyste PHP w Zend_View przy niektórych złożonych testach.
    • 78. Możliwość podpięcia OPT pod dowolny system cache dzięki interfejsowi Opt_Caching_Interface .
  • 79. Przyszłość projektu
  • 80. Open Power Template 2.1: super-switch < opt:switch test=&quot; $warunek &quot; > < opt:equals value= &quot;wartosc1&quot; > Treść... </ opt:equals > < opt:equals value= &quot;wartosc2&quot; > Treść... </ opt:equals > < opt:equals value= &quot;wartosc3&quot; > Treść... </ opt:equals > < opt:equals value= &quot;wartosc4&quot; > Trochę treści... < opt:equals value= &quot;wartosc5&quot; > treść... </ opt:equals > Jeszcze trochę treści. </ opt:equals > < opt:default > ... </ opt:default > </ opt:switch > < opt:switch test=&quot; $pojemnik &quot; > < opt:contains value= &quot;foo&quot; > treść... </ opt:contains > < opt:contains value= &quot;bar&quot; > treść... </ opt:contains > < opt:contains value= &quot;joe&quot; > treść... </ opt:contains > </ opt:switch >
  • 81. Open Power Template 2.1: procedury i argumenty snippetów < opt:procedure name= ”foo” argument= ”required” > < p > Hi, universe! </ p > < p > { @argument } </ p > </ opt:procedure > < opt:snippet name= ”foo” argument= ”required” > < p > Hello, world! </ p > < p > { $argument } </ p > </ opt:snippet > < opt:use procedure=” $procName ” argument= ” str :wartość” /> < opt:use snippet= ”foo” argument= ” str :wartość” />
  • 82. Open Power Template 2.1: długie ify < opt:if > < opt:condition test=” $warunek1 ” > < p > Warunek 1 </ p > </ opt:condition > < p > Treść między warunkami. </ p > < opt:condition test=” $warunek2 ” > < p > Warunek 2 </ p > </ opt:condition > < opt:condition test=” $warunek3 ” > < p > Warunek 3 </ p > </ opt:condition > > < p > Jeszcze trochę treści. </ p > < opt:else > < p > Pozostałe </ p > </ opt:else > </ opt:if >
  • 83. Open Power Template 2.1: nowy parser wyrażeń
    • Konstruktory kontenerów:
    • 84. Dynamiczne indeksy kontenerów:
    • 85. Funkcje z nazywanymi argumentami:
    • 86. Niektóre nowe operatory:
    { $foo is [ 'idx1' : 'wartość 1' , 'idx2' : 'wartość 2' ] } { $foo.bar. ( $joe ) } {url ( 'controller' : 'index' , 'action' : 'index' ) } < opt:if test=” $foo contains 'abc' ” > ... </ opt:if > < opt:if test=” $foo contains both 'abc' and 'def' ” > ... </ opt:if > < opt:if test=” $foo is between 7 and 13 ” > ... </ opt:if > < opt:if test=” $foo is either 5 or 9 ” > ... </ opt:if >
  • 87. Powiązane projekty
    • Open Power Libs – niewielkie jądro z podstawowymi usługami: autoloader, obsługa pluginów, obsługa błędów, rejestr obiektów, konsola debugowa.
    • 88. Open Power Forms – biblioteka obsługi formularzy zintegrowana z OPT o niespotykanej skalowalności: od prostego formularza logowania do arkusza kalkulacyjnego.
    • 89. Open Power Classes – zbiór dodatkowych niewielkich bibliotek, w tym także do OPT (stronicowanie, cache, system tłumaczeń itd.)
    • 90. Porty dla Zend Framework, Kohana, CakePHP.
  • 91. Chwila dla reportera ... czyli czas na pytania od słuchaczy, prośbę o dopowiedzenie / wytłumaczenie / wrócenie do czegoś itd.
  • 92. KONIEC Więcej informacji na www.invenzzia.org