Mix Antler and Blade to Master Translate(able)
I'm using translatable models and multi-language CRUDs in Backpack for Laravel and I need to render a custom route with it in Statamic.
This is all based on spatie/laravel-translatable
and it saves multi-language fields in JSON.
First the route in routes/web.php
<?php
Route::get('/categories', function () {
// https://statamic.dev/controllers#antlers-views
return (new \Statamic\View\View)
->template('categories')
->layout('layout')
->with([
'categories' => \App\Models\Products_category::all()
]);
});
/**
* OR
*/
// https://statamic.dev/routing#statamic-routes
Route::statamic('/categories', 'categories', [
'layout' => 'layout' // optional, uses the default template if missing
'categories' => \App\Models\Products_category::all()
]);
The Antlers layout in resources/views/layout.antlers.html
<!doctype html>
<html lang="{ { site:short_locale } }">
<head>
<meta charset="utf-8">
</head>
<body>
<div class="page">
{ { template_content } }
</div>
</body>
</html>
and I had a resources/views/categories.blade.php
<ul>
@foreach ($categories as $category)
<li><a href="{ { url('category/' . $category->id) } }">{ { $category->title } }</a></li>
@endforeach
</ul>
🙄 TL;DR
According to the docs you are able to use Antlers and Blade templates1 along side, but not really
When Statamic attempts to render a URL (eg. an entry), two views are combined. A template gets injected into a layout’s template_content variable. When the template is not an Antlers view, this rule doesn’t apply. The layout is ignored, allowing you to use @extends the way you would expect. -- https://statamic.dev/template-engines#layouts
I had no real luck to mix them!
The categories list was rendered without the layout. @extends('layout)
and { { yield:template_content } }
didn't work either
So I created an resources/views/categories.antlers.html
<ul>
{ { categories } }
<li>
<a href="category/{ { id } }">
{ { title } }
</a>
</li>
{ { /categories } }
</ul>
That worked, but {{ title }}
was missing since this is a translatable field, that means it's an object of keys and values:
$title = [
'de' => 'Titel',
'en' => 'Title'
];
and therefore nothing was rendered. I had to explicitly write {{ title.de }}
in my template and that was a no-go, because it defeats the purpose of multi-language fields in translatable.
Solution: Use a Partial!
Someone on the Statamic Discord2 pointed out that I could use partial.
So resources/views/categories.antlers.html
became:
{ { partial:categories/list } }
and I renamed the initial resources/views/categories.blade.php
to resources/views/categories/list.blade.php
<ul>
@foreach ($categories as $category)
<li><a href="{ { url('category/' . $category->id) } }">{ { $category->title } }</a></li>
@endforeach
</ul>
and this way translatable objects were rendered.
I'm not there where I have to switch language, so that might be another challenge, but so far, this works.