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.
Installation
Section titled “Installation”composer require marko/view-twigThis automatically installs marko/view. Note: marko/view-twig conflicts with marko/view-latte --- install only one view driver per project.
Configuration
Section titled “Configuration”Configure via the view config key. Settings from marko/view (cache_directory, auto_refresh) apply to all drivers. The following are Twig-specific defaults:
return [ 'cache_directory' => 'storage/views', // relative to the project root; created 0700 'auto_refresh' => true, // Set false in production 'extension' => '.twig', 'strict_variables' => true, 'autoescape' => 'html', 'debug' => false, 'charset' => 'UTF-8',];Rendering Templates
Section titled “Rendering Templates”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:
moduleis the module name (e.g.,blog,admin)path/to/templateis the path withinresources/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);Template Includes
Section titled “Template Includes”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
Passing Data to Includes
Section titled “Passing Data to Includes”Pass variables to included templates as named parameters:
{% include 'blog::post/list/item' with { post: post, showAuthor: true } %}Default values in the included template:
{# 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>Linking to Named Routes
Section titled “Linking to Named Routes”The route() function builds URLs for named routes through UrlGeneratorInterface, so templates don’t hard-code paths:
<a href="{{ route('blog.post.show', {slug: post.slug}) }}">{{ post.title }}</a><a href="{{ route('blog.index', {page: 2}) }}">Next page</a> {# /blog?page=2 #}<link rel="canonical" href="{{ route('blog.post.show', {slug: post.slug}, true) }}">The arguments match UrlGeneratorInterface::route(string $name, array $parameters = [], bool $absolute = false). Parameters the path doesn’t use become the query string, and true as the third argument uses APP_URL. The function isn’t marked safe, so its output is escaped like any other value (& renders as &). An unknown name or a missing parameter throws UrlGenerationException. Twig wraps it in a Twig\Error\RuntimeError and the render fails.
Template Organization
Section titled “Template Organization”All templates must live within at least one directory. No top-level template files.
Standard Structure
Section titled “Standard Structure”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.twigEmail Templates
Section titled “Email Templates”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.twigAPI Reference
Section titled “API Reference”TwigView implements ViewInterface from marko/view.
Key Methods
Section titled “Key Methods”| Method | Description |
|---|---|
render(string $template, array $data = []): Response | Render a template and return an HTTP response |
renderToString(string $template, array $data = []): string | Render a template and return the raw HTML string |
Template Functions
Section titled “Template Functions”| Function | Description |
|---|---|
route(string $name, array $parameters = [], bool $absolute = false): string | URL for a named route (Marko\View\Twig\RouteExtension) |
Configuration Options
Section titled “Configuration Options”| Option | Type | Description |
|---|---|---|
cache_directory | string | Directory for compiled template cache (from marko/view). Defaults to storage/views under the project root; the factory refuses a directory that is world-writable or owned by another user --- see compiled-template cache directory |
auto_refresh | bool | Recompile templates when source changes --- set false in production (from marko/view) |
extension | string | Template file extension (default .twig) |
strict_variables | bool | Throw an error for undefined variables (default true) |
autoescape | string | Auto-escaping strategy: html, js, css, url, name, or false (default html) |
debug | bool | Enable Twig debug mode (default false) |
charset | string | Template charset (default UTF-8) |