Seeding Content

Lean CMS uses a YAML file to define your site’s content structure. Running a rake task converts that definition into database rows, giving editors something to work with immediately — and giving you a repeatable way to set up new environments.

The structure file

config/lean_cms_structure.yml defines every page, section, and field in your site. Pages have sections, sections have fields (and optionally cards or bullets):

site:
  name: "Acme Corporation"
  default_author_email: "admin@acme.com"

page_order:
  - home
  - about
  - contact

pages:
  home:
    display_title: "Home"
    page_order: 1
    sections:
      hero:
        display_title: "Hero Section"
        section_order: 1
        fields:
          heading:
            type: text
            label: "Hero Heading"
            default: "Custom Fabrication & Machining"
          subheading:
            type: text
            label: "Hero Subheading"
            default: "Precision parts, fast turnaround."
          cta_label:
            type: text
            label: "CTA Button Text"
            default: "Request a Quote"
          cta_url:
            type: url
            label: "CTA Button URL"
            default: "/contact"
          background:
            type: image
            label: "Background Image"

      services_preview:
        display_title: "Services Preview"
        section_order: 2
        fields:
          section_heading:
            type: text
            label: "Section Heading"
            default: "What We Do"
        cards:
          type: cards
          max_cards: 3
          items:
            - icon: "gear"
              icon_color: "white"
              bg_color: "#2563eb"
              heading: "Machining"
              text: "Precision CNC machining."
              alignment: "left"

  about:
    display_title: "About Us"
    page_order: 2
    sections:
      intro:
        display_title: "Introduction"
        section_order: 1
        fields:
          heading:
            type: text
            label: "Heading"
            default: "About Acme Corporation"
          body:
            type: rich_text
            label: "About Body"
            default: "<p>We've been building precision parts since 2005.</p>"

  contact:
    display_title: "Contact"
    page_order: 3
    sections:
      why_partner:
        display_title: "Why Partner With Us"
        section_order: 1
        fields:
          heading:
            type: text
            label: "Section Heading"
            default: "Why Partner With Us?"
        bullets:
          type: bullets
          max_items: 8
          items:
            - "Fast turnaround"
            - "No minimums"
            - "USA-based"

Required keys: pages.<key>.sections.<key>.fields — fields must be nested under a fields: block (not directly on the section). This is what distinguishes regular fields from cards/bullets, which sit at the section level.

Optional keys: display_title on pages and sections (falls back to a titleized key), page_order / section_order for sorting in the CMS UI, label on fields (shown in the editor), max_length for text fields, options for dropdown fields, position for explicit field ordering.

Generate the structure

rails lean_cms:load_structure

This command:

  1. Reads config/lean_cms_structure.yml
  2. Creates LeanCms::PageContent records for each field using find_or_initialize_by — safe to re-run
  3. Sets the default content value for any newly created field
  4. Logs what it created

Example output:

Loading LeanCMS page content structure...
Using system user: admin@acme.com
============================================================

Page: HOME (Home) [order: 1]
  Section: hero (Hero Section) [order: 1]
    ✓ Created: heading (text)
    ✓ Created: subheading (text)
    ✓ Created: cta_label (text)
    ✓ Created: cta_url (url)
    ✓ Created: background (image)
  Section: services_preview (Services Preview) [order: 2]
    ✓ Created: section_heading (text)
    ✓ Created: cards (3 items)

Page: ABOUT (About Us) [order: 2]
  Section: intro (Introduction) [order: 1]
    ✓ Created: heading (text)
    ✓ Created: body (rich_text)

============================================================
Summary:
  Total fields: 9
  Created: 9
  Updated: 0
  Skipped: 0
============================================================

On re-runs, unchanged fields show as - Skipped, and changed metadata (label, position, options) shows as ↻ Updated. The stored content value is only set on Created — re-runs do not overwrite editor changes.

Supported field types in YAML

type Description
text Plain single-line string
rich_text HTML content (Trix editor)
image File upload via ActiveStorage
boolean True/false toggle (default: "true" or "false")
url URL string
color CSS color value
dropdown String from a predefined list
cards JSON array of card objects
bullets JSON array of bullet objects

Exporting the current structure

If you have an existing site and want to generate a YAML file from the live database:

rails lean_cms:export_structure

This writes config/lean_cms_structure_export.yml with every page, section, and field — using each field’s current value as its default. Useful for bootstrapping a second environment from production data, or for documenting an existing install. Override the output path with OUTPUT=:

rails lean_cms:export_structure OUTPUT=config/lean_cms_structure_staging.yml

Image attachments are not included in the export — re-attach via the CMS UI or copy ActiveStorage blobs separately.

Updating content after the initial seed

For copy edits and tweaks, just edit through /lean-cms — that’s the whole point of the CMS. For structural changes (new field, renamed section), edit config/lean_cms_structure.yml and re-run lean_cms:load_structure — it’s idempotent and won’t clobber editor changes to existing fields. For one-off data updates across environments, use the content sync workflow (lean_cms:sync:pull / lean_cms:sync:push).

Multiple clients

If you manage multiple client sites, keep a separate structure file per client:

config/
  lean_cms_structure_acme.yml
  lean_cms_structure_widgets_co.yml

Load a specific file:

rails lean_cms:load_structure[config/lean_cms_structure_acme.yml]