InlineRepeaters doesn't fill MediaFields in backend panel singleton module
Description
The module saves correctly in database as json field. But in backend after a page reload the image doesn't display, showing an empty field. After that, new saves store empty values.
Steps to reproduce
- In my App/Http/Controllers/Twill/ModuleNameController.php : Added an InlineRepeater field inside fieldset, then added Medias field inside the repeater.
<?php
namespace App\Http\Controllers\Twill;
use A17\Twill\Models\Contracts\TwillModelContract;
use A17\Twill\Services\Forms\Fields\Files;
use A17\Twill\Services\Forms\Fields\Medias;
use A17\Twill\Services\Forms\Fields\Repeater;
use A17\Twill\Services\Forms\Fields\Wysiwyg;
use A17\Twill\Services\Forms\Fieldset;
use A17\Twill\Services\Forms\Fieldsets;
use A17\Twill\Services\Forms\InlineRepeater;
use A17\Twill\Services\Listings\Columns\Text;
use A17\Twill\Services\Listings\TableColumns;
use A17\Twill\Services\Forms\Fields\Input;
use A17\Twill\Services\Forms\Form;
use A17\Twill\Http\Controllers\Admin\SingletonModuleController as BaseModuleController;
use App\Models\Home;
use Illuminate\Support\Facades\Cache;
use Illuminate\View\View;
class HomeController extends BaseModuleController
{
protected $moduleName = 'homes';
protected $previewView = 'pages.home';
protected function previewData($item)
{
$presentation_url = $item->file('presentation_url');
return [
'content' => $item,
'presentation_url' => $presentation_url
];
}
/**
* See the table builder docs for more information. If you remove this method you can use the blade files.
* When using twill:module:make you can specify --bladeForm to use a blade form instead.
*/
public function getForm(TwillModelContract $model): Form
{
$form = Form::make();
$form->withFieldSets(new Fieldsets([
Fieldset::make()->title('Services')->id('services')->fields([
InlineRepeater::make()->name('services')->label('Service')
->fields([
Medias::make()
->name('cover')
->label(twillTrans('Cover image'))
->translatable()
->max(1),
Input::make()->name('title')->translatable(),
Wysiwyg::make()
->name('lead')
->toolbarOptions([ [ 'header' => [1, 2, false] ], 'ordered', 'bullet' ])
->maxLength(200)
->translatable(),
])
]),
]));
return $form;
}
/**
* This method can be used to enable/disable defaults. See setUpController in the docs for available options.
*/
protected function setUpController(): void
{
$this->disablePermalink();
$this->disableEditor();
$this->disablePublish();
}
}
- Added configurations in my model :
<?php
namespace App\Models;
use A17\Twill\Models\Behaviors\HasBlocks;
use A17\Twill\Models\Behaviors\HasTranslation;
use A17\Twill\Models\Behaviors\HasMedias;
use A17\Twill\Models\Behaviors\HasRevisions;
use A17\Twill\Models\Behaviors\HasFiles;
use A17\Twill\Models\Model;
class Home extends Model
{
use HasBlocks;
use HasFiles;
use HasMedias;
use HasRevisions;
use HasTranslation;
protected $fillable = [
'published',
'title',
'header_text',
'services',
'cases',
'linkedin_url',
'instagram_url',
'facebook_url',
'presentation_url',
];
public $filesParams = [
'presentation_url'
];
public $translatedAttributes = [
'title',
'header_text',
'presentation_url',
];
protected $casts = [
'services' => 'array',
'cases' => 'array',
];
protected $with = ['files'];
}
- Create and run migration for model:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('homes', function (Blueprint $table) {
$table->json('services')->nullable();
});
Schema::table('home_translations', function (Blueprint $table) {
$table->json('services')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('homes', function (Blueprint $table) {
$table->dropColumn('services');
});
Schema::table('home_translations', function (Blueprint $table) {
$table->dropColumn('services');
});
}
};
Expected result
After saving the module from backend, the content store in database. After reload the backend page, the images show in repeater fields
Actual result
After saving the module from backend, the content store in database. After reload the backend page, cant see the images stored in database
Versions
Twill version: 3.0 Laravel version: 11 PHP version: 8.2 Database engine: MySql
Support for medias fields in JSON repeater has been released in Twill 3.3.0: https://github.com/area17/twill/pull/2554
You will need to upgrade if you want to use this.
Hi @ifox thanks for the reply. Updated to latest version: version 3.4.1.
Delete module entry in database.
Tried a few commands after the update: composer dump-autoload php artisan optimize:clear
The problem persist. Same error: Save in database but after reload the image disappear.
I see that you are using translatable() on the medias field. Does it work if you don't?
Removing the translatable() on media, same result.
$form = Form::make();
$form->withFieldSets(new Fieldsets([
Fieldset::make()
->title('Services')
->id('services')
->fields([
InlineRepeater::make()
->name('services')
->label('Service')
->fields([
Medias::make()
->name('service_cover')
->label(twillTrans('Cover image'))
->max(1),
Input::make()->name('title')->translatable(),
Wysiwyg::make()
->name('lead')
->toolbarOptions([ [ 'header' => [1, 2, false] ], 'ordered', 'bullet' ])
->maxLength(200)
->translatable(),
])
]),
]));
@ifox , Created new module, implementing the Form Fields using blade directive doesn't work ether https://twillcms.com/guides/json-repeaters.html
I will create a new project to compare. But I got no more clues to follow
Ok, after reinstall the project to reproduce the error. I Discover that for some reason multiple inline repeaters as JSON with images, the images cant be loaded for some reason. My solution is move to models type relationship , using different modules repeaters can be listed in a separate screens