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.