View

Webman uses PHP native syntax as the template by default, which offers the best performance when opcache is enabled. In addition to PHP native templates, Webman also provides template engines like Twig, Blade, and think-template.

Enable Opcache

When using views, it is highly recommended to enable the opcache.enable and opcache.enable_cli options in php.ini to allow the template engines to achieve the best performance.

Install Twig

  1. Install via composer

composer require twig/twig

  1. Modify the configuration in config/view.php to:
    
    <?php
    use support\view\Twig;

return [
'handler' => Twig::class
];

> **Tip**
> Other configuration options can be passed via `options`, for example:

```php
return [
    'handler' => Twig::class,
    'options' => [
        'debug' => false,
        'charset' => 'utf-8'
    ]
];

Install Blade

  1. Install via composer
composer require psr/container ^1.1.1 webman/blade
  1. Modify the configuration in config/view.php to:
    
    <?php
    use support\view\Blade;

return [
'handler' => Blade::class
];


## Install think-template
1. Install via composer

`composer require topthink/think-template`

2. Modify the configuration in `config/view.php` to:
```php
<?php
use support\view\ThinkPHP;

return [
    'handler' => ThinkPHP::class,
];

Tip
Other configuration options can be passed via options, for example:

return [
    'handler' => ThinkPHP::class,
    'options' => [
        'view_suffix' => 'html',
        'tpl_begin' => '{',
        'tpl_end' => '}'
    ]
];

Native PHP Template Engine Example

Create the file app/controller/UserController.php as follows:

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function hello(Request $request)
    {
        return view('user/hello', ['name' => 'webman']);
    }
}

Create the file app/view/user/hello.html as follows:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>webman</title>
</head>
<body>
hello <?=htmlspecialchars($name)?>
</body>
</html>

Twig Template Engine Example

Modify the configuration in config/view.php to:

<?php
use support\view\Twig;

return [
    'handler' => Twig::class
];

app/controller/UserController.php as follows:

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function hello(Request $request)
    {
        return view('user/hello', ['name' => 'webman']);
    }
}

The file app/view/user/hello.html as follows:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>webman</title>
</head>
<body>
hello {{name}}
</body>
</html>

For more documentation, refer to Twig.

Blade Template Example

Modify the configuration in config/view.php to:

<?php
use support\view\Blade;

return [
    'handler' => Blade::class
];

app/controller/UserController.php as follows:

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function hello(Request $request)
    {
        return view('user/hello', ['name' => 'webman']);
    }
}

The file app/view/user/hello.blade.php as follows:

Note: The suffix of Blade templates is .blade.php

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>webman</title>
</head>
<body>
hello {{$name}}
</body>
</html>

For more documentation, refer to Blade.

ThinkPHP Template Example

Modify the configuration in config/view.php to:

<?php
use support\view\ThinkPHP;

return [
    'handler' => ThinkPHP::class
];

app/controller/UserController.php as follows:

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function hello(Request $request)
    {
        return view('user/hello', ['name' => 'webman']);
    }
}

The file app/view/user/hello.html as follows:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>webman</title>
</head>
<body>
hello {$name}
</body>
</html>

For more documentation, refer to think-template.

Template Assignment

In addition to using view(template, variable array) for template assignment, we can also assign values to the template at any point by calling View::assign(). For example:

<?php
namespace app\controller;

use support\Request;
use support\View;

class UserController
{
    public function hello(Request $request)
    {
        View::assign([
            'name1' => 'value1',
            'name2'=> 'value2',
        ]);
        View::assign('name3', 'value3');
        return view('user/test', ['name' => 'webman']);
    }
}

View::assign() is very useful in certain scenarios. For example, if every page in a system needs to display the current logged-in user's information at the header, it would be tedious to assign this information using view('template', ['user_info' => 'User Info']); for each page. The solution is to obtain user information in middleware and then use View::assign() to pass user information to the template.

About View File Paths

Controller

When a controller calls view('template name',[]);, the view files are looked for according to the following rules:

  1. If it starts with /, use that path directly to find the view file.
  2. If it does not start with / and is not a multi-application, use the corresponding view file in app/view/.
  3. If it does not start with / and is a multi-application, use the corresponding view file in app/application_name/view/.
  4. If no template parameter is passed, it will automatically look for the template file according to rules 2 and 3.

Example:

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function hello(Request $request)
    {
        // Equivalent to return view('user/hello', ['name' => 'webman']);
        // Equivalent to return view('/app/view/user/hello', ['name' => 'webman']);
        return view(['name' => 'webman']);
    }
}

Closure Function

In closure functions, $request->app is null and does not belong to any application, so closure functions use view files under app/view/. For example, if a route is defined in config/route.php:

Route::any('/admin/user/get', function (Request $request) {
    return view('user', []);
});

It will use app/view/user.html as the template file (when using Blade templates, the template file will be app/view/user.blade.php).

Specify Application

To allow templates to be reused in multi-application mode, view($template, $data, $app = null) provides a third parameter $app, which can be used to specify which application's directory to use for the template. For example, view('user', [], 'admin'); will force the use of the view file in app/admin/view/.

Omit Template Parameters

In the class controller, template parameters can be omitted. For example:

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function hello(Request $request)
    {
        // Equivalent to return view('user/hello', ['name' => 'webman']);
        // Equivalent to return view('/app/view/user/hello', ['name' => 'webman']);
        return view(['name' => 'webman']);
    }
}

Extend Twig

We can extend the Twig view instance by giving a callback to the configuration view.extension, for example, the config/view.php can look like this:

<?php
use support\view\Twig;
return [
    'handler' => Twig::class,
    'extension' => function (\Twig\Environment $twig) {
        $twig->addExtension(new your\namespace\YourExtension()); // Add Extension
        $twig->addFilter(new \Twig\TwigFilter('rot13', 'str_rot13')); // Add Filter
        $twig->addFunction(new \Twig\TwigFunction('function_name', function () {})); // Add Function
    }
];

Extend Blade

Similarly, we can extend the Blade view instance by providing a callback to the configuration view.extension, for example, the config/view.php can look like this:

<?php
use support\view\Blade;
return [
    'handler' => Blade::class,
    'extension' => function (Jenssegers\Blade\Blade $blade) {
        // Add custom directive to Blade
        $blade->directive('mydate', function ($timestamp) {
            return "<?php echo date('Y-m-d H:i:s', $timestamp); ?>";
        });
    }
];

Using Component in Blade

Assuming we need to add an Alert component.

Create app/view/components/Alert.php

<?php

namespace app\view\components;

use Illuminate\View\Component;

class Alert extends Component
{

    public function __construct()
    {

    }

    public function render()
    {
        return view('components/alert')->rawBody();
    }
}

Create app/view/components/alert.blade.php

<div>
    <b style="color: red">hello blade component</b>
</div>

/config/view.php should look similar to the following code:

<?php
use support\view\Blade;
return [
    'handler' => Blade::class,
    'extension' => function (Jenssegers\Blade\Blade $blade) {
        $blade->component('alert', app\view\components\Alert::class);
    }
];

Now, the Blade component Alert has been set up, and when using it in the template, it looks like this:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>webman</title>
</head>
<body>

<x-alert/>

</body>
</html>

Extend think-template

To extend the tag library in think-template, use view.options.taglib_pre_load, for example:

<?php
use support\view\ThinkPHP;
return [
    'handler' => ThinkPHP::class,
    'options' => [
        'taglib_pre_load' => your\namespace\Taglib::class,
    ]
];

For more details, refer to think-template tag extension.