Invenzzia » Resources / Articles / OPT quickstart

OPT quickstart

  • Published on 18 January 2009 15:04:00 GMT, updated over 5 years ago by Tomasz Jędrzejewski
  • pl

This is a quick start quide for the programmers new to Open Power Template. It shows the basic concepts, features and library philosophy.

Open Power Template is an open-source template engine written for PHP5. It is a part of bigger project, Open Power Libs, which is going to be a set of advanced PHP libraries for your frameworks and web applications. Contrary to other popular solutions, OPT is not a trivial reimplementation of PHP with different syntax, but provides a set of well-designed and easy in use tools that make template creation much simpler.

What are templates?

Mixing you HTML code with the script logic that processes the data is not considered as a good practice. In every bigger project, we assume that the part that generates the HTML output, called presentation layer, must be separated from the part that generates the data (logic layer). The most common solution are templates - simple files with HTML and the code that puts the script data in the right place. The additional library that manages the templates is a template engine.

Templates can be written directly in PHP or in a special language. In the second case, the template engine provides a parser to process this language. Open Power Template belongs to the second group of template engines.

OPT templates and declarative programming

PHP is an imperative language. This means that you inform the parser, how to solve problems step by step, with functions, loops, conditions and expressions. It gives the programmer the biggest control over the execution process, however, for templates it is too much complicated. Templates unsually require a small group of simple algorithms, and in the imperative languages, you have to create them from scratch every time you want to use them, or create an advanced set of classes and other stuff.

OPT encourages to use the style called declarative programming. Here, we simply define, what we want to achieve and nothing more. An example of such language is HTML. Notice that it is also very convenient for templates: we do not have to worry about the implementation issues. For example, to display a list we only mark that we need a list here and give it a name. During the template execution, OPT will check, whether the script assigned the data to the list, what format are they and finally, how the list must be processed.

OPT template language is a set of XML tags and attributes. It has one advantage over PHP templates - the template engine understands your HTML code. It checks the syntax and informs on every tag closed in the incorrect order. Moreover, OPT can cooperate with the HTML more transparently than PHP. The language is very flexible - you can disable or enable various options: from nearly full XML standard compatibility to the quirks mode, useful for processing non-XML templates.

Step 1: the directory structure

OPT is a part of OPL and requires the OPL core in order to work. Everything you need to run the script that use OPT, can be found in the downloaded OPT archive. Create a directory /opl somewhere in your project directory tree and copy there the contents of /opt-2.x.x/lib folder in the downloaded archive. You should get something like this:

/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 is not a mistake. The OPL core is located in the very directory.

If you want to use another OPL library in your project, just copy its directory into /opl. Notice that by default, that library may also contain the OPL core - in this case nothing will happen if you overwrite it and the versions are the same.

OPT needs also two additional directories. Let's assume that they are called /templates/ and /templates_c/, but they are not obligatory names. Note that PHP must have the write access to the second directory.

Step 2: initialize OPL

Now, you have to load the OPL core and initialize the library. This can be done with the following PHP code:

require('/path/to/opl/Opl/Base.php');
Opl_Loader::setDirectory('/path/to/opl/');
Opl_Loader::register();

OPL uses its own autoloader to manage the classes. The class names use the naming convention like Opx_Something_More. The autoloader is able to recognize the class that belongs to OPL projects. Note that some frameworks also use similar naming conventions and provide their own autoloaders. You cannot, however, throw out the OPL autoloader, because they are not able to load all the OPL classes properly.

Step 3: initialize OPT

Now we are ready to initialize OPT itself. This can be done with the following code:

$tpl = new Opt_Class;
$tpl->sourceDir = './templates/';   // path to /templates/ directory
$tpl->compileDir = './templates_c/';    // path to /templates_c/ directory
$tpl->setup();

This is the basic configuration, but there are much more options. They can be also loaded from an INI file or external array passed to the setup() method.

OPT reports the problems with exceptions. We recommend to enclose the entire code with OPT in a try...catch block that captures Opt_Exceptions. You can use the default error handler to display them:

catch(Opt_Exception $exception)
{
    Opt_Error_Handler($exception);
}

Step 4: create the main template

Let's create some templates. Firstly, we need a template with the overall HTML structure:

<?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>Hi, this is my website!</h1>
</div>
<div id="content">
    <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>  
</div>
<div id="footer">
    <p>This is a sample OPT script.</p>
</div>
</body>  
</html>
</opt:root>

All the templates must be saved in /templates/ directory. The comment at the beginning of the code defines the file name.

Below, you can find a brief explaination of used elements:

  1. opt:root - we have some extra tags before <html>, but XML does not allow more root nodes to exist. OPT provides this tag to solve this problem.
  2. opt:prolog - generates an XML prolog for the browser (the prolog visible in the template is not sent there!)
  3. opt:dtd - generates the Document Type Definition block, using predefined template for XHTML 1.0 transitional.
  4. parse:content="$contentType" - with this namespace we indicate that this attribute contains a dynamic content, generated by the script. $contentType is a name of a variable.
  5. {$title} - a convenient way to place the variable values in the static text. Alternatively, you may use opt:put instruction.
  6. opt:section - creates a list called "modules".
  7. opt:include - includes a sub-template and imports the template data from the section "modules". If the sub-template cannot be found, the content inside the tag will be displayed.

Let's get back to the following part:

<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>

All the instructions that generate list-like data are called "sections". They are declarative instructions, so the exact implementation does not interest us. Inside the tag <opt:section> we define, how to display every list element. With this code, we want to load all the content templates defined in a script, so we create a section and mark that every its element is a template to include. Note that in PHP or many other template engines, you would have to decide here, what data format will be used, check whether the list is not empty etc.

Step 5: create some content templates

Let's create some simple content templates:

<?xml version="1.0" ?>
<!-- template1.tpl -->
<opt:root>
    <h2>Module 1</h2>
    <p>Hi, I am the module 1.</p>
    <p>Today is: {$date}</p>
</opt:root>
 
<!-- template2.tpl -->
<?xml version="1.0" ?>
<opt:root>
    <h2>Module 2</h2>
    <p>I'm the module 2</p>
    <p>A motto for today is: {$motto}</p>
</opt:root>

Step 6: create the views and outputs

Here we will stop for a moment to describe, how the templates are parsed.

OPT model

The diagram above shows the way to generate the complete output. First of all, we have an Opt_Class object. In many other template engines, it manages everything, including template parsing. However, in OPT its role is reduced to the configuration and plugin issues. The main work is done by OPT views. They are objects that represent a template with some script data assigned to it. That data are not seen in other templates you are going to parse, so the naming collisions between the modules are not a problem.

Finally, we have the OPT output object. It runs the template associated with the specified view and decides, where to send the result. OPT provides two outputs by default: Opt_Output_Http sends it to the browser and Opt_Output_Return returns it to the script. The script below shows us, how it works in practice:

// Module view
$moduleView = new Opt_View('template1.tpl');
$moduleView->date = date('d.m.Y');
 
$layoutView = new Opt_View('layout.tpl');
$layoutView->title = 'Some title';
$layoutView->contentType = 'text/html; charset=UTF-8';
$layoutView->modules = array(0 =>
    array('view' => $moduleView)
);

The OPT view constructor takes the template name. The data can be assigned to the variables as $viewObject->variableName, but there are several additional methods (for example to assign by reference). Each template should have its own view, and that is what the code above does. We have a view for one of our modules and assign the date variable to it with the current date. Later, we create the layout view, specify the website title and content type for the <meta> tag, and at last, create the data for the list of module views. If we wished to have two modules, the code would look like this:

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

As the views are ready, we should create the output object and send everything to the browser:

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

Note that the HTTP output contains also the header management.

Conclusion

We encourage you to study and explore the code you have just written. Once you understand, how it works, you can get deeper into OPT, because this is only a small set of features. Take a look at other tutorials and remember to follow the OPT philosophy.

Open Power Template 2.0 projects tutorial

This text is licensed under Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States license.

Add new comment

You are writing a reply to comment

  • Will not be published | Gravatar supported
  • Type here the name of our group.

Comments