Weave 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

Redkite Cms Bundle Laravel Package

redkite-cms/redkite-cms-bundle

RedKite CMS Bundle delivers core CMS features for RedKite, an open-source PHP/Symfony content management system. It provides page and content management, a modular architecture, and tools for building editable websites.

View on GitHub
Deep Wiki
Context7

Getting Started

Accept up front that this is not something you composer require into a Laravel app. It's a Symfony 2-era bundle depending on symfony/http-kernel 2.x, Propel, Twig 1, and Assetic. Laravel 10/11 pull Symfony 6/7 components, so the dependency graph won't resolve — and --ignore-platform-reqs just moves the failure to runtime. The realistic "first use case" is one of two things:

  1. You inherited a RedKite site and need to understand it, stabilize it, or extract content from it.
  2. You want the content model — pages, blocks, slots, in-place editing — to reimplement on Eloquent/Blade/Livewire.

Where to look first, in this order:

  • RedKiteCmsBundle.php — the bundle boot/config lifecycle; tells you which services and routes get registered.
  • Resources/config/*.yml — the service container definitions. This is the fastest map of the domain: block managers, page managers, content repositories, theme loaders.
  • The model/entity layer (Propel-generated) — Page, Block, Language, Seo and their join tables. This is what you actually want to copy.
  • Resources/views/ — the frontend editing UI (Twig 1). Read it for the UX contract: how a block is selected, edited, saved, and re-rendered in place.
  • DependencyInjection/Configuration.php — the config tree; shows what was tunable (languages, themes, block types).

Concrete first step for a Laravel dev: open the Propel schema (or the generated om/ and map/ classes) and transcribe it into Eloquent migrations. That one exercise gives you ~80% of the value of this repo.

Implementation Patterns

1. Reference-to-migration pattern (the one you'll actually use).

Sketch the tables from the Propel model, then write Laravel migrations against them:

Schema::create('pages', function (Blueprint $t) {
    $t->id();
    $t->foreignId('site_id')->index();
    $t->string('slug')->index();
    $t->string('locale', 5)->index();
    $t->boolean('is_published')->default(false);
    $t->timestamps();
    $t->unique(['site_id', 'locale', 'slug']);
});

Schema::create('blocks', function (Blueprint $t) {
    $t->id();
    $t->string('type');            // 'text', 'image', 'menu', custom
    $t->json('payload');           // replaces RedKite's per-type block data
    $t->timestamps();
});

Schema::create('page_block', function (Blueprint $t) {
    $t->foreignId('page_id')->constrained()->cascadeOnDelete();
    $t->foreignId('block_id')->constrained()->cascadeOnDelete();
    $t->string('slot');            // 'main', 'sidebar', 'footer'
    $t->unsignedInteger('position');
    $t->timestamps();
});

2. Port the block-registry idea to the Laravel container.

RedKite registers block types as tagged Symfony services. The Laravel equivalent is a config-driven map plus a small resolver:

// config/blocks.php
return [
    'text'  => App\Blocks\TextBlock::class,
    'image' => App\Blocks\ImageBlock::class,
];

// app/Blocks/BlockManager.php
public function resolve(string $type): BlockRenderer
{
    $class = config("blocks.{$type}");
    abort_unless($class, 422, "Unknown block type [{$type}]");
    return app($class);
}

This keeps templates and the editor dropdown in sync via one source of truth — the same guarantee RedKite's tagged services gave it.

3. In-place editing UX pattern.

RedKite's selling point is editing on the rendered page, not in an admin panel. Reproduce it in Laravel with a route-level switch rather than a separate app:

Route::middleware(['web', 'can:edit-content'])
    ->get('/_edit/{page}', [EditorController::class, 'show']);

The public page and the editor render the same Blade view; a @can('edit-content') check injects wrapper attributes and Livewire/Alpine edit affordances. That avoids the classic mistake of maintaining two templates that drift.

4. Strangler pattern for a live legacy instance.

If a working RedKite deployment holds content and you're moving to Laravel:

  • Run the legacy app in its own container on its original PHP version.
  • Put a reverse proxy in front; route content URLs to Laravel, the legacy editor to a network-restricted path.
  • Write a one-way Propel → JSON exporter early (see Gotchas).
  • php artisan redkite:import consumes that JSON into Eloquent, idempotently keyed on (site, locale, slug).
  • Dual-run, diff outputs, then flip reads and kill the legacy writes.

5. Feature-flag the cutover, not the code. Put migrated pages behind a content_source flag per site, so you can flip back per-tenant during the transition without a deploy.

Gotchas and Tips

  • The Composer failure is informative, not annoying. When you run composer require redkite-cms/redkite-cms-bundle in a Laravel app and get a wall of constraint errors, that is the assessment result. Don't spend a day fighting it.
  • Two persistence layers, zero shared transactions. Propel owns the content tables; Eloquent will own everything new. Any write that spans both is a distributed transaction you do not want. Do the migration in a batch job, not in a request.
  • PHP 5.x/7.x syntax throughout. No typed properties, no arrow functions, no declare(strict_types=1). You generally can't lift code — you read it and rewrite. Budget accordingly; "just copy the block renderer" rarely works.
  • Twig 1 templates are not portable. Blade has no inheritance/tag parity with Twig macros. Rewrite views from the UX, not from the template source.
  • Write the content exporter before you need it. Propel's schema has no supported export path. A SELECT *-to-JSON dump per table, plus the page/block join table, is a few hours of work now and a panic later.
  • Vendor the source and commit the resolved lock. No dependents means no one will notice if a transitive package is yanked from Packagist. Pin artifacts in your own storage so builds stay reproducible.
  • Treat the legacy editor as a hostile surface. No upstream security patches, and it's a web-facing authenticated admin. Put it behind a gateway with IP allowlisting or mTLS, and write down a decommission date with an owner.
  • Extension points are a trap in read-only repos. RedKite's theme/bundle extension system looks inviting, but you'd be the only consumer. If you need custom block types, build them on your own registry in Laravel, not via the Symfony DI tags.
  • Debugging a legacy instance means bin/console in the old container, not php artisan. Keep the two toolchains mentally separated; mixing them up wastes more time than the port itself.
  • Distrust the score. A "high opportunity" signal on a deprecated, zero-dependent repo is noise, not an opening. The extractable value here is the block/slot/locale data model and the in-context editing UX — both of which you can reimplement natively with less effort than any bridge will cost you over a year.
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log