Skip to content

Seeding content programmatically

Status: Skeleton — sections below are outlines. Contributions welcome.

How to create Capell content — pages, URLs, translations, element types, element instances, layouts — from seeders or migrations, without going through the admin UI. Primary audience: deployers who want reproducible installs and app authors replacing the default demo data.

When to seed vs. migrate vs. use the admin UI

Section titled “When to seed vs. migrate vs. use the admin UI”
  • Seeders: reproducible local content, starter kits, test fixtures.
  • Migrations: schema-like changes that must run once per environment (e.g. creating a default site on upgrade).
  • Admin UI: day-to-day editorial changes by humans.

Recipe: add a translated page to every existing site

Section titled “Recipe: add a translated page to every existing site”
  • Walk Site::all().
  • For each site, Page::firstOrCreate(...) + attach Translation + PageUrl.

Recipe: register an element type + instance

Section titled “Recipe: register an element type + instance”
  • Type::firstOrCreate with type=element.
  • Element::firstOrCreate pointing at the type.
  • See the ContentSections package docs for the full element flow.
  • Layout::create(...) + LayoutContainer::create(...) per section.
  • Attach elements in each layout container’s elements array.
  • Navigation::firstOrCreate with the desired type (main, footer, sub-footer).
  • Add NavigationItem rows keyed to pages by pageable_type + pageable_id.
  • php artisan db:seed --class=YourSiteSeeder after php artisan migrate --force.
  • Laravel Forge / Envoyer / Spin hook examples.

The Capell marketplace app keeps the first-party extension catalogue in database/seeders/MarketplaceExtensionSeeder.php. That seeder should be updated whenever a package becomes Capell-approved so the marketplace, package registry, and docs agree on:

  • display name;
  • Composer package name;
  • extension kind;
  • short description;
  • pricing;
  • product group;
  • tier;
  • bundle key;
  • capabilities.

Run it in the marketplace app with:

Terminal window
php artisan db:seed --class=MarketplaceExtensionSeeder

The seeder marks removed first-party extensions as hidden, so keep the list complete rather than only adding the latest package.

  • Morph map. Any pageable model must register its alias in the service provider before the seeder runs.
  • PublishingStudio. Rows inserted without a workspace_id land in the live version (workspace 0). If you seed draft content, set workspace_id explicitly.
  • Cache. Run php artisan capell:cache:clear-pages (or equivalent) after seeding if your app is hot.