novius / laravel-nova-visual-composer
A Laravel Nova field to compose blocks.
Installs: 23 219
Dependents: 0
Suggesters: 0
Security: 0
Stars: 15
Watchers: 5
Forks: 9
Open Issues: 2
Language:Vue
Requires
- php: >=7.4
- illuminate/support: ^8.0|^9.0
- intervention/image: ^2.4
Requires (Dev)
- friendsofphp/php-cs-fixer: ~2.15.0
README
Requirements
- PHP >= 7.4
- Laravel Framework >= 8.
- Nova >= 2.0
- Imagick PHP extension or GD Library (for Intervention Image)
NOTE: These instructions are for Laravel >= 8. If you are using prior version, please see the previous version's docs.
Installation
composer require novius/laravel-nova-visual-composer
Next, configure Intervention Image package :
Intervention Image configuration instructions
Configuration
Some options that you can override are available.
php artisan vendor:publish --provider="Novius\NovaVisualComposer\NovaVisualComposerServiceProvider" --tag="config"
JS Configuration
Some options (like wysiwyg config) are configurable from JS config file.
You can override it with :
php artisan vendor:publish --provider="Novius\NovaVisualComposer\NovaVisualComposerServiceProvider" --tag="js"
Purge TMP uploaded files
In your app/Console/Kernel.php file, you should register a daily job to purge any stale files :
protected function schedule(Schedule $schedule) { $schedule->command('nova-visual-composer:purge-tmp-files') ->daily(); }
By default tmp file is stale considered after 24h. You can override this value in configuration file with seconds_before_purge_tmp_files
key.
Usage
Step 1
Create a long text column on your model's table.
$table->longText('content')->nullable();
Configure your model by adding object
to the desired column.
use Illuminate\Database\Eloquent\Model; class Foo extends Model { protected $casts = [ 'content' => 'object', ]; }
Step 2
Add the field to your Nova resource.
use App\Nova\Resource; use Novius\NovaVisualComposer\NovaVisualComposer; class FooResource extends Resource { public function fields(Request $request) { return [ // .. NovaVisualComposer::make('Content') ->stacked(), // .. ]; } }
Step 3
Display in your blade template.
@foreach($item->content as $row) {!! $row->template::renderFront($row->content) !!} @endforeach
Create new row templates
Step 1
You have to publish lang and view files.
php artisan vendor:publish --provider="Novius\NovaVisualComposer\NovaVisualComposerServiceProvider" --tag="config" php artisan vendor:publish --provider="Novius\NovaVisualComposer\NovaVisualComposerServiceProvider" --tag="views"
Step 2
Create your own Row Template and link it into configuration file.
Row Template Class
namespace App\Nova\Templates\Rows; use Novius\NovaVisualComposer\Templates\RowTemplateAbstract; use Novius\NovaVisualComposer\Traits\HasImageField; use Novius\NovaVisualComposer\Traits\HasPrunableFiles; class ImageText extends RowTemplateAbstract { use HasImageField; use HasPrunableFiles; public static $name = 'image-text'; protected static function imageFieldsIndexes(): array { return [0]; // Because image field is the first field that contains "js-visual-field" class of CRUD view } }
Add it to configuration file
return [ ... 'templates' => [ \Novius\NovaVisualComposer\Templates\Article::class, \Novius\NovaVisualComposer\Templates\ImageMultiple::class, \Novius\NovaVisualComposer\Templates\ImageSimple::class, \Novius\NovaVisualComposer\Templates\Separator::class, \Novius\NovaVisualComposer\Templates\Title::class, // Custom Template \App\Nova\Templates\Rows\ImageText::class, ], ];
Step 3
Create template views (CRUD + front views).
resources/views/vendor/nova-visual-composer/templates/ImageText/crud.blade.php
TIPS :
- Each HTML field that you want to save must contains
js-visual-field
class. - If you want a wysiwyg add
js-wysiwyg
class to textarea field. - If you want an image upload field add
js-image-uploader
class to file field. - If you want a multiple images upload field add
js-image-uploader
class +multiple
attribute to file field.
<div class="shadow-md mb-4 w-full"> <div class="px-6 py-4"> <div class="font-bold text-xl mb-4"> {{ $templateDetails['name_trans'] }} </div> <div class="flex"> <div class="w-1/3 pr-3"> <div class="form-group"> <input type="file" class="filepond js-visual-field js-image-uploader"> </div> </div> <div class="w-2/3"> <div class="form-group mb-2"> <label class="block text-grey-darker text-sm font-bold mb-2"> {{ trans('nova-visual-composer::templates.'.$templateName.'.crud_pre_title') }} </label> <input class="js-visual-field w-full form-control form-input form-input-bordered" type="text"/> </div> <div class="form-group mb-2"> <label class="block text-grey-darker text-sm font-bold mb-2"> {{ trans('nova-visual-composer::templates.'.$templateName.'.crud_title') }} </label> <input class="js-visual-field w-full form-control form-input form-input-bordered" type="text"/> </div> <div class="form-group mb-2"> <label class="block text-grey-darker text-sm font-bold mb-2"> {{ trans('nova-visual-composer::templates.'.$templateName.'.crud_text') }} </label> <textarea name="content" class="js-visual-field js-wysiwyg w-full form-control form-input-bordered py-2 h-20"></textarea> </div> </div> </div> </div> </div>
resources/views/vendor/nova-visual-composer/templates/ImageText/front.blade.php
@php if (empty($content) || !is_array($content)) { return; } list( $images, $preTitle, $title, $htmlContent, ) = $content; $image = is_array($images) ? array_shift($images) : null; @endphp <div class="block-image-text"> @if (!empty($image)) <img src="{{ asset('storage/'.$image) }}"/> @endif @if (!empty($preTitle)) <h5 class="pre-title"> {{ $preTitle }} </h5> @endif @if (!empty($title)) <h3 class="title"> {{ $title }} </h3> @endif @if (!empty($htmlContent)) <div class="content"> {!! $htmlContent !!} </div> @endif </div>
Step 4
Add your translations to language files.
resources/lang/vendor/nova-visual-composer/fr/templates.php
return [ ... 'image-text' => [ 'name' => 'Image / texte', 'crud_pre_title' => 'Sur-titre', 'crud_title' => 'Titre', 'crud_text' => 'Texte', ], ];
Lint
Run php-cs with:
composer run-script lint
Contributing
Contributions are welcome! Leave an issue on Github, or create a Pull Request.
Licence
This package is under GNU Affero General Public License v3 or (at your option) any later version.