Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Understanding Twig PHP Template Engine

Twig is an open source product developed by Fabien Potencier and licensed under the BSD license. It is a template engine for PHP and easy to use for PHP developers and we will understand how it works.

Twig is an open source product developed by Fabien Potencier and licensed under the BSD license. It is a template engine for PHP and easy to use for PHP developers because, it inherits all the properties of PHP and also twig syntaxes are inherited from the Jinjo and django templates.

What is template engine?

Template engine is the software that helps to combine the templates with data elements related to one another to produce the one or more resulting documents.

Twig is fast, secure and flexible template engine for PHP. Compared to other templates, twig is the fastest template engine for PHP because,

  • the twig compiler converts templates into the plain PHP code,
  • it loads the 4318 templates per second and also caches 5982 templates per second.
  • Twig evaluates the un-trusted template code by using the sandbox mode which makes the template secure.
  • Lexer and Parser make the twig language flexible and theyallow to create own custom tags, filters and own DSL.

Note: Twig needs latest version of PHP i.e. 5.2.4 to run.

Installation of the Twig

  • Download the Twig from the following website: https://github.com/twigphp/Twig
  • Extract the downloaded file and copy that file into the localhost root directory as shown: /../www/twig, where the twig is the downloaded file.

Configuring the Environment

  • Once you install the library files, you need to register the autoloader function as follows:

      require_once 'twig/lib/Twig/Autoloader.php';
      Twig_Autoloader::register();
      

    The above code helps to use all the library functions of the twig without including them explicitly. In our code Autoloader.php is defined in the twig->lib->Twig folder.


  • The below code shows how to configure the environment object of twig to load the templates.

      require_once 'twig /lib/Twig/Autoloader.php';
      Twig_Autoloader::register();
      $loader = new Twig_Loader_Filesystem('/path/to/templates');
      $twig = new Twig_Environment($loader, array(
      'cache' => '/path/to/compilation_cache',
      ));
      

    The twig uses the environment object to load the templates from the file system or from the other location. The Twig_Loader_Filesystem() method is used to load templates and it takes /path/to/templates as parameter, where you can store your templates.

    The Twig_Environment() takes the instance of loader and array of options as a parameter.

    The following options can be used in the array of constructor:


  • cache: You need to specify the path to store the cached templates to avoid the parsing for sub-sequent requests. This boosts up the twig performance and also you can use the cached template for future. You can use any PHP cache library to do so.
  • debug: It states that generated template has a __toString() method. By default value of debug is false.
  • charset: It specifies the charset used by the template and by default utf-8.
  • auto_reload: It reloads the templates each time the source of the template changes. If it is set to false, the templates will be loaded when the contents of the templates are deleted.
  • autoescape: This determines variables are automatically escaped in the view. By default it is set to true.
  • optimizations: A flag that indicates an optimization process as
    • -1 for enable and
    • 0 for disable.

Architecture



Figure 1: Architecture of the Twig template engine

Twig template engine processes the templates that are HTML files or XML files stored in the templates directory and render the multiple documents as output. It also accesses the data from the data model and produces the multiple documents.

This MVC architecture has a view as HTML or XML files and controller as Twig template engine to process the view. This is an easy way for PHP template.

Working of Twig Template Engine

The rendering of the template in the twig takes four steps

  • Load the templates: Load the compiled template for evaluation step:
    • Lexer makes template source code into the small pieces of tokens, which helps to process easily.
    • Then, the parser creates the tree node by processing the tokens of the template source code i.e. Abstract Syntax Tree.
    • Compiler transforms the AST into PHP code.
  • Evaluate the template: Calling of the display() method of the compiled template to display the result.

Features

  • It is easy to install and configure the twig.
  • It supports reusability in which the twig cache stores the cached templates in temporary folder so that it can be reused in future.
  • You can extend and override the templates by using the twig inheritance feature.
  • You can also customize the twig syntax for better use of the block delimiters.
  • Easy to validate the template that are provided by the third party. In this case sandbox policy is neglected
  • You can also use the database to store your templates.

Basic Rules


  1. {{ _ }} tag is used to print the expression or variables.
  2. {# Comments #} tag is used to write the comments.
  3. {% _ %} tag is used for looping and control statement such as for and if loop.

Example

Following example shows a simple Twig template.

Listing 1: twig_html.html

  <!doctype html>
  <html>
  <head>
    <title>Simple Twig Template</title>
  </head>
  <body>
              <h1> Welcome {{ name }}</h1>
  </body>
  </html>
  

Listing 2: twig_index.php

  <?php
  require_once('twig/lib/Twig/Autoloader.php');
  Twig_Autoloader::register();
  $loader = new Twig_Loader_Filesystem('templates');
  $twig = new Twig_Environment($loader, array(
    'cache' => 'cache',
  ));
   
   $disp=$twig->render('twig_html.html', array('name' => 'to the world of possibility'));
   echo $disp;
  ?>
  

Details of the code

  • In the twig_html.html file, the line {{ name }} access the value of array stored in the twig_index.php file.
  • In twig_index.php file you need to register the autoloader.php file.
  • Instantiate the $loader by loading the templates.
  • Configure the $twig environment variable.
  • Use the $twig environment variable to render the twig_html.html file and pass the array.
  • $disp used to display the value of the name.

Output

  • Save the file as twig_html.html file into the templates folder.
  • Save the file as twig_index.php. Place both the templates folder and PHP file into the root directory of your localhost server.
  • Open the web browser, type localhost/twig_index.php and you would get the result as seen in the below screen:

Figure 2: welcome_twig

Filters


Filters are used to format the variables. Some of the built in filters are as follows:

upper and lower

These filters are used to format the text. The upper filter used to display the text in uppercase letter and lower is use to display the text in lower case.

  {{ 'welcome'|upper }}
  

The above code describes, the value welcome should be displayed in uppercase letter.

  {{ 'welcome'|lower }}
  

The above code describes, the value welcome should be displayed in lowercase letter.

trim

trim removes the whitespace from the beginning and end of a text.

  {{ ‘ Hello world ’|trim('  ') }}
  

The above code is used to trim the whitespace of the text Hello world.

split

split filter splits the string by the specified delimiter and returns the set of the string values.

  {% set name = "hi,hello"|split(',') %}
   

The above code splits the values “hi,hello” by ‘,’ and set values to the name array.

reverse

The reverse filter used to reverse the given string, sequence and mapping.

  {{ '1234'|reverse }}
  

The code reverses the ‘1234’ values.

date

The date filter displays the current date.

  {{ "now"|date("m/d/Y H:i") }}
   

The above code displays the current date and time of the day.

format

The format filter formats the string by replacing its placeholder.

  {{ "I like %s and %s."|format(foo, "bar") }}
   

The above code formats the %s and %s with the foo and bar values.

replace

The replace filter replaces the given new string by the old string.

  {{ ‘welcome to the World of possibilities’|replace({'welcome':"come", 'World': "city"}) }}
   

The above code replaces the words welcome and World with respective come and city values.

title

The title filter is used to display the text in titlecased format i.e. the word starts with the uppercase character and remaining all characters are in lower case.

  {{ 'my bike'|title }}
  

The above code describes the text ‘my bike’ must be displayed in the titlecased format.

capitalize

The capitalize filter displays the values in capitalized version i.e. first character of the word is uppercase and rest of all other characters are in lowercase.

  {{ 'my bike'|capitalize }}
  

The above code describes the text ‘my bike’ must be displayed in the capitalized version.

url_encode

The url_encode filter encodes the given string into the URL segment or an array of query string. It supports for RFC 3986 encoding mechanism.

  {{ "text with spaces"|url_encode }}
  

The above code displays the text ‘text with spaces’ equivalent to URL segment.

json_encode

The filter json_encode filter encodes the given values into the JSON (java simple object notation) format. The twig uses the PHP’s json_encode() method.

  {{ bunch_of_data|json_encode() }}
  

Above code generates the data so that represents as JSON.

sort

The filter sort, sorts the array values into the ascending or descending order and by default it sorts values in an ascending order.

  {% for value in values|sort %}
  //code goes here
  {% endfor %}
  

Above code sorts values in ascending order

default

The filter default filter used to specify the default values for the variables if it is not defined.

  {{ var|default('var not declared') }}
   

Above code set the default value ‘var not declared’ for var variable.

keys

The key filter returns the key values of the array elements. It uses them fullyduring the iterating over an array.

  {% for key in array|keys %}
  //code goes here
  {% endfor %}
  

Above code gets the key values of the array

max and min

The max and min filters are used to display the biggest and smallest values of an array respectively.

  {{ max(1, 3, 2) }}
  {{ min(1, 3, 2) }}
   

The above code displays the maximum and minimum values.

For more information of the filters such as e, striptags, join, raw, merge etc. You can refer the documentation of the twig template as follows.

http://twig.sensiolabs.org/documentation

Example

The following code shows the use of the upper, lower, trim and reverse filters

Listing 3:twig_html1.html

  <!doctype html>
  <html>
  <head>
    <title>Simple Twig Template</title>
  </head>
  <body>
              <h2>Initial Text</h2> <h4>{{ name }}</h4>
              <h2>Upper case Text</h2> <h4>{{ name|upper }}</h4>
              <h2>Lower case Text</h2> <h4>{{ name|lower }}</h4>
              <h2>Trim Text</h2> <h4>{{ name|trim(' ') }}</h4>
              <h2>Reverse Text</h2> <h4>{{ name|reverse }}</h4>
  </body>
  </html>
  

Listing 4:twig_index1.php

  <?php
  require_once('twig/lib/Twig/Autoloader.php');
  Twig_Autoloader::register();
  $loader = new Twig_Loader_Filesystem('templates');
  $twig = new Twig_Environment($loader, array(
    'cache' => 'cache',
  ));
   $disp=$twig->render('twig_html1.html',array('name'=>' Welcome to the World of Possibility. '));
   echo $disp;
  ?>
  

Output

  • Save html file as twig_html1.html
  • Save PHP file as twig_index1.php
  • Open the web browser, type localhost/twig_index1.php and you would get the result as seen in the below screen:

Figure 3: filters_image

Example

The following code shows the use of the date, format, replace, title and capitalize filters

Listing 5:twig_html2.html

  <!doctype html>
  <html>
  <head>
    <title>Simple Twig Template</title>
  </head>
  <body>
              <h2>Initial Text</h2> <h4>{{ name }}</h4>
              <h2>Date and time</h2> <h4>{{ "now"|date("m/d/Y H:i") }}
              <h2>Format text</h2> <h4>{{ "I like %s%s."|format(foo,"You") }}</h4>
              </h4><h2>Replace Text</h2> <h4>{{ name|replace({'welcome':"come", 'World': "city"}) }}</h4>
              <h2>Title Text</h2> <h4>{{ name|title }}</h4>
              <h2>Capitalize Text</h2> <h4>{{ name|capitalize }}</h4>
  </body>
  </html>
  

Listing 6:twig_index2.php

  <?php
  require_once('twig/lib/Twig/Autoloader.php');
  Twig_Autoloader::register();
  $loader = new Twig_Loader_Filesystem('templates');
  $twig = new Twig_Environment($loader, array(
    'cache' => 'cache',
  ));
   $disp=$twig->render('twig_html2.html',array('name'=>'welcome to the World of possibility.'));
   echo $disp;
  ?>
  

Output

  • Save html file as twig_html2.html
  • Save PHP file as twig_index2.php
  • Open the web browser, type localhost/twig_index2.php and you would get the result as seen in the below screen:

Figure 4: filters_image3

Control Structure

The if and for are the control structure used in the twig template. Twig has its own way of defining the control structure.

if

The if control statement helps to execute the block of statement, if the Boolean condition is true.

The else execute the block of statement, if the Boolean condition of the if controller is false.

Syntax

  {% if Boolean expression %}
  ....
  {% endif %}
  

The above code describes the syntax of if control structure it takes argument as Boolean expression.

The not is used for evaluate false values:

  {% if not product.contains %}
  <h4>No more products available in shop.</h4>
  {% endif %}
  

In the above code not displays the false value of the product.contains.

The if-else version of twig:

  {% if  product.contains %}
  <h4>Availableproducts are…..</h4>
  {% else %}
  <h4>No more products available in shop.</h4>
  {% endif %}
  

The above code if-else controller displays the message ‘Availableproducts are…..’ if the product.contains has the product or else displays the false message ‘No more products available in shop’.

Determining the expression

  • empty string: false
  • numeric zero: false
  • whitespace-only string: true
  • empty array: false
  • null: false
  • non-empty array: true
  • object: true

Example

The below example shows how the if control statement works

Listing 9: twig_html4.html

  <!doctype html>
  <html>
  <head>
    <title>Simple Twig Template</title>
  </head>
  <body>
              {% if name is empty %}
                          {% set name = "World" %}
                    {% endif %}
              <h1> Welcome {{ name }}</h1>
  </body>
  </html>
  

Listing 10: twig_index4.php

  <?php
  require_once('twig/lib/Twig/Autoloader.php');
  Twig_Autoloader::register();
  $loader = new Twig_Loader_Filesystem('templates');
  $twig = new Twig_Environment($loader, array(
  ‘cache’=>’cache’,
  ));
   $disp=$twig->render('twig_html4.html',array('name'=>''));
  //the value of name is empty
   echo $disp;
  ?>
  

Output

  • Save html file as twig_html4.html
  • Save PHP file as twig_index4.php
  • Open the web browser, type localhost/twig_index4.php and you would get the result as seen in the below screen:

Figure 5: filters_image4

for

The for control statement helps to execute the block of statement repeatedly.

Syntax

{% for param in params %}

……..

{% endfor %}

Advanced variables used in the Twig for loop.

Variable Description

  • loop.index:The current iteration of the loop. (1 indexed)
  • loop.index0:The current iteration of the loop. (0 indexed)
  • loop.revindex:The number of iterations from the end of the loop (1 indexed)
  • loop.revindex0:The number of iterations from the end of the loop (0 indexed)
  • loop.first:True if first iteration
  • loop.last:True if last iteration
  • loop.length:The number of items in the sequence
  • loop.parent:The parent context

  {% for param in params %}
  {{ loop.index }} - {{ params.name }}
  {% endfor %}
  

Example

The below example shows how the if control statement works

Listing 11: twig_html5.html

 
  <!doctype html>
  <html>
  <head>
    <title>Simple Twig Template</title>
  </head>
  <body>
              <h1>{{ title }}</h1>
               <h3>
               {% for product in products %}
                    <li>{{ product }}</li>
               {% endfor %}
              </h3>
  </body>
  </html>
  

Listing 12: twig_index5.php

 
  <?php
  require_once('twig/lib/Twig/Autoloader.php');
  Twig_Autoloader::register();
  $loader = new Twig_Loader_Filesystem('templates');
  $twig = new Twig_Environment($loader, array(
  ‘cache’=>’cache’,
  ));
  $disp=$twig->render('twig_html5.html', array(
      'title' => 'Welcome to the Fruite market',
      'products' => array(
          'Mango',
          'Banana',
          'Orange',
      ),
  ));
   echo $disp;
  ?>
  

Output

  • Save html file as twig_html5.html
  • Save PHP file as twig_index5.php
  • Open the web browser, type localhost/twig_index5.php and you would get the result as seen in the below screen:

Figure 6: filters_image5

Template Inheritance

This is a most powerful feature of the twig. In twig, you can inherit the new template by using the base template. This can be possible by using extend tag. The new template can inherit all the properties of the base template. When the template engine evaluates the code, first it looks for the base template and then new template.

Listing 13: base_temp.html

 
  <!DOCTYPE html>
  <html>
  <head>
  <title>{% block title %}{% endblock %} Parent Page</title>
  </head>
              <body>
                    <h1>{% block contenth1 %}{% endblock %}</h1>
                    <h2>{% block contenth2 %}{% endblock %}</h2>
                    <h3>{% block contenth3 %}Work is Worship{% endblock %}</h3>
              </body>
  </html>
  

Listing 14: new_temp.html

 
  {% extends "base_temp.html" %}
  {% block title %}Index{% endblock %}
  {% block contenth1 %}
              Work is Worship
  {% endblock %}
  {% block contenth2 %}
              Work is Worship
  {% endblock %}
   

Listing 15: twig_index6.php

 
  <?php
  require_once('twig/lib/Twig/Autoloader.php');
  Twig_Autoloader::register();
  $loader = new Twig_Loader_Filesystem('templates');
  $twig = new Twig_Environment($loader, array(
  ‘cache’=>’cache’,
  ));
   $disp=$twig->render('new_temp.html');
   echo $disp;
  ?>
  

Details of the code

  • You need to create the two HTML files say base_temp.html and new_temp.html. In this case new_temp.html will inherit the properties of the base_temp.html.
  • The block tag is used to tell the childe template, which can override only those portions of the template.
  • The extends tag is the key that extends the base_temp.html template into the new_temp.html.
  • Note that the extends tag should be the beginning tag of the child (new_temp.html) template.
  • Note that since the child template doesn't define the contenth3 block, the value from the parent template is used instead.
  • Note that the child template defines the contenth1 and contenth2.

Output

  • Save html file as new_temp.html
  • Save html file as base_temp.html
  • Save PHP file as twig_index6.php
  • Open the web browser, type localhost/twig_index6.php and you would get the result as seen in the below screen:

Figure 7: inheritance

Sandbox

The sandbox mode helps to keep the contents of the template safe and secure. When the sandbox is not enabled globally, the sandbox tag enables the sandboxing mode for an included template as follows:

  {% sandbox %}
  {% include 'user.html' %}
  {% endsandbox %}
  

In the above code user.html template will be accessed securely by using the sandbox mode.

When the sandbox extension is enabled the sandbox tag is made to be available. It always uses the include tag to include the template.

Note: Do not write the codes in the sandbox tag directly it won’t work.

Set

The set tag is used to assign values to variables inside the block. The set tag can have multiple targets.

Following code shows how to assign values inside the block.

  {% set name = 'Sachin' %}
  

In the above code variable name holds the value sachin.

After calling the set, the name variable is available in the template as:

{# displays name #}

  {{ name }}
  

The above code is used to display the name value.

You can also assign several variables in one block as:

  {% set str1, str2 = 'values1', 'values2' %}
  

In the above code set tag sets the two variables str1 and str2 as values values1 and values2 respectively.

For looping, you can access the variable, by just declaring it before the loop:

  {% set i = "" %}
  {% for product in products %}
  {% set i = item %}
  {% endfor %}
   

In the above code, value of i is set to an item that are stored in the product. For each loop in the code, the value of i will be updated.

Example

The following example shows the use of set tag:

Listing 16: set_html.html

 
  <!doctype html>
  <html>
  <head>
    <title>Simple Twig Template</title>
  </head>
  <body>
              {% set name = 'Sachin' %}
              {% set num = [1, 2] %}
              {% set str= {'key': 'values'} %}
              {% set str1 = 'key' ~ 'values' %}
              <h4>{{ name }}</h4>
              <h4>
                     {% for nums in num %}
                          {{ nums }}
                     {% endfor %}
              </h4>
              <h4>
                    {% for strs in str %}
                          {{ strs }}
                     {% endfor %}
              </h4>
              <h4>{{ str1 }}</h4>
  </body>
  </html>
  

Listing 17: twig_index7.php

 
  <?php
  require_once('twig/lib/Twig/Autoloader.php');
  Twig_Autoloader::register();
  $loader = new Twig_Loader_Filesystem('templates');
  $twig = new Twig_Environment($loader, array(
  ‘cache’=>’cache’,
  ));
   $disp=$twig->render('set.html');
   echo $disp;
  ?>
  

Output

  • Save html file as set.html
  • Save PHP file as twig_index7.php
  • Open the web browser, type localhost/twig_index7.php and you would get the result as seen in the below screen:

Figure 8: set

Embed

The embed tag combines both include and extends tags. The include tag used to include the contents of another template and it allows you to override any block that is declared in the included template. During extending the template you should override the blocks.

Difference between include and embed

  • Include is used to wrap the code from non flexible HTML structure.
  • Embed allows flexibility.
  • Include tag splits a template into many functional sub-templates and also reuse the wrapped code.
  • Embed tag needed to customize the reusable templates.

Think of an embedded template as a "micro layout skeleton".

  {% embed "swing.html" %}
  {# embeds all blocks that are defined in the" swing.html" #}
  {# override the blocks: #}
  {% block contents1 %}
  //text you want to include
  {% endblock %}
  {% block contents2 %}
  //text you want to include
  {% endblock %}
  {% endembed %}
  

The above code embeds all blocks that are defined in the swing.html and also overrides the blocks.

The embed tag is used as template inheritance. The template inheritance allows inheriting the properties of the base template which are used in the child template.

Two ways to design the template without the embed tag as follows:

  • Create two "intermediate" base templates that extend the master layout template
  • Embed the markup for the contents into the each page template directly.

The below code shows the use of the page template:

  {% extends "example1.twig" %}
  {% block contents %}
  {% embed "example2.twig" %}
  {% block contents %}
  //Some contents
  {% endblock %}
  {% block contents %}
  //Some contents
  {% endblock %}
  {% endembed %}
  {% endblock %}
  

The above code describes we are extending contents of the example1.twig and also embedding the example2.twig contents.

Use

Horizontal Reusing is an advanced Twig feature. It is rapidly used in the project that makes template blocks reusable without using an inheritance. One of the most powerful Twig's features is template inheritance and it is limited to single inheritance. The template can only extend one other template. This limitation makes template inheritance simple to use.

  {% extends "base_new.html" %}
  {% block title %}{% endblock %}
  {% block content %}{% endblock %}
  

In the above code we are extending the base_new.html file block contents i.e. title and content.

Horizontal reuse is used for to achieve the multiple inheritance. The following code shows how to make use of the multiple inheritance.

  {% extends "base_new.html" %}
  {% use "blocks_new.html" %}
  {% block title %}title{% endblock %}
  {% block content %} //contents to be added here {% endblock %}
  

In the above code use statement imports the blocks defined in blocks_new.html into the current template.

  {# blocks_new.html #}
  {% block contentsh1 %}{% endblock %}
  

In the above code example, the use statement imports the contentsh1 block into the main template. The imported blocks are not outputted automatically.

  {% extends "base_new.html" %}
  {% block contenth1 %}{% endblock %}
  {% block title %}{% endblock %}
  {% block content %}{% endblock %}
  

The use tag imports a template that does not extend any other template. But it can use the other templates. Because use statements are resolved independently of the context passed to the template and main template overrides any imported block. It also avoids the name conflicts, you can also rename an imported blocks

  {% extends "base_new.html" %}
  {% use "blocks_new.html" with contenth1 as base_contents %}
  {% block contenth1 %}{% endblock %}
  {% block title %}{% endblock %}
  {% block content %}{% endblock %}
  

The above code describes how to make use of the ‘use’ tag. In our code we are using the contents of the blocks_new.html template. The contenth1 is the block that is defined in the base_new.html template.

The parent() method overrides a block defined in an imported template

  {% extends "base_new.html" %}
  {% use "blocks_new.html" %}
  {% block contenth1 %}
  {{ parent() }}
  {% endblock %}
  {% block title %}{% endblock %}
  {% block content %}{% endblock %}
  

In the above code, parent() will correctly call the contenth1 block from the blocks_new.html template.

  {% extends "base_new.html" %}
  {% use "blocks_new.html" with contenth1 as parent_content %}
  {% block contenth1 %}
  {{ block('parent_content') }}
  {% endblock %}
  

Conclusion

Here we studied about some of the basic features of the templating framework, Twig. We saw how to install twig, and we looked at its architecture and some feature. We also studied some basic rules of Twig, along with Filters, Control Structure, Template Inheritance. We also studied about Sandbax module, tags such as set, embed. All these are explained well with simple examples. Source code is also attached with this article.



I''m a full stack developer with around 10+ yrs of experience. I enjoy writing technical articles on upcoming technical trends.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login