The framework wraps marwa-view for rendering Twig templates with theme support.
// Controller
return view('welcome', ['name' => 'Alice']);
view()->share('appName', 'Marwa');
echo view()->render('welcome', [
'name' => 'Alice',
]);
In Twig templates, use double curly braces for variables:
<!-- welcome.twig -->
<p>Hello, Alice!</p>
// From controller
return view('user.profile', [
'user' => $user,
'title' => 'Profile',
]);
// Or share globally
view()->share('siteName', 'My App');
// Available in all views
view()->share('siteName', 'My App');
Learn more about Twig template inheritance at: https://twig.symfony.com/doc/templates.html#inheritance
Create a base layout:
<!-- resources/views/layout.twig -->
<!DOCTYPE html>
<html>
<head>
<title>Default Title</title>
</head>
<body>
<main>Content goes here</main>
</body>
</html>
Extend the layout in child templates:
<!-- resources/views/home.twig -->
<!-- extends layout -->
<h1>Welcome</h1>
For Twig control structures, see: https://twig.symfony.com/doc/templates.html
Use conditional logic in templates:
<!-- If user exists -->
<p>Hello!</p>
Iterate over collections:
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
Apply Twig filters to modify output - see: https://twig.symfony.com/doc/filters/index.html
<p>UPPERCASE TEXT</p>
<p>Truncated text...</p>
For includes, see: https://twig.symfony.com/doc/tags/include.html
<!-- Include header partial -->
<!-- Include navbar partial -->
Create reusable components - see: https://twig.symfony.com/doc/tags/macro.html
<!-- Define input field macro -->
<!-- Define button macro -->
// In service provider or module
view()->addNamespace('blog', resource_path('views/themes/blog'));
For namespace usage in templates, use the double-colon syntax:
<!-- blog::header -->
<!-- blog::layout -->
resources/views/themes/
└── default/
├── manifest.php
└── views/
├── layout.twig
└── home.twig
<?php
// resources/views/themes/default/manifest.php
return [
'name' => 'Default',
'parent' => null,
];
view()->theme('dark');
view()->setFallbackTheme('default');
$current = view()->currentTheme();
$selected = view()->selectedTheme();
// Shortcut
return view('page', $data);
// With status
return response()->view('page', $data, 200);
// With headers
return response()->view('page', $data)
->header('X-Custom', 'value');
// Render to string
$html = view()->render('page', $data);
view()->clearCache();
In config/view.php:
return [
'paths' => [
resource_path('views'),
],
'cachePath' => storage_path('cache/views'),
'debug' => env('VIEW_DEBUG', false),
];
<link rel="stylesheet" href="css/style.css">
<script src="js/app.js"></script>
<a href="/">Home</a>
<a href="/user/1">Profile</a>
<p>Hello, Guest</p>
<p>App: My App</p>
public function index(): Response
{
view()->share('siteName', 'My Blog');
return view('blog.index', [
'posts' => Post::published(),
]);
}
<!-- resources/views/layout.twig -->
<!DOCTYPE html>
<html>
<head>
<title>My Blog</title>
</head>
<body>
<header>My Blog</header>
<main>Content</main>
<footer>2024</footer>
</body>
</html>
<!-- resources/views/blog/index.twig -->
<h1>Latest Posts</h1>
<!-- Post list -->
view() Helper// Render view
view('template', $data);
// Share data globally
view()->share('key', $value);
// Check exists
view()->exists('template');
| Key | Type | Default | Description |
|---|---|---|---|
paths |
array |
[] |
View directories |
cachePath |
string |
- | Compiled views cache |
debug |
bool |
false |
Debug mode |
themePath |
string |
- | Theme directory |
activeTheme |
string |
default |
Active theme |
fallbackTheme |
string |
- | Fallback theme |