1. Invenzzia Group presentations Open Power Template 2 Open Power Template 2 XML presentation framework / template engine for PHP5
2. Invenzzia Group presentations Open Power Template 2 Every template engine consists of two parts: - public API: manages the script data and executes templates - template language used to write templates
3. Invenzzia Group presentations Open Power Template 2 Template engine = Public API + template language Every template engine consists of two parts: - public API that manages the script data and executes templates - template language used to write templates There are two approaches when choosing a template language: Dedicated template language Template engine introduces a custom language, with simpler syntax, easier to use in HTML templates. Examples: Smarty, Dwoo, PHPTAL PHP as a template language Templates are written in plain PHP supported by extra classes and functions. Examples: Savant, Zend_View
4. Invenzzia Group presentations Open Power Template 2 Why do people invent new template languages instead of using PHP? Why did they invent PHP instead of writing web applications in C/C++? The answers are simple: Complexity Language limitations Unsuitable syntax
7. PHP does not understand the HTML document structure.
8. Lack of useful functions for generating and manipulating HTML code (unless we write it).
9. Invenzzia Group presentations Open Power Template 2 Template engine = Public API + template language Every template engine consists of two parts: - public API that manages the script data and executes templates - template language used to write templates A sample list in a PHP template: <?php if(is_array( $items ) && sizeof( $items ) > 0 ){ ?> <div> <h1>Our list</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 } ?> So simple problem and we get a classic example of a write-only code Complex conditions to check if the list is not empty. Hardcoded algorithms to find the first item . Adding new attribute is problematic – PHP does not understand HTML . We must remember to escape the data, and the code becomes longer and longer. And we must know which data are objects and which are arrays.
10. Invenzzia Group presentations Open Power Template 2 Smarty and many other template engines do not make things better: <?php if(is_array($items) && sizeof($items) > 0){ ?> <div> <h1>Our list</h1> <ol> <?php $first = 0; foreach($items as $item){ ?> <li <?php if($first == 0){ echo ' class=”first”'; $first = 1; } ?> > <?php echo htmlspecialchars($items['title']); ?> </li> <?php } ?> </ol> </div> <?php } ?> An example of a language which repeats the PHP drawbacks and produces new ones. {if $items } <div> <h1>Our list</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} We still hard-code every single algorithm in a template: Inventing esoteric syntax for well-known stuff (i.e. function calls). And we still must remember about escaping. Smarty does not understand HTML, too. We must still remember, which item is an array and which is object.
22. Invenzzia Group presentations Open Power Template 2 The same problem in OPT: < opt:show name = ”items” > < div > < h1 > Our list </ 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 > Sections, smart loops, hide all the logic and data type-specific issues. The parser understands HTML and makes use of it. We do not have to find our way to determine the first element in a list. In declarative programming, OPT does it for us. The data are automatically escaped. And we do not even have to know, if this is an object or array.
23. Invenzzia Group presentations Open Power Template 2 <opt:show name=”items”> <div> <h1>Our list</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> Thanks to the XML parser, OPT reports all the HTML syntax errors for you, just like the validator, but for all your templates and constantly . < opt:show name = ”items” > < div > < h1 > Our list </p> < ol > < li opt:section = ”items” > < opt:attribute str:name = ”class” str:value = ”first” opt:if =” $system.section.items.first ” /> { $items.title } </ li > </ ol > ??? </ opt:show >
24. Invenzzia Group presentations Open Power Template 2 Open Power Template 2 A short trip over the template language features
25.
26. Four types of sections: traditional lists, selectors, trees and grids.
27. Very simple process of creating nested sections and relationships between them.
28. Declarative design – focus on how the list should look like, not – how it should work.
29. The iteration details can be changed from the script level without rewriting templates.
30. Invenzzia Group presentations Open Power Template 2 < opt:section name = ”entries” > < div class= ”entry” > < h1 > { $entries.title } </ h1 > { u : $entries.body } <!-- do not escape the body --> < 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 > The main template of a blog created with OPT sections.
31.
32. For the first time introduced in Python template engines.
36. Invenzzia Group presentations Open Power Template 2 Template inheritance – base template We leave placeholders for the extending templates. <?xml version=”1.0” ?> < opt:root > < html > < head > < title >< opt:insert snippet = ”title” /></ title > </ head > < body > < div id= ”header” >< opt:insert snippet = ”header” > < h1 > My website </ h1 > <!-- the default content --> </ opt:insert ></ div> < div id= ”content” > < opt:insert snippet = ”content” /> </ div > </ body > </ html > </ opt:root >
37. Invenzzia Group presentations Open Power Template 2 Template inheritance – base template We leave placeholders for the extending templates. <?xml version=”1.0” ?> <opt:root> <html> <head> <title> <opt:insert snippet=”title” /> </title> </head> <body> <div id=”header”> <opt:insert snippet=”header”> <h1>My website</h1> <!-- the default content --> </opt:insert> </div> <div id=”content”> <opt:insert snippet=”content” /> </div> </body> </html> </opt:root> <?xml version=”1.0” ?> < opt:extend file = ”base.tpl” > < opt:snippet name = ”title” > My title </ opt:snippet > < opt:snippet name = ”header” > < opt:parent />< h2 > Home page </ h2 > </ opt:snippet > < opt:snippet name = ”content” > < p > Some content goes here </ p > </ opt:snippet > </ opt:root > Template inheritance – extending template. We specify the content for the placeholders, using snippets. Note that the default content may be used in our work thanks to <opt:parent/>
38. Invenzzia Group presentations Open Power Template 2 The form processing problem How to keep the form definition and validation rules in one place? How not to move the form look&feel issues to the presentation logic or the controller? How to keep the look&feel code compact and reusable according to DRY rules? How to keep the freedom of editing pure, custom HTML for certain form elements?
39. Invenzzia Group presentations Open Power Template 2 PHP-based systems simply do not work here! Zend Framework : form look&feel configured by massive OOP manipulations, often in the controller layer. The simplest custom change of HTML code must be hardcoded as another set of PHP classes. Kohana Framework : provides only the simplest helpers. Binding them with the form status, error reporting, look&feel issues must be hardcoded in PHP for each single field of each form (unless we write a new PHP layer over it). Symfony Framework : form library independent from the template engine – repeats part of its functionality. We can either hard-code everything, like in Kohana, or reconfigure dozens of default template templates written in PHP.
40.
41. Separate form field logic (managed by user-defined PHP classes) from their presentation (managed by templates).
48. Manage the component logic – they can communicate with the form processing engine, downloading the information about validation errors or element status.
49.
50. Define the layout of the entire element, including the labels, places for error messages, and for rendering the widget itself.
51. May load the component objects from the script or create them on their own.
52. The layout can be saved in snippets (the same, as in the template inheritance) and reused over all the forms.
53. Invenzzia Group presentations Open Power Template 2 Sample form – part 1 <!-- static deployment, loading the l&f from a snippet --> < form:input name = ”title” template = ”standardLayout” > < opt:set str:name = ”label” str:value = ”Title” /> </ form:input > <!-- custom layout --> < form:input name = ”age” label = ”Age” > < div opt:component-attributes = ”default” > < label parse:for =” $system.component.id ” > { $system.component.label } </ label > < opt:display /> < opt:onEvent name = ”error” > < p class= ”error” > { $system.component.errorMessage } </ p > </ opt:onEvent > </ div > </ form:input >
54. Invenzzia Group presentations Open Power Template 2 Sample form – part 2 <!-- static deployment, loading the l&f from a snippet --> <form:input name=”title” template=”standardLayout”> <opt:set str:name=”label” str:value=”Title” /> </form:input> <!-- custom layout --> <form:input name=”age” label=”Age”> <div opt:component-attributes=”default”> <label parse:for=”$system.component.id”>{$system.component.label} </label> <opt:display /> <opt:onEvent name=”error”> <p class=”error”>{$system.component.errorMessage}</p> </opt:onEvent> </div> </form> <!-- dynamic deployment: load everything from a section --> < o pt:section name = ”widgets” > < opt:component from =” $widgets.component ” template = ”standardLayout” > <!-- we can still set some extra component parameters --> < opt:set str:name = ”specificParam” str:value = ”Foo” /> </ opt:component > </ opt:section >
55. Invenzzia Group presentations Open Power Template 2 Open Power Template does not provide a form processing engine. Open Power Template does provide a framework to render the forms in templates which must be extended by a form processing library. Open Power Forms – a project of the form processing library integrated with OPT. Currently under active development.
56.
57. Optimizes the PHP expression syntax for XML language in order to avoid using entities.
61. Invenzzia Group presentations Open Power Template 2 Expression engine: examples <!-- display a variable value in a text --> < p > some text { $variable } some text </ p > <!-- an expression generating the CSS class name in the attribute --> < span parse:class =” 'error ' ~ $customCss ” > ... </ span > <!-- formatting a text --> < p > {capitalize ( $text ) } </ p > <!-- complex mathematical calculations --> < p > { $a + $b * ( $c – 17.43 ) } </ p > <!-- variable assignments --> { $foo is 'bar' } , { $bar = 'joe' } <!-- translation support --> < p > { $news@pageTitle } </ p >
62. Invenzzia Group presentations Open Power Template 2 Expression engine: containers An abstraction built over compound PHP data types: arrays and objects < h1 > { $article.title } </ h1 > < p > { $article.body } </ p > You do not have to know the exact data types returned by your models while you are writing a template. You can copy and reuse the same templates and template parts in different places without the need to rewrite them to the new context. OPT does it for you, using the configuration from a script. < title > { $helpers.title.getTitle } </ title > Containers can represent even more complex structures, such as view helpers, hiding their real nature and providing the unified access to them and their properties.
63.
64. Hides the real nature of the displayed data, which allows you to write the templates independently from the model layer implementation details.
69. Invenzzia Group presentations Open Power Template 2 Most available template engines are object-oriented only by the name. Usually, their end-user API is reduced to a „class-for-everything”: Smarty, Dwoo, Savant, PHPTAL, PHP-Sugar, and many more... They may reinvent some of the PHP stuff: Smarty and resources vs PHP streams Or simply provide lots of „extra” features that should not be a concern of template engines: Smarty and caching
70. Invenzzia Group presentations Open Power Template 2 This does not happen in OPT 2! Usually, their end-user API is reduced to a „class-for-everything”: Smarty, Dwoo, Savant, PHPTAL, PHP-Sugar, and many more... They may reinvent some of the PHP stuff: Smarty and resources vs PHP streams Or simply provide lots of „extra” features that should not be a concern of template engines: Smarty and caching
78. Invenzzia Group presentations Open Power Template 2 Performance Of course, we do remember about it. And you will be surprised by the results...
79. Invenzzia Group presentations Open Power Template 2 Performance OPT is a bit slower for the smallest and the simplest templates ran once, where the library loading plays the most important role. OPT becomes faster if we start writing bigger and more complex templates, and such templates usually are used on most websites. OPT is faster than Smarty and even than pure PHP in Zend_View in more complex benchmark tests.
80. Invenzzia Group presentations Open Power Template 2 Performance facts OPT execution algorithm is very simple and well-optimized. Most of the library is not even loaded, if we do not compile the templates. The template compiler is not limited by the readability of the output PHP code. Thus, it can generate more optimized code than human-made PHP templates, the best for the concrete situation. The template compiler can solve many problems during the compilation, which is done only when the template source changes. At the same time, PHP templates must execute the same fundamental code on runtime. New versions may introduce new optimizations that are automatically applied to your templates after recompilation.
82. Invenzzia Group presentations Open Power Template 2 OPT is the first step towards constructing a complete, new generation presentation layer solution for frameworks and PHP web applications. Open Power Forms – form processing library integrated with OPT. Currently under active development. Open Power Classes – set of smaller OPT-ready utility classes. Under active development. Zend Framework port – the advanced port that makes the integration with ZF easy.