Using Laravel Translatable in Kirby CMS
- Install dependencies
- Setting up the autoloader in /composer.json
- Setup the Eloquent Model
- Setup the Kirby Page Model
Updated 2021-07-13: This should work with Kirby 3.5 and PHP 7.3
Here is a way how to use Kirby CMS along with Backpack for Laravel as a database admin (or any other app that uses Laravel ORM) with multi-language database table. For that, use the spatie/laravel-translatable
package that saves translation as JSON in the respective column.
id | title |
---|---|
32 | {"en":"Title","de":"Titel"} |
Retrieving 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 utilize some Laravel's black magic here?
Install dependencies
I'm using afbora/kirby-blade: Enable Laravel Blade Template Engine for Kirby 3 and ran in some conflicts with beebmx/kirby-db: Enable Kirby 3 database support for Illuminate\Database, because the latter is using Laravel 5.x (to this date 2021-07-13) illuminate/database
under the hood.
Also there are some PSR-4 warnings so I tried to fix that in my own fork.
1. Change /composer.json
Require my fork of beebmx/kirby-db "beebmx/kirby-db": "dev-patch-1"
and refer to it in the repositories
part of the file.
{
"require": {
"php": ">=7.1.0",
"getkirby/cms": "^3.0",
...
"beebmx/kirby-db": "dev-patch-1"
},
"autoload": {
"psr-4": {
"MO\\": "site/"
}
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/marcus-at-localhost/kirby-db"
}
]
}
2. Install beebmx/kirby-db
Run
$ composer update beebmx/kirby-db
this will install my fork of the plugin, which is basically just an updated composer.json file
3. Update the illuminate/*
Bundle
The plugin comes with an outdated version of Laravel's Eloquent ORM and this might kill your app, if you have more recent Laravel libraries installed, like collections or afbora/kirby-blade
.
To fix that, run right after step 2.
$ composer update --working-dir=./site/plugins/kirby-db
This will update illuminate/database
to the latest version and installs spatie/translatable
as required for this exercise.
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 autoload 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() ?