# Template

Wolff\Core\Template

The template system of Wolff allows you to write cleaner and safer PHP code in your views by avoiding things like the PHP tags and automatically escaping all the output.

It only works in the views and is completely optional, so you can write normal PHP code if you want to.

The template system can be completely disabled if the template_on key in the system/config.php file is equal to false.

Views can be rendered anywhere inside your Wolff project.

Sending data to views

When loading a view from a controller, you can pass as parameter an associative array with data in it:

View::render('page', [ 'message' => 'Hello world' ]);

Print

Then in the view you can print the variables that are in that array using the brackets tag, this way:

{{ $message }}

This will print the 'message' key in the data array.

Keep in mind that the content will be automatically escaped for your safety.

Print raw

If you don't want your data to be escaped, use the following tags:

{! $message !}

That is the equivalent to:

<?php echo $data['message']; ?>

All the variables in the data array are accessible from the view without needing to refer to the given array. This $variable in the view, is the equivalent to this $data['variable'].

Comments

The template comments have an advantage over the common comments and is that the comments of the template system aren't included in the final HTML returned to the user.

{# This is a simple comment #}

You can write multiline comments too:

{# This is a
multiline
comment #}

Tags

In Wolff you can use the replacement of the old php tags, which are {% for <?php and %} for ?>.

Original PHP:

<?php foreach ($array as $key => $value): ?>
    //code
<?php endfor ?>

<?php if ($foo): ?>
    //code
<?php endif ?>

Template:

{% foreach ($array as $key => $value): %}
    //code
{% endfor %}

{% if ($foo): %}
    //code
{% endif %}

Loops

You can write traditional for loops in a short way:

{% for $i in (0, 10) %}
    {{$i}}
{% endfor %}

That should print 012345678910.

The same but using variables:

{% for $i in (0, length|$text) %}
    {{$i}}
{% endfor %}

Functions

The template system of Wolff has some abbreviated functions to make the code cleaner.

To use a function only write its' name followed by a vertical bar and then the variable.

{{ upper|$title }}

In that case, it will print the $title variable in uppercase.

{{ repeat(3)|$title }}

In that case, it will print the $title variable three times.

Language

With the @lang tag you can print variables of the language system in a short way.

@lang('home.title')

That code will be replaced by the value of the 'title' key in the 'home' language array.

Keep in mind that this tag does NOT escape the content, you are fully responsible for escaping it.

List

This are the available functions and their PHP equivalent:

TemplatePHP EquivalentDescription
ehtmlspecialchars
strip_tags
perfect for avoiding xss
upperstrtoupperall text to uppercase
lowerstrtolowerall text to lowercase
upperfucfirstfirst letter to uppercase
lengthstrlenstring length
countcountarray length
titleucwordsall first word letters to uppercase
md5md5md5 hash value
countwordsstr_word_countnumber of words
trimtrimwhitespace stripped from the beginning and end
nl2brnl2brinsert HTML line breaks before newlines
join(var)implodejoin an array by a text (var)
repeat(var)str_repeatrepeat a string fixed number of times (var)

CSRF

The template engine has a tag which can be used to avoid CSRF.

@csrf

Internally it creates a __token cookie if it does not exists and replaces the CSRF tag with a hidden input which value is the same of the cookie.

Keep in mind that the cookie has a live time of one hour and is http only.

<form action="theurl" method="post">
    @csrf
    <input type="text" name="username"/>
    <button type="submit">Send</button>
</form>

Then you can use the validateCsrf function of the standard library to verify the incoming form.

if (validateCsrf()) {
    echo 'Safe, continue';
    // Code
} else {
    echo 'You shall not pass';
}

Import

Instead of using the html script and link tags for importing external files, you can include them using the template tags.

{% style="styles.css" %}

Equivalent to: <link rel="stylesheet" type="text/css" href="styles.css"/>

{% script="scripts.js" %}

Equivalent to: <script type="text/javascript" src="scripts.js"></script>

{% icon="img.svg" %}

Equivalent to: <link rel="icon" href="img.svg">

Escape

For escaping the template tags, only prefix your text/tag with an hypen ~ symbol, like this:

~{{ $message }}

That will leave this in the HTML returned to the client:

{{ $message }}

Include

Instead of using the php include function. You can include other views by using the include method.

Example:

<div>
    @include('header')
</div>

That will put all the header.wlf view content inside the div tags.

The included view has access to all the variables in the current scope.

View inheritance

View inheritance is a great feature to reduce repeated code.

Wolff supports view inheritance, but not multiple view inheritance.

Extending the view

The parent view can have multiple blocks which will be used by the child views to redefine what is inside them.

A child view must extend from a parent, and for that, use the following syntax.

@extends('parent_view')

Print parent block

You can print the content of a parent's block anywhere in the child view with the following syntax.

{[ parent block_name ]}

Example

app/views/base.wlf:

<!DOCTYPE html>
<head>
    {[ block head ]}
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
    {[ endblock ]}
</head>
<body>
    {[ block body ]}
    {[ endblock ]}
</body>
</html>

app/views/child.wlf:

@extends('base')

{[ block head ]}
    {[ parent head ]}
    <title>Tundra</title>
{[ endblock ]}

{[ block body ]}
    <div>Hello world</div>
{[ endblock ]}

Given the examples of above, the following code:

View::render('child');

Will render this:

<!DOCTYPE html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Tundra</title>
</head>
<body>
    <div>Hello world</div>
</body>
</html>

Extending the template

custom($func): void

You can extend the template engine and make your own tags or rules by using the custom method.

The method takes a closure, which must take a parameter that is suposed to be the view content and it must return it. What you do with the view content inside the function is up to you.

Example

If you add the following code to the system/web.php file:

Wolff\Core\Template::custom(function ($content) {
    return preg_replace('/\!\!(.*?)\!\!/', '<?php echo "message: $1" ?>', $content);
});

Now the following tags in the views !! $str !! will be replaced by <?php echo "message: $str" ?>.

Documentation made with
Something is wrong in here? Make a issue/pull request on the repo.