twill icon indicating copy to clipboard operation
twill copied to clipboard

InlineRepeaters doesn't fill MediaFields in backend panel singleton module

Open cloon opened this issue 1 year ago • 6 comments

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

  1. 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();
    }

}
  1. 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'];

}
  1. 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

cloon avatar Nov 28 '24 16:11 cloon

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.

ifox avatar Nov 28 '24 16:11 ifox

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.

cloon avatar Nov 29 '24 13:11 cloon

I see that you are using translatable() on the medias field. Does it work if you don't?

ifox avatar Nov 29 '24 14:11 ifox

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(),
                    ])
            ]),
        ]));

cloon avatar Nov 29 '24 16:11 cloon

@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

cloon avatar Dec 02 '24 14:12 cloon

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

cloon avatar Dec 18 '24 13:12 cloon