(You are reading the documentation for HTML v2. Switch to the documentation for Html v1.)
HTML
Install
In order to have an HTML reprensentation, Let’s install Twig v2 module with composer.
composer require madapaja/twig-module ^2.0
Next create the context file src/Module/HtmlModule.php
and install the TwigModule
.
namespace MyVendor\MyPackage\Module;
use BEAR\AppMeta\AppMeta;
use Madapaja\TwigModule\TwigErrorPageModule;
use Madapaja\TwigModule\TwigModule;
use Ray\Di\AbstractModule;
class HtmlModule extends AbstractModule
{
protected function configure()
{
$this->install(new TwigModule);
$this->install(new TwigErrorPageModule);
}
}
Update the context in bin/page.php
or public/index.php
and enable html
.
$context = 'cli-html-app'; // or 'html-app'
Template
One template file is required for one resource object class in var/templates
directory to represent in HTML.
For example, for src/Page/Index.php
resource class, a template file is required in var/templates/Page/Index.html.twig
.
The body of the resource is assigned to the template.
example)
src/Page/Index.php
class Index extend ResourceObject
{
public $body = [
['greeting' => 'Hello BEAR.Sunday']
];
}
var/templates/Page/Index.twig.php
<h1>{{ greeting }}</h1>
Output:
php bin/page.php get /
200 OK
content-type: text/html; charset=utf-8
<h1>Hello BEAR.Sunday</h1>
Select template file
Resource does not select the template file. It includes
depending on the state of the resource.
{% if user.is_login %}
{{ include('member.html.twig') }}
{% else %}
{{ include('guest.html.twig') }}
{% endif %}
In the resource class, you should only concern resource state. Then template should concern the resource representation. See Separation of concerns (SoC).
Error Page
Edit var/templates/error.html.twig
. Following values are assigned to the error page.
Variable | Title | Key |
---|---|---|
status | HTTP status | code, message |
e | Exception | code, message, class |
logref | Log ID | n/a |
例
{% extends 'layout/base.html.twig' %}
{% block title %}{{ status.code }} {{ status.message }}{% endblock %}
{% block content %}
<h1>{{ status.code }} {{ status.message }}</h1>
{% if status.code == 404 %}
<p>The requested URL was not found on this server.</p>
{% else %}
<p>The server is temporarily unable to service your request.</p>
<p>refference number: {{ logref }}</p>
{% endif %}
{% endblock %}
Assign resource
To refer to the properties of the resource object class, Use _ro
(resource object) to which the entire resource object is assigned
exmaple)
Todos.php
class Todos extend ResourceObject
{
public $code = 200;
public $text = [
'name' => 'BEAR';
];
public $body = [
['title' => 'run']
];
}
Todos.html.twig
{{ _ro.code }} // 200
{{ _ro.text.name }} // 'BEAR'
{% for todo in _ro.body %}
{{ todo.title }} // 'run'
{% endfor %}
Hierarchical view structure
You can have a view on a resource class basis. It represents the structure well. Also, the cache is also hierarchically done on a resource basis, so it is efficient.
example) page://self/index
which embeds app://self/todos
app://self/todos
class Todos extends ResourceObject
{
use AuraSqlInject;
use QueryLocatorInject;
public function onGet() : ResourceObject
{
$this->body = $this->pdo->fetchAll($this->query['todos_list'])
return $this;
}
}
{% for todo in _ro.body %}
{{ todo.title }}</td>
{% endfor %}
page://self/index
class Index extends ResourceObject
{
/**
* @Embed(rel="todos", src="app://self/todos")
*/
public function onGet() : ResourceObject
{
return $this;
}
}
{% extends 'layout/base.html.twig' %}
{% block content %}
{{ todos|raw }}
{% endblock %}
Extending Twig
When you extend Twig with the addExtension()
method, prepare Twig’s Provider class which performs extension and bind Provider
to Twig_Environment
class.
use Ray\Di\Di\Named;
use Ray\Di\ProviderInterface;
class MyTwigProvider implements ProviderInterface
{
private $twig;
/**
* @Named("original")
*/
public function __construct(\Twig_Environment $twig)
{
// $twig is an original \Twig_Environment instance
$this->twig = $twig;
}
public function get()
{
// Extending Twig
$this->twig->addExtension(new MyTwigExtension());
return $this->twig;
}
}
class HtmlModule extends AbstractModule
{
protected function configure()
{
$this->install(new TwigModule);
$this->bind(\Twig_Environment::class)->toProvider(MyTwigProvider::class)->in(Scope::SINGLETON);
}
}
Template for mobile device
To use the template for mobile devices, install MobileTwigModule
.
class HtmlModule extends AbstractModule
{
protected function configure()
{
$this->install(new TwigModule);
$this->install(new MobileTwigModule);
}
}
If there is a mobile site template Index.mobile.twig
that will replace Index.html.twig
, it will be used in preference.
Custom Settings
If you would like to change options depending on the context or add a template path, configuration values are bound to @TwigPaths
and @TwigOptions
annotations.
Note: Since caches are always created in the var/tmp
folder, there is no particular need for special settings for production.
namespace MyVendor\MyPackage\Module;
use Madapaja\TwigModule\Annotation\TwigDebug;
use Madapaja\TwigModule\Annotation\TwigOptions;
use Madapaja\TwigModule\Annotation\TwigPaths;
use Madapaja\TwigModule\TwigModule;
use BEAR\Package\AbstractAppModule;
class AppModule extends AbstractAppModule
{
protected function configure()
{
// ...
$this->install(new TwigModule);
// You can add twig template paths by the following
$appDir = $this->appMeta->appDir;
$paths = [
$appDir . '/src/Resource',
$appDir . '/var/templates'
];
$this->bind()->annotatedWith(TwigPaths::class)->toInstance($paths);
// Also you can set environment options
// @see http://twig.sensiolabs.org/doc/api.html#environment-options
$options = [
'debug' => false,
'cache' => $appDir . '/tmp'
];
$this->bind()->annotatedWith(TwigOptions::class)->toInstance($options);
// Only for debug option
$this->bind()->annotatedWith(TwigDebug::class)->toInstance(true);
}
}