skyraptor/filament-blocks-builder
Installation
composer require skyraptor/filament-blocks-builder
Publish the config (if needed):
php artisan vendor:publish --provider="Skyraptor\FilamentBlocksBuilder\FilamentBlocksBuilderServiceProvider"
Register the Plugin
Add to your app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
\Skyraptor\FilamentBlocksBuilder\FilamentBlocksBuilderPlugin::make(),
]);
}
First Use Case: Basic Block Builder
Use BlocksInput in a Filament form:
use Skyraptor\FilamentBlocksBuilder\Forms\Components\BlocksInput;
public static function form(Form $form): Form
{
return $form
->schema([
BlocksInput::make('content_blocks')
->blocks([
'header' => HeaderBlock::class,
'text' => TextBlock::class,
]),
]);
}
Define a Block Class
Create a block class (e.g., app/Filament/Resources/Blocks/HeaderBlock.php):
namespace App\Filament\Resources\Blocks;
use Skyraptor\FilamentBlocksBuilder\Contracts\Block;
class HeaderBlock implements Block
{
public static function getLabel(): string
{
return 'Header';
}
public function form(): array
{
return [
TextInput::make('title')->required(),
Select::make('style')->options(['h1', 'h2', 'h3']),
];
}
}
Register blocks dynamically in a service provider or panel configuration:
FilamentBlocksBuilderPlugin::make()
->blocks([
'custom_block' => \App\Filament\Blocks\CustomBlock::class,
]);
Enable nested blocks by configuring BlocksInput:
BlocksInput::make('nested_blocks')
->blocks([
'container' => ContainerBlock::class,
'item' => ItemBlock::class,
])
->allowNestedBlocks(['container']);
Store blocks in a JSON column (e.g., blocks_data in your model):
// Save
$record->blocks_data = $form->getState()['content_blocks'];
$record->save();
// Retrieve
$blocks = json_decode($record->blocks_data, true);
Predefine templates for common layouts:
BlocksInput::make('template_blocks')
->blocks([
'hero' => HeroBlock::class,
'cta' => CtaBlock::class,
])
->defaultBlocks([
'hero' => ['title' => 'Welcome', 'style' => 'h1'],
'cta' => ['text' => 'Get Started', 'link' => '#'],
]);
Use BlocksInput in resource forms/pages:
public static function form(Form $form): Form
{
return $form
->schema([
BlocksInput::make('page_layout')
->blocks([
'section' => SectionBlock::class,
'media' => MediaBlock::class,
]),
]);
}
Extend functionality by creating custom Livewire components for blocks:
use Livewire\Component;
class CustomBlockComponent extends Component
{
public $blockData;
public function render()
{
return view('filament.blocks.custom', ['block' => $this->blockData]);
}
}
Serialize/deserialize blocks for API responses:
// Serialize
$blocks = $record->blocks_data;
$serialized = json_encode($blocks);
// Deserialize
$blocks = json_decode($serialized, true);
Override default styles via CSS:
/* app.css */
.filament-blocks-builder .block-header {
background: #f0f0f0;
}
Block Data Serialization
$blocks = json_decode($record->blocks_data, true);
if (json_last_error() !== JSON_ERROR_NONE) {
// Handle fallback or migration
}
Performance with Large Layouts
BlocksInput::make('blocks')
->maxBlocks(100) // Limit blocks
->lazyLoad();
Caching Block Definitions
$blocks = Cache::remember('filament-blocks-definitions', now()->addHours(1), function () {
return [
'header' => HeaderBlock::class,
// ...
];
});
CSRF Token in Block Forms
use Illuminate\Support\Facades\Blade;
Blade::directive('csrfField', function () {
return '<?php echo csrf_field(); ?>';
});
Log Block Data Dump block data for debugging:
\Log::debug('Block Data', [
'raw' => $form->getState()['blocks'],
'decoded' => json_decode($form->getState()['blocks'], true),
]);
Validate Block Structure Add validation to ensure blocks conform to expected schemas:
use Skyraptor\FilamentBlocksBuilder\Validation\BlockValidator;
$validator = new BlockValidator();
$errors = $validator->validate($blocks, ['header', 'text']);
Inspect Block Rendering Override the block view to debug rendering:
// In a service provider
view()->composer('filament-blocks-builder::blocks.block', function ($view) {
\Log::debug('Block Data', $view->block);
});
Custom Block Storage
Extend storage by implementing Skyraptor\FilamentBlocksBuilder\Contracts\BlockStorage:
class DatabaseBlockStorage implements BlockStorage
{
public function save($blocks, $model)
{
$model->blocks_data = json_encode($blocks);
$model->save();
}
}
Block Events
Listen to block-related events (e.g., blocks.saved):
event(new BlocksSaved($blocks, $model));
Block Middleware Add middleware to block forms:
BlocksInput::make('blocks')
->middleware([
\App\Filament\Middleware\ValidateBlockPermissions::class,
]);
Block Assets Load custom assets (JS/CSS) per block:
class CustomBlock implements Block
{
public function assets(): array
{
return [
'css' => ['css/custom-block.css'],
'js' => ['js/custom-block.js'],
];
}
}
Block Localization Support multi-language blocks:
class TranslatableBlock implements Block
{
public function form(): array
{
return [
Repeater::make('translations')
->relationship()
->items([
TextInput::make('title')->required(),
Select::make('locale')->options(['en', 'es']),
]),
];
}
}
How can I help you explore Laravel packages today?