-
Notifications
You must be signed in to change notification settings - Fork 0
Home
STL is a lightweight yet powerful template language (and library) based on regular expressions-driven parser. It was built from scratch to work with plain text templates.
STL is a very powerful language designed to be very easy to use and powerful at the same time. STL is designed for both, template designers and developers who can extend and enrich STL’s built in capabilities. If you already have experience with other text based template engines such as Django’s template language or Smarty you will fill very familiar and comfortable with STL.
Besides variable/placeholder parsing STL supports all common control structures such as if/elseif/else and for/in/forelse. Another powerful feature of the STL library is an extension API that allows any developer to easily build custom reusable extensions.
For STL Template is a text taken from any text file, database or other data source, it can generate any text based output(HTML, XML, Textile, CSV, Emal texts etc.), doesn’t have dependencies on any particular format and you can freely use STL not only for producing web pages.
Template may consist of variables, control structures such as if/elseif/else, for/in/forelse, function calls and modules(think about modules as custom tags).
Example show below is a very basic STL template:
{if students}
<h1>This is students list</h1>
<ul>
{for student in students}
<li>
<h2>{fn:ucfirst(strtolower(%student.name%))}</h2>
<ul>
{for friend in student.friends}
<li>%friend.name%</li>
{/for}
</ul>
</li>
{/for}
</ul>
{else}
<h1>The students list is empty :(</h1>
{/if}As you can see from example above variables are enclosed within % signs, whenever you see similar text in a template: %friend.name% – is variable.
In STL template it is possible to use any type of variable such as primitives(int, boolean, float etc.), arrays, objects… in other words you can use any variable as you are using in PHP. Table below shows comparison between PHP and STL variables:
| PHP variable declaration | Access variable(PHP) | Access variable(STL) |
|---|---|---|
$number = 2; |
echo $number; |
%number% |
$list = array('one', 'two); |
echo $list[0]; |
%list[0]% |
$list = array('one', 'two'); |
foreach ($list as $value) { } |
{for value in list} {/for} |
$logged_in=true |
if ($logged_in) { } |
{if logged_in} {/if} |
$user = array('name' => 'John'); |
echo $user['name']; |
%user.name% |
$user = (object)array('name' => 'John'); |
echo $user->name; |
%user.name% |
It is important to note that for accessing associative array keys or object properties is unified in STL, moreover same approach(dot notation) works in case when object doesn’t gives direct access to the property(e.g. private or protected property) but provides public accessor. For example consider following class:
class MyClass {
private $firstName = "John";
private $lastName = "Doe";
private $married = true;
private $hasChildren = true;
//getters
public function getFirstName() {
return $this->firstName;
}
public function getLastName() {
return $this->firstName;
}
public function isMarried() {
return $this->married;
}
public function hasChildren() {
return $this->hasChildren;
}
}//initialize object of MyClass
$obj = new MyClass();//and use object in STL
<dl>
<dt>First Name: </dt>
<dd>%obj.firstName%</dd>
</dl>
<dl>
<dt>Last Name: </dt>
<dd>%obj.lastName%</dd>
</dl>
{if obj.married}
<p>%obj.firstName% %obj.lastName% is married!</p>
{/if}
{if obj.hasChildren}
<p>%obj.firstName% %obj.lastName% has children!</p>
{/if}Evaluating shown STL template will result to following output:
<dl>
<dt>First Name: </dt>
<dd>John</dd>
</dl>
<dl>
<dt>Last Name: </dt>
<dd>Doe</dd>
</dl>
<p>John Doe is married!</p>
<p>John Doe has children!</p>As you see from example get, is and has are considered as possible prefixes for getters. Property is being discovered in following order:
- If object has requested property with public access
- if object has public method with name
getRequestedPropertyName() - if object has public method with name
hasRequestedPropertyName() - if object has public method with name
isRequestedPropertyName()
All three cases are examined before requested property is discovered otherwise null will be returned.
You don’t have any limitation on array/object complexity and nesting levels, following example demonstrates usage of PHP array with several nesting levels:
$member = array(
'first_name' => 'John',
'last_name' => 'Doe',
'sex' => 'M',
'address' => (object) array(
'city' => 'New York',
'state' => 'NY',
'country' => 'USA'
),
);//print member's country
echo $member['address']->country;//to achieve same result with STL variable use following
%member.address.country%//or use in @if@ statement
{if member.address.country=="USA"}
Member is from: %member.address.country%
{/if}STL supports function calls. Both, PHP’s built-in and user defined functions are supported. Only constraint is that invoked function needs to accept parameter(s).
Function call has following structure: {fn:ucfirst(%variable_name%)}. Nested function calls is allowed as well. For example consider following code:
PHP code
$str = "TEXT";
echo ucfirst(strtolower($str)); //will output *Text*Same as above but with STL
{fn:ucfirst(strtolower(%str%))} //will output *Text*As you may already noticed from examples {fn: prefix is only required before first function calls and nested function calls do not required fn: prefix.
STL supports most frequently used control statements such as if/elseif/else and for.
if/elseif/else statement works exactly same way as PHP’s own structure with little differences that will be described below. For more clarity compare following two snippets of code(assumed that used variables are somewhere defined already):
//PHP code
if ($user_name == "john" && !$is_logged_in_user || $is_not_super_user) {
echo "<strong>
I'm sorry ". $user_name . ", but, you are not allowed to view this resource! :(
</strong>";
} else if ($user_name == "admin") {
echo "Welcome Master!";
} else {
echo "Something is wrong!";
}//STL Code
{if user_name=="john" && !is_logged_in_user || is_not_super_user}
<strong>
I'm sorry %user_name%, but, you are not allowed to view this resource! :(
</strong>
{elseif user_name == "admin"}
<strong>Welcome Master!</strong>
{else}
<strong>Something is wrong!</strong>
{/if}As you can see from example both PHP and STL versions have a lot in common, moreover both examples will result to same output.
| Operator | Name | Description |
|---|---|---|
user_name=="john" |
Equal |
TRUE if user_name is equal to “john”
|
var1===var2 |
Equal |
TRUE only if values and types of both variables are same |
user_name!="john" |
Not equal |
TRUE if user_name is not equal to “john”
|
var1!==FALSE |
Equal |
TRUE only if value of the var1 is boolean FALSE
|
age < 31 |
Less than |
TRUE if age is less than 31
|
age <= 31 |
Less than or equal to |
TRUE if age is less than or equal to 31
|
age > 31 |
Greater than |
TRUE if age is greater than 31
|
age >= 31 |
Greater than or equal to |
TRUE if age is greater than or equal to 31
|
user_name in users |
In array |
TRUE if user_name exists in array users
|
| Operator | Name | Description |
|---|---|---|
!logged_in |
Is empty |
TRUE if variable is empty string, false, null or 0
|
logged_in |
Not empty |
TRUE if variable is not empty string, false, null or 0
|
var1 && var2 |
And |
TRUE if both var1 and var2 are not empty |
var1 and var2 |
And |
TRUE if both var1 and var2 are not empty |
var1 or var2 |
Or |
TRUE if either var1 and var2 is not empty |
for/in statement works pretty much same way as PHP’s foreach statement it loops through array and return next element on each iteration. Assume you have following PHP array and want to loop through it:
//Users array
$users = array(
array(
'name' => 'David',
'bio' => 'David is an engineer',
),
array(
'name' => 'Ann',
'bio' => 'Ann is a teacher',
),
array(
'name' => 'John',
'email' => 'John is a doctor',
),
);//PHP Version
foreach ($users as $user) {
echo '<dl>
<dt><strong>Name: </strong>'. $user['name'] .'</dt>
<dd>'. $user['bio'] .'</dd>
</dl>';
}//STL Version
{for user in users}
<dl>
<dt><strong>Name: </strong>%user.name%</dt>
<dd>%user.bio%</dd>
</dl>
{/for}Additionally for statement provides forelse block, think about this block as else in case of if but note that this block is executed only when array is empty or it doesn’t exist. For example:
//PHP code
$testArray = array(); //empty array//STL code
{for var in testArray}
<p>%var</p>
{forelse}
Array is empty!
{/for}After evaluating this STL template Array is empty! will be printed as far as used testArray variable is empty and doesn’t contain elements.