Search code examples
laravelrepeatertwill

Twill repeaters translatable


I'm using twill for laravel

I need to have a translatable repeater like this translatable repeater

So i created the repeater model

php artisan twill:make:module TechnologyBenefits -P

If I do not enabled translation module and disable from form the translate key all works.

I don't understand how to make this work with the translations.

If I try to update my model (if there is a row repeater in db) with translation enabled this is what i see in db emptydb But the editor still empty

Instead if I try to update my model without a row this error appear

exception: "TypeError"
file: "/srv/www/mysite/current/vendor/laravel/framework/src/Illuminate/Database/Grammar.php"
line: 136
message: "Illuminate\\Database\\Grammar::parameterize(): Argument #1 ($values) must be of type array, int given, called in /srv/www/mysite/current/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php on line 920"

So i'm also trying to use jsonRepeaters

I save add in my model a column named "field_repeaters"

public function afterSave($object, $fields)
{   
    $tech_repeaters = [];
    $tech_repeaters['benefits'] = [
        'title' => collect($fields['repeaters']['info_benefits_repeater'] ?? [])->pluck('title'),
        'description' => collect($fields['repeaters']['info_benefits_repeater'] ?? [])->pluck('desc'),
    ];
    $tech_repeaters['materials'] = [
        'name' => collect($fields['repeaters']['info_materials_repeater'] ?? [])->pluck('name'),
        'description' => collect($fields['repeaters']['info_materials_repeater'] ?? [])->pluck('description'),
        'media' => collect($fields['repeaters']['info_materials_repeater'] ?? [])->pluck('media'),
        'ideal_for' => collect($fields['repeaters']['info_materials_repeater'] ?? [])->pluck('ideal_for'),
    ];
    $tech_repeaters['videos'] = [
        'embed' => collect($fields['repeaters']['info_materials_repeater'] ?? [])->pluck('embed'),
    ];
    $object->field_repeaters = json_encode($tech_repeaters, true);
    $object->save();

    parent::afterSave($object, $fields);
}

This save in field_repeater an array with all the repeaters and translations

{'benefit': {'title': {'en' => 'english title', ru => 'ru title'}, 'desc': {'en': 'desc', 'ru': 'desc_ru'}}, ... }

Now I need to populate field with getFormFields

public function getFormFields($object)
{
    $fields = parent::getFormFields($object);

    if(isset($fields['field_repeaters'])){
        $repeaters = json_decode($fields['field_repeaters'], true);
        foreach($repeaters as $repeaterName =>$serializedData){
            // $fields = $this->getJsonRepeater($fields, $repeaterName, $serializedData);
            $repeatersFields = [];
            $repeatersBrowsers = [];
            $repeatersList = app(BlockCollection::class)->getRepeaterList()->keyBy('name');

            foreach ($serializedData as $index => $repeaterItem) {
                $id = $repeaterItem['id'] ?? $index;

                $repeaters[] = [
                    'id' => $id,
                    'type' => $repeatersList[$repeaterName]['component'],
                    'title' => $repeatersList[$repeaterName]['title'],
                    'titleField' => $repeatersList[$repeaterName]['titleField'],
                    'hideTitlePrefix' => $repeatersList[$repeaterName]['hideTitlePrefix'],
                ];

                if (isset($repeaterItem['browsers'])) {
                    foreach ($repeaterItem['browsers'] as $key => $values) {
                        $repeatersBrowsers["blocks[$id][$key]"] = $values;
                    }
                }

                $itemFields = Arr::except($repeaterItem, ['id', 'repeaters', 'files', 'medias', 'browsers', 'blocks']);

                var_dump($itemFields)
                foreach ($itemFields as $index => $value) {
                    $repeatersFields[] = [
                        'name' => "blocks[$id][$index]",
                        'value' => $value,
                    ];
                }
            }

            $fields['repeaters'][$repeaterName] = $repeaters;
            $fields['repeaterFields'][$repeaterName] = $repeatersFields;
            $fields['repeaterBrowsers'][$repeaterName] = $repeatersBrowsers;
        }
    }

I don't understand how to create the translated field correctly, through the internet I can't find anything that can explain to me how to have translatable repeaters


Solution

  • Seems like jsonRepeaters is the way to go and apparently this dude achieved it. I use jsonRepeaters feature myself and I also had to set the following on my model's repository (note about it in the docs).

    protected $jsonRepeaters = ['my_json_field'];