whitecube / nova-flexible-content

Flexible Content & Repeater Fields for Laravel Nova
MIT License
788 stars 231 forks source link

"relationResolver()" I get this error #445

Closed engbz closed 1 year ago

engbz commented 1 year ago

hello, can you please help me how to solve this error.

Call to undefined method App\Nova\Flexible\Layouts\SimpleWysiwygLayout::relationResolver()

toonvandenbos commented 1 year ago

Hi @eno7x, does your SimpleWysiwygLayout class extend the package's Whitecube\NovaFlexibleContent\Layouts\Layout class?

I did a quick check and it seems the relationResolver method is not defined in the LayoutInterface, which is probably an issue if you're only implementing the Interface instead of extending the base Layout class.

engbz commented 1 year ago

Hi @toonvandenbos Is there a video on how to use this? Can't I use it like in the example below

public function fields(Request $request)
{
    return [
        Text::make('Title'),
        Flexible::make('Content')
            ->addLayout('Simple content section', 'wysiwyg', [
                Text::make('Title'),
                Markdown::make('Content')
            ])
            ->addLayout('Video section', 'video', [
                Text::make('Title'),
                Image::make('Video Thumbnail', 'thumbnail'),
                Text::make('Video ID (YouTube)', 'video'),
                Text::make('Video Caption', 'caption')
            ])
    ];
}
johnpuddephatt commented 1 year ago

@eno7x your example code looks fine. I'm assuming that's in your App\Nova\{resourceName}.php file?

In your original post there's a reference to App\Nova\Flexible\Layouts\SimpleWysiwygLayout, which makes me wonder if you're mixing two approaches.

You either want to be defining your flexible layout within your Nova resource, as shown in your example code.

OR

You want to be creating a layout class in App\Nova\Flexible\Layouts with a fields method on it that defines your fields. If you do that your code above becomes something like:

public function fields(Request $request)
{
    return [
        Text::make('Title'),
        Flexible::make('Content')
            ->addLayout(\App\Nova\Flexible\Layouts\SimpleWysiwygLayout::class)
            ->addLayout(\App\Nova\Flexible\Layouts\VideoSectionLayout::class)
    ];
}

You no longer define the fields in your Nova resource because they're defined on the layout class.

Using this second approach is useful not only for avoiding duplication. It also opens up the possibility of using accessors on your layout classes which is pretty cool (e.g. you could create an accessor that takes your Youtube video ID above and turns it into OEmbed data). You need to write a custom flexible cast for this to work but it's pretty straightforward, you basically just list your custom layout classes.

engbz commented 1 year ago

Hi @johnpuddephatt johnpuddephatt, thank you for your answer. I just tried to use it as "App\Nova{resourceName}" but I think I'm doing something wrong. Can't I use this without "preset,layout,resolver"

johnpuddephatt commented 1 year ago

Yes. you can just add the code in your second comment above ( public function fields(...) {[ ... ]} ) to your Nova resource, e.g. in \App\Nova\Page.php

You do not need to create a preset/layout/resolver to do this. Adding this is all you should need to do to see the flexible field appear in Nova.

To output the information on your frontend you will need to use either the HasFlexible trait or casting.

engbz commented 1 year ago

Hello again @johnpuddephatt , I'm trying to do what you say, but it's still the mistake I got. "Call to Undefined Method WhiteCube \ Novaflexiblecontent \ Layouts \ Layout :: Relationresolver ()" I don't know where I did wrong :(

// App\Nova\Post.php

public function fields(NovaRequest $request)
{
    return [

         Text::make('Name'),

        Flexible::make('Materials','materials')
            ->addLayout('Simple content section', 'wysiwyg', [
                Text::make('Name'),
            ])
            ->addLayout('Video section', 'video', [
                Text::make('Name'),
            ])

    ];
}

// App\Models\Post.php

class Post extends Model
{
    use HasFactory;
    use HasFlexible;

    protected $table = "posts";

    protected $guarded = [];

    public function getFlexibleContentAttribute()
    {
        return $this->flexible('materials');
    }

}
engbz commented 1 year ago

It works when I don't give "wysiwyg, video", the second parameter of "addLayout", but the fields are not visible

public function fields(NovaRequest $request)
{
    return [

         Text::make('Name'),

        Flexible::make('Materials','materials')
            ->addLayout('Simple content section', 'wysiwyg', [
                Text::make('Name'),
            ])
            ->addLayout('Video section', 'video', [
                Text::make('Name'),
            ])

    ];
}
johnpuddephatt commented 1 year ago

I can't replicate this...

Do you have any casts or attribute mutators (e.g. getMaterialsAttribute() ) defined on your model?

Are you seeing the Call to undefined method... error in Nova or on your frontend?

engbz commented 1 year ago

getMaterialsAttributedoes not exist in Model

->addLayout('Simple content section', 'wysiwyg', [......])

This is the error I get when I give the second parameter "wysiwyg" in the "addLayout" section Call to undefined method App\Nova\Flexible\Layouts\SimpleWysiwygLayout::relationResolver()

eugenbg commented 1 year ago

got the same problem too, just installed the package and added the example code from the docs

engbz commented 1 year ago

got the same problem too, just installed the package and added the example code from the docs

did you solve the problem

eugenbg commented 1 year ago

this was fixed in 1.0.6, I was using the version 1.0.2