### Install nova-flexible-content Source: https://whitecube.github.io/nova-flexible-content Install the package using Composer. This is the first step to using the Flexible content field in your Laravel Nova project. ```bash composer require whitecube/nova-flexible-content ``` -------------------------------- ### Implement custom field resolution Source: https://whitecube.github.io/nova-flexible-content The get method retrieves content and transforms it into a collection of hydrated Layout instances. ```php /** * get the field's value * * @param mixed $resource * @param string $attribute * @param \Whitecube\NovaFlexibleContent\Layouts\Collection $layouts * @return \Illuminate\Support\Collection */ public function get($resource, $attribute, $layouts) { $blocks = $resource->blocks()->orderBy('order')->get(); return $blocks->map(function($block) use ($layouts) { $layout = $layouts->find($block->name); if(!$layout) return; return $layout->duplicateAndHydrate($block->id, ['value' => $block->value]); })->filter(); } ``` -------------------------------- ### Generate Layout via Artisan Source: https://whitecube.github.io/nova-flexible-content Use the artisan command to scaffold a new layout class. ```bash php artisan flexible:layout {classname?} {name?} // Ex: php artisan flexible:layout SimpleWysiwygLayout wysiwyg ``` -------------------------------- ### Generate Preset via Artisan Source: https://whitecube.github.io/nova-flexible-content Use the artisan command to scaffold a new preset class. ```bash php artisan flexible:preset {classname?} // Ex: php artisan flexible:preset WysiwygPagePreset ``` -------------------------------- ### Create custom layout for media library Source: https://whitecube.github.io/nova-flexible-content Custom layouts must implement HasMedia and use the HasMediaLibrary trait to enable media fields. ```php use Spatie\MediaLibrary\HasMedia; use Whitecube\NovaFlexibleContent\Layouts\Layout; use Ebess\AdvancedNovaMediaLibrary\Fields\Images; use Whitecube\NovaFlexibleContent\Concerns\HasMediaLibrary; class SliderLayout extends Layout implements HasMedia { use HasMediaLibrary; protected $name = 'sliderlayout'; protected $title = 'SliderLayout'; public function fields() { return [ Images::make('Images', 'images') ]; } } ``` -------------------------------- ### Create a Custom Flexible Cast Source: https://whitecube.github.io/nova-flexible-content Extend the default FlexibleCast to map specific keys to custom layout classes. This allows for more structured handling of different flexible content layouts. ```php namespace App\Casts; class MyFlexibleCast extends FlexibleCast { protected $layouts = [ 'wysiwyg' => \App\Nova\Flexible\Layouts\WysiwygLayout::class, 'video' => \App\Nova\Flexible\Layouts\VideoLayout::class, ]; } ``` -------------------------------- ### Generate Resolver via Artisan Source: https://whitecube.github.io/nova-flexible-content Use the artisan command to scaffold a new resolver class for custom data storage. ```bash php artisan flexible:resolver {classname?} // Ex: php artisan flexible:resolver WysiwygPageResolver ``` -------------------------------- ### Define a Preset Class Source: https://whitecube.github.io/nova-flexible-content Create a Preset class to encapsulate complex Flexible field configurations and dynamic layouts. ```php namespace App\Nova\Flexible\Presets; use App\PageBlocks; use Whitecube\NovaFlexibleContent\Flexible; use Whitecube\NovaFlexibleContent\Layouts\Preset; class WysiwygPagePreset extends Preset { /** * The available blocks * * @var Illuminate\Support\Collection */ protected $blocks; /** * Create a new preset instance * * @return void */ public function __construct() { $this->blocks = PageBlocks::orderBy('label')->get(); } /** * Execute the preset configuration * * @return void */ public function handle(Flexible $field) { $field->button('Add new block'); $field->resolver(\App\Nova\Flexible\Resolvers\WysiwygPageResolver::class); $field->help('Go to the "Page blocks" Resource in order to add new WYSIWYG block types.'); $this->blocks->each(function($block) use ($field) { $field->addLayout($block->title, $block->id, $block->getLayoutFields()); }); } } ``` -------------------------------- ### Configure Post model for media library Source: https://whitecube.github.io/nova-flexible-content The parent model must implement HasMedia and use the InteractsWithMedia trait to support media library integration. ```php use Spatie\MediaLibrary\HasMedia; use Illuminate\Database\Eloquent\Model; use Spatie\MediaLibrary\InteractsWithMedia; use Whitecube\NovaFlexibleContent\Concerns\HasFlexible; class Post extends Model implements HasMedia { use HasFlexible; use InteractsWithMedia; } ``` -------------------------------- ### Define a Custom Layout Class Source: https://whitecube.github.io/nova-flexible-content Create a reusable layout by extending the Layout class and defining its fields. ```php namespace App\Nova\Flexible\Layouts; use Laravel\Nova\Fields\Text; use Laravel\Nova\Fields\Markdown; use Whitecube\NovaFlexibleContent\Layouts\Layout; class SimpleWysiwygLayout extends Layout { /** * The layout's unique identifier * * @var string */ protected $name = 'wysiwyg'; /** * The displayed title * * @var string */ protected $title = 'Simple content section'; /** * Get the fields displayed by the layout. * * @return array */ public function fields() { return [ Text::make('Title'), Markdown::make('Content') ]; } } ``` -------------------------------- ### Apply a Preset to a Field Source: https://whitecube.github.io/nova-flexible-content Reference the preset class within the Flexible field definition. ```php Flexible::make('Content') ->preset(\App\Nova\Flexible\Presets\WysiwygPagePreset::class); ``` -------------------------------- ### Register a Custom Layout Source: https://whitecube.github.io/nova-flexible-content Use the class name to add the custom layout to a Flexible field. ```php Flexible::make('Content') ->addLayout(\App\Nova\Flexible\Layouts\SimpleWysiwygLayout::class); ``` -------------------------------- ### Implement custom field persistence Source: https://whitecube.github.io/nova-flexible-content The set method saves Flexible content to a storage location, such as a database table, for later retrieval. ```php /** * Set the field's value * * @param mixed $model * @param string $attribute * @param \Illuminate\Support\Collection $groups * @return void */ public function set($model, $attribute, $groups) { $class = get_class($model); $class::saved(function ($model) use ($groups) { $blocks = $groups->map(function($group, $index) { return [ 'name' => $group->name(), 'value' => json_encode($group->getAttributes()), 'order' => $index ]; }); // This is a quick & dirty example, syncing the models is probably a better idea. $model->blocks()->delete(); $model->blocks()->createMany($blocks); }); } ``` -------------------------------- ### Limit Layout Instances Source: https://whitecube.github.io/nova-flexible-content Restrict the number of times a specific layout can be added by setting the $limit property. ```php /** * The maximum amount of this layout type that can be added */ protected $limit = 1; ``` -------------------------------- ### Customize Layout Selection Menu Source: https://whitecube.github.io/nova-flexible-content Change the component used for selecting layouts. Options include 'flexible-drop-menu' (default) and 'flexible-search-menu'. Custom components can also be used. ```php // Default, simple list of all layouts Flexible::make('Content')->menu('flexible-drop-menu'); // searchable select field Flexible::make('Content')->menu('flexible-search-menu'); // customized searchable select field Flexible::make('Content') ->menu( 'flexible-search-menu', [ 'selectLabel' => 'Press enter to select', // the property on the layout entry 'label' => 'title', // 'top', 'bottom', 'auto' 'openDirection' => 'bottom', ] ); ``` -------------------------------- ### Enable Layout Removal Confirmation Source: https://whitecube.github.io/nova-flexible-content Add a confirmation prompt before a layout is deleted. You can also customize the confirmation dialog's button labels. ```php Flexible::make('Content')->confirmRemove(); // You can override the text as well Flexible::make('Content')->confirmRemove($label = '', $yes = 'Delete', $no = 'Cancel'); ``` -------------------------------- ### Limit Number of Layouts Source: https://whitecube.github.io/nova-flexible-content Restrict the maximum number of layouts that can be added to the Flexible field. Defaults to 1 if no integer is provided. ```php Flexible::make('Content')->limit(2); ``` -------------------------------- ### Add Layouts to Flexible Field Source: https://whitecube.github.io/nova-flexible-content Define repeatable groups of fields within the Flexible field. Use this to structure content with different types of sections. ```php use Whitecube\NovaFlexibleContent\Flexible; // ... 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') ]) ``` -------------------------------- ### Customize Add Layout Button Label Source: https://whitecube.github.io/nova-flexible-content Change the default text of the button used to add new layouts. This can be used for more descriptive or branded button text. ```php Flexible::make('Content') ->button('Add something amazing!'); ``` -------------------------------- ### Specify Layout Mappings with HasFlexible Trait Source: https://whitecube.github.io/nova-flexible-content When using the HasFlexible trait, you can provide an array of layout mappings as the second argument to the flexible() method to map keys to custom layout classes. ```php public function getFlexibleContentAttribute() { return $this->flexible('flexible-content', [ 'wysiwyg' => \App\Nova\Flexible\Layouts\WysiwygLayout::class, 'video' => \App\Nova\Flexible\Layouts\VideoLayout::class, ]); } ``` -------------------------------- ### Cast Flexible Content with FlexibleCast Source: https://whitecube.github.io/nova-flexible-content Use the FlexibleCast class to automatically parse JSON string values from the flexible content field into usable objects. This is typically defined in your Eloquent model's $casts property. ```php namespace App; use Illuminate\Database\Eloquent\Model; use Whitecube\NovaFlexibleContent\Value\FlexibleCast; class MyModel extends Model { protected $casts = [ 'flexible-content' => FlexibleCast::class ]; } ``` -------------------------------- ### Override Layout Mappings in Custom Cast Source: https://whitecube.github.io/nova-flexible-content Override the getLayoutMappings method in your custom flexible cast to programmatically define layout mappings, allowing for conditional or complex mapping logic. ```php namespace App\Casts; class MyFlexibleCast extends FlexibleCast { protected function getLayoutMappings() { $mappings = []; // Conditionally add mappings however you want return $mappings; } } ``` -------------------------------- ### Make Flexible Field Full Width Source: https://whitecube.github.io/nova-flexible-content Configure the Flexible field to occupy the full width of the form. This also moves the field's label above the input area. ```php Flexible::make('Content') ->fullWidth() ``` -------------------------------- ### Use HasFlexible Trait for Flexible Content Source: https://whitecube.github.io/nova-flexible-content Implement the HasFlexible trait in your Eloquent model to easily access flexible content attributes using the flexible() method. This method transforms the attribute's value into a Collection of layouts. ```php namespace App; use Illuminate\Database\Eloquent\Model; use Whitecube\NovaFlexibleContent\Concerns\HasFlexible; class MyModel extends Model { use HasFlexible; public function getFlexibleContentAttribute() { return $this->flexible('flexible-content'); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.