Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Page Builder Plugin Laravel Package

redberry/page-builder-plugin

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require redberry/page-builder-plugin
    

    Publish the plugin assets and config:

    php artisan vendor:publish --provider="Redberry\PageBuilderPlugin\PageBuilderPluginServiceProvider"
    
  2. Register the Plugin: Add to app/Providers/Filament/AdminPanelProvider.php:

    public function panel(Panel $panel): Panel
    {
        return $panel
            ->plugins([
                \Redberry\PageBuilderPlugin\PageBuilderPlugin::make(),
            ]);
    }
    
  3. First Use Case: Create a basic block (e.g., TextBlock) by generating a stub:

    php artisan make:page-builder-block TextBlock
    

    This creates a TextBlock class in app/Filament/Resources/Blocks/TextBlock.php.

  4. Register the Block: In your PageBuilderPlugin registration, add:

    ->blocks([
        \App\Filament\Resources\Blocks\TextBlock::class,
    ])
    
  5. Use in a Resource: Attach the page builder to a Filament resource (e.g., PageResource):

    use Redberry\PageBuilderPlugin\Fields\PageBuilder;
    
    public static function form(Form $form): Form
    {
        return $form->schema([
            PageBuilder::make('content')->blocks([
                \App\Filament\Resources\Blocks\TextBlock::class,
            ]),
        ]);
    }
    

Implementation Patterns

Core Workflows

1. Block Development

  • Structure: Each block is a class extending Redberry\PageBuilderPlugin\Contracts\Block. Key methods:

    • fields(): Define form fields for block configuration.
    • render(): Return a Blade view or string for frontend rendering.
    • preview() (optional): Customize preview in the builder.

    Example:

    class TextBlock extends Block
    {
        public static function fields(): array
        {
            return [
                TextInput::make('title')->required(),
                RichEditor::make('content'),
            ];
        }
    
        public function render(): string
        {
            return view('blocks.text', [
                'title' => $this->title,
                'content' => $this->content,
            ])->render();
        }
    }
    
  • Reusability: Extend existing blocks or compose blocks (e.g., a ColumnBlock containing other blocks).

2. Page Management

  • CRUD Integration: Use PageBuilder field in a Filament resource to manage pages. Example:

    PageBuilder::make('layout')
        ->blocks([TextBlock::class, ImageBlock::class])
        ->enableReorders()
        ->previewInIframe()
    
  • Data Handling:

    • Storing: Data is stored as JSON in the database (default column: content).
    • Retrieving: Use $record->content to get raw data or $record->content->blocks for parsed blocks.

3. Frontend Rendering

  • Blade Integration: Render pages on the frontend using:
    @foreach($page->content->blocks as $block)
        {!! $block->render() !!}
    @endforeach
    
  • Dynamic Styling: Pass block data to Blade views for dynamic CSS/JS (e.g., style="background: {{ $block->bgColor }}").

4. Preview Customization

  • Iframe Preview: Enable real-time preview with:

    PageBuilder::make('content')->previewInIframe()
    

    Configure the iframe URL in config/page-builder.php:

    'preview_url' => env('APP_URL'),
    
  • Custom Preview Views: Override preview() in blocks:

    public function preview(): string
    {
        return view('blocks.previews.text', ['block' => $this])->render();
    }
    

Integration Tips

1. Filament Resources

  • Page Resource Example:
    class PageResource extends Resource
    {
        public static function form(Form $form): Form
        {
            return $form->schema([
                PageBuilder::make('builder_content')
                    ->blocks([TextBlock::class, HeroBlock::class])
                    ->columnSpanFull(),
            ]);
        }
    }
    

2. API Responses

  • Serialize Blocks: Use JsonSerializable or custom accessors to format API responses:
    public function jsonSerialize(): array
    {
        return [
            'title' => $this->title,
            'content' => $this->content,
            // Add other fields
        ];
    }
    

3. Localization

  • Block Labels: Localize block names in config/page-builder.php:
    'blocks' => [
        'text' => [
            'label' => 'Text Block',
            'plural' => 'Text Blocks',
        ],
    ],
    

4. Asset Management

  • Block Assets: Use mix or Vite to compile block-specific CSS/JS. Reference assets in render():
    @vite(['resources/css/blocks/text.css'])
    

Gotchas and Tips

Pitfalls

1. Block Registration

  • Issue: Blocks not appearing in the builder.
    • Fix: Ensure blocks are registered in the PageBuilder field and the plugin config:
      // In PageBuilderPlugin registration
      ->blocks([TextBlock::class]);
      
      // In resource form
      PageBuilder::make('content')->blocks([TextBlock::class]);
      

2. Data Serialization

  • Issue: Undefined index errors when accessing block data.
    • Fix: Always check if the block exists before rendering:
      @foreach($page->content->blocks ?? [] as $block)
          {!! optional($block)->render() !!}
      @endforeach
      

3. Caching

  • Issue: Preview iframe not updating.
    • Fix: Clear Filament cache:
      php artisan filament:cache:clear
      
    • Disable caching in config/page-builder.php during development:
      'cache_previews' => false,
      

4. Nested Blocks

  • Issue: Reordering nested blocks breaks.
    • Fix: Use enableReorders() only on top-level blocks. For nested blocks, implement custom logic in fields():
      PageBuilder::make('nested_content')->enableReorders(false);
      

Debugging Tips

1. Log Block Data

  • Dump block data in render() for debugging:
    \Log::debug('Block data:', $this->toArray());
    

2. Validate JSON

  • Ensure stored JSON is valid:
    $blocks = json_decode($record->content, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        \Log::error('Invalid JSON in page builder:', $record->content);
    }
    

3. Check Plugin Events

  • Listen for block events (e.g., BlockSaved):
    use Redberry\PageBuilderPlugin\Events\BlockSaved;
    
    BlockSaved::listen(function (BlockSaved $event) {
        \Log::info('Block saved:', $event->block->toArray());
    });
    

Extension Points

1. Custom Block Categories

  • Group blocks by category:
    PageBuilder::make('content')
        ->blocks([
            TextBlock::class->category('Content'),
            ImageBlock::class->category('Media'),
        ]);
    

2. Dynamic Block Loading

  • Load blocks dynamically (e.g., from a database):
    PageBuilder::make('content')
        ->blocks(fn () => BlockRepository::getAvailableBlocks())
    

3. Block Thumbnails

  • Add thumbnails to blocks:
    class TextBlock extends Block
    {
        public static function thumbnail(): string
        {
            return view('blocks.thumbnails.text')->render();
        }
    }
    

4. Custom Storage

  • Override storage engine (e.g., use Redis):
    use Redberry\PageBuilderPlugin\Contracts\StorageEngine;
    
    class RedisStorage implements StorageEngine
    {
        public function store($data): string
        {
            // Custom logic
        }
    }
    
    // Register in config
    'storage_engine' => \App\Services\RedisStorage::class,
    

5. Block Permissions

  • Restrict block access by user roles:
    PageBuilder::make('content')
        ->blocks([
            TextBlock::class->visible(fn (User $user) => $user->can('edit-text')),
        ]);
    

Configuration Quirks

1. Preview URL

  • Default: Uses APP_URL. Override in `config/page-builder
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
croct/coding-standard
croct/plug-php
nqxcode/phpmorphy
boundwize/pyrameter
testo/facade
headercat/phpstan-extension-ide-helper
yosymfony/parser-utils
innmind/black-box
babenkoivan/elastic-migrations
babenkoivan/elastic-adapter
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle