PHP Classes

File: docs.php

Recommend this page to a friend!
  Classes of Jose Maria Rodriguez Millan   Siviglia Templating   docs.php   Download  
File: docs.php
Role: Documentation
Content type: text/plain
Description: Getting Started
Class: Siviglia Templating
Template engine that uses PHP as template language
Author: By
Last change: Added contact information
Date: 14 years ago
Size: 15,437 bytes
 

Contents

Class file image Download
<html> <head> <style type="text/css"> .example { margin-bottom:10px; border:1px solid #E0E0E0; background-color:#F0F0F0; padding:5px; clear:both } h1 {border-bottom:1px solid black} .template, .usedWidgets, .result,.generated { color:#303030; background-color:white; border:1px solid black; float:left; margin-right:20px; width:500px } .result,.generated { margin-top:5px; border:1px solid black; background-color:white; width:500px; float:left } .resultCode {padding:10px} .widget { margin:2px; border:1px solid black } p { padding:3px; margin:0px; background-color:#A0A0A0; font-weight:bold; font-size:16px } .widget p {background-color:#C0C0C0} .firstRow , .secondRow {clear:both} .comment {margin-bottom:20px} .bolder,.bolder2 {font-size:14px;font-weight:bolder;} .bolder {color:blue} .bolder2 {color:red} </style> </head> <body> <h1>Siviglia Templating System</h1> The Siviglia Templating System is the template engine used by the Siviglia Framework (work in process). It was designed with the following goals in mind: <ul> <li><b>Intuitive</b>: It's syntax should be very intuitive.It should be usable without technical knowledge (specially, for content creators)</li> <li><b>Reusable</b>: Templates should be composed of smaller bits ("widgets") ,which, in turn may be composed of other widgets.Those widgets may be reusable.</li> <li><b>No need for "templating languages"</b>: Templates and widgets may use php freely, without needing of special template languages.</li> <li><b>Different levels of abstraction</b>: From the website structure, to the smallest boxes, should be expressed by templates.</li> <li><b>Cacheable</b>: Templates should generate code, which may be cached</li> <li><b>Output depending on platform</b>:Given a template, and using different widget resolution paths,code for different platforms may be generated.</li> </ul> <br><br> <div class="example"> <h1>Sample usage</h1> Using the engine is easy.You'll need at least one directory to store widgets.You'll see how to code those widgets in the examples below.<br> To include and initialize the engine, use the following code: <div class="template"> <pre> &lt;?php include_once("SivigliaTemplates.php"); $o=new CTemplateParser(); $st=& $o->solveTemplate("[_B]Hello World[/B]"); // Here you get the code generated by the engine $code=$st->nodesToText(); // To use it right away, just eval it. eval("?&gt".$code); ?&gt; </pre> </div> <div style="clear:both"> </div> <br><br> The <b>CTemplateParser</b> constructor accepts two parameters: <ul> <li>An additional array of paths for widget resolution (with higher priority than the default paths)</li> <li>An array of paths to be used as the default widget resolution paths</li> </ul> <br> The <b>solveTemplate</b> method accepts a template as a string, and returns a CTemplate object, which can be converted to actual code using the <b>nodesToText</b> method.<br> Usually, the string given to solveTemplate has been read from a file (or database), and the code generated by nodesToText is stored in a cache file. <br><br> So, including and using the class is simple.Lets look now how to write templates and widgets.<br><br> </div> <br> <?php function boldify($cad) { $cad=preg_replace('/(\\[(?:_|\/)[^\\]]*\\])/','<b class="bolder">\1</b>',$cad); return preg_replace('/(\\[\:(?:_|\/)[^\\]]*\\])/','<b class="bolder2">\1</b>',$cad); } $tests=array( array("template"=>"B.html", "title"=>"Simple Template and Widget", "comment"=>"Let's begin with a simple example.<br>The template is:<br><br><b>[_B]</b>Hello World<b>[/B]</b><br><br>This is a simple template, using a simple widget.The widget name is <b>\"B\"</b>, and will set to bold its contents.<br> This means the templating system will look for a file named \"B.html\", located in the 'widgets' folder.<br><br> The widget file only contains:<br><br> &lt;b&gt;[_*]&lt;/b&gt;<br><br> The tag [_*], means 'whatever the template contained within this tag'.The tag, in this case, is B.The upper-level tag for any widget, is its file name (without extension).<br> ", "widgets"=>array("B") ), array("template"=>"BI.html", "title"=>"Simple template-side composition", "comment"=>"Template side composition means you can use multiple widgets in the same template.<br> The widgets can be used sequentially, or nested, as the contents of any tag is always re-evaluated looking for nested widgets.<br> This template uses 2 nested widgets, B and I.You can see how the output from the widgets are combined.", "widgets"=>array("B","I") ), array("template"=>"WIN.html", "title"=>"Widgets with nested subtags", "comment"=>"A widget can have any number of nested tags.In this case, the template will have to use those tags following the structure the widget dictates.<br> The important thing here is that, once the template uses a widget, the output will be controlled by the <b>widget</b>.<br><br> Let's see an example, which will help to intuitively understand how it works:<br>", "postcomment"=>" There are a few things to understand about nested tags.<br> <ul> <li>All nested tags are optional.<br>The templating system will not force the presence of any nested tag.<br>In the previous example, nothing prevents the use of a <b>FLOATBOX</b> not containing any <b>[_TITLE]</b> subtag.<br></li> <li>The same tag can appear multiple times in the widget.Each apparition of a tag in a template, is replaced in the widget in every place the tag is used (given they're at the same depth level)</li> <li>Any tag that includes nested tags, cant use <b>[_*]</b>.If a tag has subtags, its content is constructed by the output of its subtags.<br>This means, in the previous example, that <b>FLOATBOX</b> cant have a <b>[_*]</b> tag, that it's not inside <b>TITLE</b> or <b>CONTENTS</b></li> <li>Then, any content in the template under the scope of a tag, which has subtags, will not be processed by the widget.<br>This means, if the template uses a <b>FLOATBOX</b>, all the text that it's not inside the subtags <b>[_TITLE]</b> or <b>[_CONTENTS]</b>, will be lost when code is generated.</li> <li>There are no restrictions in the number of times a certain sub-tag can appear in a template.<br>The associated code in the widget will be repeated as many times as the subtag appears in the template<br>This means that if a template uses 2 <b>[_TITLE]</b> tags inside a widget instance,the associated code in the widget file will be included twice.</li> <li>In a template, the code generated for a widget is driven by the <b>widget</b> structure, not the template structure.<br> This means that doesnt matter if the template specifies <b>[_CONTENTS]</b> before <b>[_TITLE]</b>.As the widget drives its code generation, the title will still appear first.</li> <li>A widget can specify nested tags in two ways: <ul> <li> Simply by its name : <b>[_TITLE]</b>, without closing tag.<br> In this case, the contents of this tag in the template, will be inserted there.<br> If there's no <b>[_TITLE]</b> tag in the template, nothing will be shown.</li> <li> Using closing tag and (optionally), <b>[_*]</b><br> For example, <b>[_TITLE][_*][/TITLE]</b>.<br> The <b>[_*]</b> tag will be replaced by the content specified in the template inside the [_TITLE] tag. </li> </ul> Whats the difference between the two?<br> Consider the following cases:<br><br> Case 1: &lt;div&gt;[_TITLE]&lt;/div&gt;<br><br> Case 2: [_TITLE]&lt;div&gt;[_*]&lt;/div&gt;[/TITLE]<br><br> In the first case, the div will be included in the generated code, even if the template didnt specified any <b>[_TITLE]</b> tag.<br><br> In the second case, the div will only appear if there was a <b>[_TITLE]</b> tag in the template, acting like a condition.<br><br> </li> <li>You can nest tags as much as you wish, and the template must use the same nesting structure</li> </ul> ", "widgets"=>array("FLOATBOX") ), array("template"=>"WIN2.html", "title"=>"Nested subtags and nested widgets", "comment"=>"You can seamlessly use new widgets inside terminal subtags of a parent widget.<br>Notice that nested subtags always have precendence.<br> So, if a <b>FLOATBOX</b> widget has a <b>TITLE</b> nested tag, that tag will be used, even if there's another independent widget with the name <b>TITLE</b> (inside a TITLE.html file)<br>", "widgets"=>array("FLOATBOX","B","I")), array("template"=>"CONTAINER.html", "title"=>"Widget-side composition", "comment"=>"A very powerful feature is the ability of use widgets within widgets.<br> To do this, just prepend <b>:</b> around nested widgets tags.<br><br> In this way, widgets can be reused, stack different abstraction levels, and create very different outputs playing with widget inclusion paths.<br> You can also see the recommended way of creating loops to repeat widget sub-tags, using <b>PRE</b> and <b>POST</b> dummy tags.<br> Remember that, if a widget has nested tags, any code outside those tags in the template will be lost!<br> To understand this, see how the html comment is lost in the following example generated code.<br><br> You can see too how using <b>[_PRE]</b> is equivalent to using <b>[_PRE][_*][/PRE]</b>", "widgets"=>array("BOXCONTAINER","FLOATBOX")), array("template"=>"LINEWRITER.html", "title"=>"PHP context resolution", "comment"=>"One of the most powerful features of the Siviglia Templating system is resolution of php contexts, so PHP and HTML code can be safely mixed.<br> The previous examples used just static values for tag values.But it'll be usual that you may need pass php variables, even php code, to certain tags.<br> On the other hand, the widgets may need to use certain tags inside PHP code, for example, to initialize variables.<br The templating system analyzes the code across the multiple template-side and widget-side nesting, and builds a new PHP code resolving the different contexts where tags are used within the templates and widgets.<br> In the following example, look the few different ways the template is specifying the widget tag value, and the different ways the widget uses that tag.<br> In the widget, you can also see how the same tag is used in different places in the same widget", "postcomment"=>"In the previous example, you can see an important consecuence of having both template and widget-side nesting:<br><h3><b>All php used in the template and all widgets, is executed within the same scope</b></h3>.<br> That means the chance of name clashing is high!All names used within widgets should be properly prefixed to avoid name clashing, specially for loop counters.", "widgets"=>array("LINEWRITER") ) ); include_once("SivigliaTemplates.php"); $o=new CTemplateParser('',getcwd()."/widgets"); for($k=0;$k<count($tests);$k++) { $current=$tests[$k]; echo '<div class="example"><h1>'.$current["title"].'</h1>'; echo '<div class="comment">'.$current["comment"].'</div>'; $content=file_get_contents("templates/".$current["template"]); echo '<div class="firstRow">'; echo '<div class="template"><p>Template code</p>'; echo '<div class="templateCode"><pre>'.boldify(htmlentities($content)).'</pre></div>'; echo '</div>'; $st=& $o->solveTemplate($content); $code=$st->nodesToText(); echo '<div class="usedWidgets"><p>Used widgets</p>'; for($j=0;$j<count($current["widgets"]);$j++) { echo '<div class="widget"><p>'.$current["widgets"][$j].' (File: widgets/'.$current["widgets"][$j].'.html)</p>'; echo '<div class="widgetCode"><pre>'; echo boldify(htmlentities(file_get_contents("widgets/".$current["widgets"][$j].".html"))); echo '</pre></div></div>'; } echo "</div>"; echo "</div>"; echo '<div class="secondRow">'; echo '<div class="result"><p>Result</p>'; echo '<div class="resultCode">'; eval("?>".$code); echo '</div></div>'; echo '<div class="generated"><p>Generated code</p>'; echo '<div class="generatedCode"><pre>'.htmlentities($code).'</pre></div>'; echo '</div></div>'; echo '<div style="clear:both"></div>'; if($current["postcomment"]) echo '<div class="postcomment">'.$current["postcomment"].'</div>'; echo '</div>'; } ?> Send any comments, bug reports, feature requests to <a href="mailto:dashiad@gmail.com">dashiad@gmail.com</a><br><br> Are you using this class? I'll be really grateful if you make me know! </body> </html>