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 Composer Laravel Package

flobbos/page-composer

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Installation Run:

    composer require flobbos/page-composer
    php artisan page-composer:install
    

    Accept the default name (or specify one) during installation.

  2. Access the CMS Register a Livewire component in your routes (e.g., routes/web.php):

    Route::get('/admin/pages', PageComposer::make('pages')->route());
    

    Visit /admin/pages to see the editor UI.

  3. First Page Creation

    • Click "Create New Page" in the UI.
    • Add a row (default: 12-column grid).
    • Drag a text element or image element into the row.
    • Publish the page.
  4. Display Content in Blade Use the page helper in your Blade template:

    @page('homepage', 'content')
    

    Where homepage is the page name and content is the slot (e.g., default).


Where to Look First

  • Livewire Documentation (Core interaction logic).
  • Package Config (Customize allowed elements, grid settings).
  • /resources/views/vendor/page-composer/ (Override default UI templates).
  • php artisan page-composer:sync-row-space (Fix layout issues post-install).

First Use Case: Static Landing Page

  1. Create a page named home.
  2. Add a hero row (12 columns) with a text element and image element.
  3. Save and publish.
  4. Display it in Blade:
    @page('home', 'default')
    

Implementation Patterns

Core Workflows

1. Element Development

  • Extend Existing Elements: Create a custom element by publishing the stub:

    php artisan vendor:publish --tag=page-composer-elements
    

    Edit app/PageComposer/Elements/CustomElement.php and register it in config/page-composer.php:

    'elements' => [
        \App\PageComposer\Elements\CustomElement::class,
    ],
    
  • Element Structure:

    namespace App\PageComposer\Elements;
    use Flobbos\PageComposer\Contracts\Element;
    
    class CustomElement implements Element {
        public function render() { ... }
        public function config() { ... } // Livewire properties
    }
    

2. Page Management

  • Dynamic Page Loading: Fetch pages via the Page model:

    use Flobbos\PageComposer\Models\Page;
    $homepage = Page::where('name', 'home')->first();
    

    Render content in Blade:

    @if($homepage)
        @foreach($homepage->rows as $row)
            @foreach($row->elements as $element)
                {!! $element->render() !!}
            @endforeach
        @endforeach
    @endif
    
  • Conditional Rendering: Use slots for modular content:

    @page('home', 'header')
    @page('home', 'footer')
    

3. Layout Syncing

  • Grid System: Configure column counts in config/page-composer.php:
    'grid' => [
        'columns' => 12, // Default 12-column grid
        'gutter' => '1rem',
    ],
    
    Sync row space after changes:
    php artisan page-composer:sync-row-space
    

4. Livewire Integration

  • Custom Livewire Components: Extend the editor with custom Livewire logic:
    use Flobbos\PageComposer\Http\Livewire\PageEditor;
    
    class CustomPageEditor extends PageEditor {
        protected $rules = [
            'custom_field' => 'required',
        ];
    }
    
    Register in app/Providers/AppServiceProvider.php:
    PageComposer::extend('pages', function () {
        return CustomPageEditor::class;
    });
    

Integration Tips

Laravel Ecosystem

  • Cache Pages: Cache rendered pages for performance:

    $cachedContent = Cache::remember("page_{$page->id}", now()->addHours(1), function () use ($page) {
        return $page->render();
    });
    
  • Media Library: Integrate with Spatie Media Library for image/video handling:

    use Spatie\MediaLibrary\HasMedia;
    class ImageElement implements Element, HasMedia {
        public function registerMediaCollections(): void {
            $this->addMediaCollection('images');
        }
    }
    

Frontend

  • Tailwind/Alpine.js: Use Alpine.js for dynamic interactions within elements:

    <div x-data="{ open: false }">
        <button @click="open = true">Toggle</button>
        <div x-show="open">Content</div>
    </div>
    
  • Inertia.js: For SPA-like experiences, pair with Inertia:

    public function render() {
        return Inertia::render('PageEditor', [
            'pages' => Page::all(),
        ]);
    }
    

Gotchas and Tips

Pitfalls

  1. Stale Row Space

    • Issue: After changing column layouts, existing rows may show misaligned elements.
    • Fix: Run php artisan page-composer:sync-row-space and republish affected pages.
  2. Element Serialization

    • Issue: Custom element data may not serialize correctly, causing UI glitches.
    • Fix: Implement Arrayable or Jsonable in your element class:
      use Illuminate\Contracts\Support\Arrayable;
      public function toArray() { return [...] }
      
  3. Livewire Hooks

    • Issue: Custom Livewire logic in elements may conflict with PageComposer’s lifecycle.
    • Fix: Use updated() or mounted() sparingly; prefer config() for properties.
  4. Permission Handling

    • Issue: No built-in auth; users can edit all pages by default.
    • Fix: Gate access via middleware or policies:
      Page::where('name', $pageName)->gate(['update']);
      
  5. Database Bloat

    • Issue: Unpublished drafts or deleted pages may clutter the DB.
    • Fix: Add soft deletes and a cleanup command:
      php artisan page-composer:prune --days=30
      

Debugging

  1. Element Rendering

    • Check storage/logs/livewire.log for Livewire errors.
    • Temporarily add {{ dd($element) }} in Blade to inspect data.
  2. Layout Issues

    • Inspect the available_space column in page_rows table:
      SELECT * FROM page_rows WHERE available_space IS NULL;
      
    • Re-sync with the artisan command.
  3. Livewire Wire:ignore

    • If elements fail to update, ensure they’re not wrapped in <div wire:ignore> unless intentional.

Configuration Quirks

  1. Default Element Order

    • Elements appear in the editor in the order defined in config/page-composer.php under 'elements'.
    • Reorder the array to prioritize frequently used elements.
  2. Grid Overrides

    • To use a 16-column grid globally, override the config:
      'grid' => [
          'columns' => 16,
          'gutter' => '0.75rem',
      ],
      
    • Note: Existing pages may need manual adjustment.
  3. Element Icons

    • Customize icons in the editor by extending the Element class:
      public function icon() {
          return 'heroicon-o-star';
      }
      

Extension Points

  1. Custom Storage

    • Store pages in a headless CMS (e.g., Strapi) by implementing Flobbos\PageComposer\Contracts\PageRepository.
  2. Element Presets

    • Pre-populate rows/elements via migrations or seeders:
      Page::create([
          'name' => 'home',
          'content' => json_encode([
              'rows' => [
                  [
                      'elements' => [
                          ['type' => 'text', 'content' => 'Hello World'],
                      ],
                  ],
              ],
          ]),
      ]);
      
  3. API Endpoints

    • Expose pages via API:
      Route::get('/api/pages/{name}', function ($name) {
          return Page::where('name', $name)->with('rows.elements')->firstOrFail();
      });
      
  4. Webhooks

    • Trigger actions on page updates via events:
      use Flobbos\PageComposer\Events\PageUpdated;
      PageUpdated::dispatch($page);
      
    • Listen in EventServiceProvider
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle