Skip to content

Installation ​

Requirements ​

  • PHP 8.2 or newer
  • Laravel 11 or 12
  • An admin panel: Filament 5 or Laravel Nova 5 (Nova requires a license)
  • A database: SQLite, MySQL or MariaDB — or an existing WordPress database
  • Node.js 20.19+ and npm, if you use a Vue theme (Blade themes need no build)

Pre-release

kitloom packages are not on Packagist yet. Until the first tagged release, install them from a path or VCS repository with the @dev constraint.

Starting from a skeleton ​

The fastest way to get a working site is a skeleton — a plain Laravel application with the core packages, every module, both bundled themes and the WordPress schema migrations already wired.

bash
composer create-project kitloom/filament-skeleton my-site
bash
composer create-project kitloom/cms-skeleton my-site

Then create the database, an administrator and build the default theme:

bash
cd my-site
php artisan migrate --seed
npm install
npm run build
php artisan serve

Open http://localhost:8000 for the site and /admin (Filament) or /nova (Nova) for the admin panel. The demo seeder creates [email protected] with the password from SEED_ADMIN_PASSWORD in your .env.

Adding kitloom to an existing application ​

1. Require the core ​

The core packages are always needed. The admin packages depend on your panel:

bash
composer require kitloom/core kitloom/wp-schema kitloom/routing \
    kitloom/settings kitloom/content kitloom/themes kitloom/modules
bash
composer require filament/filament:"^5.0" \
    kitloom/wp-schema-filament kitloom/settings-filament \
    kitloom/themes-filament kitloom/modules-filament
bash
composer require laravel/nova:"^5.0" \
    kitloom/wp-schema-nova kitloom/settings-nova \
    kitloom/themes-nova kitloom/modules-nova

Every package registers its own service provider through Laravel package discovery. There is nothing to add to bootstrap/providers.php.

2. The database schema ​

kitloom works on the WordPress tables. You have two options:

  • A new database. Copy the schema migrations from a skeleton (database/migrations/*_create_posts_table.php, *_create_terms_table.php, *_create_term_taxonomy_table.php, *_create_term_relationships_table.php, *_create_comments_table.php, *_create_postmeta_table.php, *_create_termmeta_table.php, *_create_usermeta_table.php, *_create_options_table.php) and run php artisan migrate.

  • An existing WordPress database. Point a MySQL connection at it and set the table prefix:

    ini
    DB_CONNECTION=mysql
    DB_DATABASE=wordpress
    DB_PREFIX=wp_

    Laravel adds the prefix to every table, so posts becomes wp_posts. Run php artisan migrate once — modules add the tables they need on top of WordPress's own. Back up the database first, as with any migration on a live site.

3. Route pages to kitloom ​

Every URL that is not one of your own routes is a page: a post, a term archive, an author. Hand them over to the page controller as the very last route:

php
// routes/web.php
use Kitloom\Core\Http\PageController;

Route::fallback(PageController::class);

The same URL answers a browser with the rendered page and a request with Accept: application/json with the page data.

4. Hook in module activation ​

To let administrators deactivate modules, add one line to bootstrap/app.php, after create():

php
use Kitloom\Modules\Modules;

$app = Application::configure(basePath: dirname(__DIR__))
    // ...
    ->create();

// Modules deactivated on the Modules screen are not loaded.
Modules::bootstrap($app);

return $app;

Without this line the Modules screen still lists modules, but shows a notice that deactivation has no effect. See Enabling & Disabling.

5. Your own models ​

kitloom ships models for every WordPress table. When a site needs its own behaviour — a trait from a module, an extra relation — it extends the package model and registers it:

php
// app/Models/Post.php
use Kitloom\Seo\Concerns\ReadsHeadMeta;
use Kitloom\Seo\Contracts\HasHeadMeta;
use Kitloom\WpSchema\Models\Post as WordPressPost;

class Post extends WordPressPost implements HasHeadMeta
{
    use ReadsHeadMeta;
}
php
// config/kitloom-wp-schema.php
return [
    'models' => [
        'post' => App\Models\Post::class,
        'user' => App\Models\User::class,
    ],
];

Models you do not list stay the package's own.

6. The admin panel ​

php
// app/Models/User.php
use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;

class User extends Authenticatable implements FilamentUser
{
    public function canAccessPanel(Panel $panel): bool
    {
        return $this->can('read');
    }
}
php
// app/Providers/NovaServiceProvider.php
protected function gate(): void
{
    Gate::define('viewNova', fn (User $user): bool => $user->can('read'));
}

kitloom sections attach themselves to the default Filament panel or to Nova. See Filament and Nova for panel-specific details.

7. A theme ​

Without a theme every page is returned as JSON — a headless site. To render HTML, install a theme — it brings the engine it renders with:

bash
composer require kitloom/portfolio-theme   # Vue + Inertia: pulls in kitloom/inertia
# or, without a JavaScript build:
composer require kitloom/blade-theme       # Blade: pulls in kitloom/blade

An engine is never installed on its own: with only Blade themes the site has no Inertia or Vue at all. (Nova uses Inertia for its own admin, so with Nova inertiajs/inertia-laravel is in vendor/ anyway.)

Then follow Installing Themes.

Installing from a repository ​

Until the packages are published, add the repository that holds them to your application's composer.json:

json
{
    "minimum-stability": "dev",
    "prefer-stable": true,
    "repositories": [
        {
            "type": "path",
            "url": "../kitloom-packages/*",
            "options": { "symlink": true }
        }
    ]
}
json
{
    "minimum-stability": "dev",
    "prefer-stable": true,
    "repositories": [
        { "type": "vcs", "url": "https://git.example.com/kitloom/redirects.git" }
    ]
}

and require packages with @dev:

bash
composer require kitloom/redirects:@dev kitloom/redirects-filament:@dev

Next steps ​