Using Laravel Translatable in Kirby CMS

I'm still evaluating Kirby CMS against my decision to use [Backpack for Laravel]() as a database admin. So far so good. Since it's a multi-language database table, I used the spatie/laravel-translatable package that saves translation as JSON in the respective column.

id title
32 {"en":"Title","de":"Titel"}

Retriving the right translation is as easy as $myModel->title and depending whats set as language in your Laravel app you get the right translated item.

Now Kirby handles things a bit different and it would be easy to recreate this kind of functionality, but why not let utilize some Laravel in here?

Install dependencies

First install the following dependencies in this order:

  1. afbora/kirby-blade: Enable Laravel Blade Template Engine for Kirby 3
  2. beebmx/kirby-db: Enable Kirby 3 database support for Illuminate\Database
  3. spatie/laravel-translatable: Making Eloquent models translatable

If you don't use kirby-blade then it doesn't matter, but right now (2020-10-04) kirby-blade depends on packages from Laravel 7.x and laravel-translatable pulls in Laravel 8.x packages if it's not restricted by another package.

Setting up the autoloader in /composer.json

I could use a simple require but I think a better way is to setup a PSR-4 autoloader and use namespaces etc.

    "autoload": {
      "psr-4": {
        "MO\\": "site/"
      }
    }

Setup the Eloquent Model

The model is placed at site/models/ORM/Categories.php (to differentiate from Kirby Page Models)

<?php

namespace MO\models\ORM;
use Beebmx\KirbyDB\Model;
use Spatie\Translatable\HasTranslations;

class Categories extends Model
{
    use HasTranslations;
    protected $table = 'products_categories';
    public $translatable = ['title'];
}

Setup the Kirby Page Model

The Page model at resides at site/models/categories.php

<?php

use MO\models\ORM as ORM;

class CategoriesPage extends Kirby\Cms\Page
{
    /**
     * Language Code
     * @var string
     */
    public $lc;

    public function __construct(array $props)
    {
        parent::__construct($props);
        // this only set the default language ?!
        $this->lc = $this->kirby()->language()->code();
    }

    public function children()
    {

        $results = [];
        $pages   = [];

        $this->lc = $this->kirby()->language()->code();
        $cats = ORM\Categories::all();
        foreach($cats as $cat) {
            // set the locale for translatable
            $cat->setLocale($this->lc);
            #d($cat->title);
            $pages[] = [
              'slug'     => $cat->id,
              'num'      => 0,
              'template' => 'comment',
              'model'    => 'comment',
              'content'  => [
                'title'  => $cat->title,
              ]
            ];
        }

        return Pages::factory($pages, $this);
    }
}

And, any idea why I can't set $this->lc in the CategoriesPage::__construct() ?