Laravel integration for the Craftile visual editor - Build dynamic, block-based layouts with seamless editor integration.
This package provides Laravel integration for the Craftile Visual Editor, enabling you to create block-based content management systems with Blade templates.
Install via Composer:
composer require craftile/laravelPublish the configuration file:
php artisan vendor:publish --provider="Craftile\Laravel\CraftileServiceProvider"This will create a config/craftile.php file where you can customize:
- Blade directive names
- Component namespace
- Block compiler settings
- Cache configuration
Create a block by implementing the BlockInterface:
<?php
namespace App\Blocks;
use Craftile\Core\Contracts\BlockInterface;
use Craftile\Core\Data\Property\Text;
use Craftile\Core\Data\Property\Boolean;
class Hero implements BlockInterface
{
public static function getType(): string
{
return 'hero';
}
public static function getLabel(): string
{
return 'Hero Section';
}
public static function properties(): array
{
return [
Text::make('title', 'Title')->default('Welcome'),
Text::make('subtitle', 'Subtitle'),
Boolean::make('showButton', 'Show Button')->default(true),
];
}
protected static array $accepts = ['button', 'text']; // Optional: specify accepted child types
public function render(): mixed
{
return view('blocks.hero');
}
}Create the corresponding Blade template:
<!-- resources/views/blocks/hero.blade.php -->
<section class="hero bg-gray-900 text-white py-16">
<div class="container mx-auto px-4">
<h1 class="text-4xl font-bold mb-4">{{ $block->properties->title }}</h1>
@if($block->properties->subtitle)
<p class="text-xl mb-8">{{ $block->properties->subtitle }}</p>
@endif
@if($block->properties->showButton)
@children
@endif
</div>
</section>Register your block in a service provider:
// In AppServiceProvider or dedicated BlockServiceProvider
use Craftile\Laravel\Facades\Craftile;
public function boot()
{
Craftile::registerBlock(Hero::class);
}Use blocks directly in your Blade templates:
{{-- Basic block usage --}}
@craftileBlock('hero', 'hero-1', ['title' => 'Hello World'])
Or use the component syntax:
<craftile:block type="hero" id="hero-1" :properties="['title' => 'Hello World']" />Create template files that can be rendered directly:
// resources/views/pages/homepage.json
{
"blocks": {
"hero-1": {
"id": "hero-1",
"type": "hero",
"properties": {
"title": "Welcome to our site",
"subtitle": "Build amazing things with Craftile"
},
"children": ["btn-1"]
},
"btn-1": {
"id": "btn-1",
"type": "button",
"properties": {
"text": "Get Started",
"variant": "primary"
}
}
},
"regions": [
{
"name": "main",
"blocks": ["hero-1"]
}
]
}Then render in your route or controller:
Route::get('/', function () {
return view('pages.homepage'); // Will automatically compile the JSON template
});Craftile provides several property types for your blocks:
use Craftile\Core\Data\Property\{Text, Textarea, Boolean, Select};
public static function properties(): array
{
return [
Text::make('title', 'Title')
->default('Default title')
->required(),
Textarea::make('content', 'Content')
->default('Enter your content here...'),
Boolean::make('isVisible', 'Visible')
->default(true),
Select::make('size', 'Size')
->options([
['value' => 'sm', 'label' => 'Small'],
['value' => 'md', 'label' => 'Medium'],
['value' => 'lg', 'label' => 'Large'],
])
->default('md'),
];
}Blocks can accept and render child blocks:
// In your block class
protected static array $accepts = ['*']; // Accept any child type
// or
protected static array $accepts = ['button', 'text']; // Accept specific types
// In your block template
@children {{-- Renders all child blocks --}}Customize directive names in config/craftile.php:
'directives' => [
'craftileBlock' => 'block', // @block instead of @craftileBlock
'craftileContent' => 'content', // @content instead of @craftileContent
],Change the component tag namespace:
'components' => [
'namespace' => 'builder', // <builder:block> instead of <craftile:block>
],