Skip to content

marko/view-twig

Twig templating driver for the Marko Framework. Implements ViewInterface from marko/view using the Twig engine, with module-namespaced template resolution and automatic caching.

Terminal window
composer require marko/view-twig

This automatically installs marko/view. Note: marko/view-twig conflicts with marko/view-latte --- install only one view driver per project.

Configure via the view config key. Settings from marko/view (cache_directory, auto_refresh) apply to all drivers. The following are Twig-specific defaults:

config/view.php
return [
'cache_directory' => '/path/to/cache',
'auto_refresh' => true, // Set false in production
'extension' => '.twig',
'strict_variables' => true,
'autoescape' => 'html',
'debug' => false,
'charset' => 'UTF-8',
];

Templates are rendered using the module namespace syntax:

use Marko\View\ViewInterface;
$view->render('blog::post/index', ['posts' => $posts]);

The format is module::path/to/template where:

  • module is the module name (e.g., blog, admin)
  • path/to/template is the path within resources/views/

The render() method returns an HTTP Response object. Use renderToString() when you need the raw HTML --- for example, when rendering email bodies:

use Marko\View\ViewInterface;
$html = $view->renderToString('blog::email/comment-verification/html', $data);
$text = $view->renderToString('blog::email/comment-verification/text', $data);

All template includes use the same namespaced syntax:

{% include 'blog::post/list/item' with { post: post } %}
{% include 'blog::pagination/index' with { pagination: posts } %}

Relative paths are not supported. This ensures:

  • Consistent syntax throughout templates
  • Templates can include from any module
  • No fragile relative path dependencies

Pass variables to included templates as named parameters:

{% include 'blog::post/list/item' with { post: post, showAuthor: true } %}

Default values in the included template:

resources/views/post/list/item.twig
{# post/list/item.twig #}
{% set showAuthor = showAuthor ?? true %}
{% set linkAuthor = linkAuthor ?? true %}
<li class="post-item">
<h2><a href="/blog/{{ post.slug }}">{{ post.title }}</a></h2>
{% if showAuthor %}
<span>By {{ post.author.name }}</span>
{% endif %}
</li>

All templates must live within at least one directory. No top-level template files.

views/
post/
index.twig # Post listing
show.twig # Single post
list/
item.twig # Reusable list item
category/
show.twig
tag/
index.twig
author/
show.twig
search/
index.twig
bar.twig # Search input
comment/
form.twig
thread.twig
pagination/
index.twig

Email templates group HTML and plain text versions together:

views/
email/
comment-verification/
html.twig # HTML version
text.twig # Plain text version
welcome/
html.twig
text.twig

TwigView implements ViewInterface from marko/view.

MethodDescription
render(string $template, array $data = []): ResponseRender a template and return an HTTP response
renderToString(string $template, array $data = []): stringRender a template and return the raw HTML string
OptionTypeDescription
cache_directorystringDirectory for compiled template cache (from marko/view)
auto_refreshboolRecompile templates when source changes --- set false in production (from marko/view)
extensionstringTemplate file extension (default .twig)
strict_variablesboolThrow an error for undefined variables (default true)
autoescapestringAuto-escaping strategy: html, js, css, url, name, or false (default html)
debugboolEnable Twig debug mode (default false)
charsetstringTemplate charset (default UTF-8)