Plato.SchemaBuilder (plato v0.0.24)

Copy Markdown View Source

DSL for defining CMS schemas in code.

Schema definitions in code provide version control, consistency, and team collaboration benefits over UI-defined schemas. Schemas are marked as managed_by: "code" and displayed as read-only in the admin UI.

Basic Usage

defmodule MyApp.ContentSchemas do
  use Plato.SchemaBuilder

  schema "homepage", unique: true do
    field :title, :text
    field :tagline, :text, multiline: true
  end

  schema "blog-post" do
    field :title, :text
    field :slug, :text
    field :excerpt, :text, multiline: true
    field :body, :text, multiline: true
    field :author, :reference, to: "author"
  end

  schema "author" do
    field :name, :text
    field :email, :text
    field :bio, :text, multiline: true
  end
end

Syncing to Database

Sync schemas on application startup in application.ex:

def start(_type, _args) do
  children = [MyApp.Repo, ...]
  {:ok, pid} = Supervisor.start_link(children, opts)

  # Sync after repo starts
  Plato.sync_schemas(MyApp.ContentSchemas, otp_app: :my_app)
  {:ok, pid}
end

Or use a migration for one-time sync:

defmodule MyApp.Repo.Migrations.SyncCMSSchemas do
  use Ecto.Migration

  def up do
    Plato.sync_schemas(MyApp.ContentSchemas, repo: MyApp.Repo)
  end

  def down do
    # Schemas remain but can be manually deleted if needed
  end
end

Schema Options

  • :unique - Only one content instance allowed (default: false)

Unique schemas are useful for singleton content like homepage, site settings, or global configuration.

Field Types

  • :text - Single-line or multiline text input
  • :image - Image upload with S3 storage (requires S3 configuration)
  • :reference - Reference to another schema (one-to-one relationship)

Field Options

Text Fields

  • :multiline - Render as textarea instead of input (default: false) Textareas are 100% width, 250px height with vertical resizing

Reference Fields

  • :to - Target schema name (required for reference fields)

Field Options (All Types)

  • :as_title - Use this field as the display title in lists (default: first field)

Complete Example

defmodule MyApp.ContentSchemas do
  use Plato.SchemaBuilder

  # Singleton content
  schema "site-settings", unique: true do
    field :site_name, :text, as_title: true
    field :tagline, :text
    field :logo, :image
  end

  # Blog system
  schema "blog-post" do
    field :title, :text, as_title: true
    field :slug, :text
    field :excerpt, :text, multiline: true
    field :body, :text, multiline: true
    field :cover_image, :image
    field :author, :reference, to: "author"
    field :category, :reference, to: "category"
  end

  schema "author" do
    field :name, :text, as_title: true
    field :email, :text
    field :bio, :text, multiline: true
    field :avatar, :image
  end

  schema "category" do
    field :name, :text, as_title: true
    field :slug, :text
    field :description, :text, multiline: true
  end
end

Updating Schemas

When you modify schema definitions, re-running sync_schemas/2 will:

  • Create new schemas that don't exist
  • Update existing schemas (unique flag, field options)
  • Create new fields
  • Update field options on existing fields
  • Preserve existing content and field values

Note: Sync does not delete schemas or fields. Remove them manually via the admin UI if needed.

Image Fields

Image fields require S3-compatible storage configuration. See Plato.Storage.S3Adapter for setup instructions. Without S3 configuration, image fields will not appear in the admin UI.

Summary

Functions

Defines a field within a schema.

Defines a schema with fields.

Functions

field(name, type, opts \\ [])

(macro)

Defines a field within a schema.

Field Types

  • :text - Text field
  • :reference - Reference to another schema (requires to: "schema_name" option)

Field Options

  • :multiline - Render text field as textarea (default: false)
  • :to - Referenced schema name (for reference fields only)

Examples

field :title, :text
field :body, :text, multiline: true
field :excerpt, :text, multiline: true
field :author, :reference, to: "author"

schema(name, opts \\ [], list)

(macro)

Defines a schema with fields.

Options

  • :unique - Whether only one instance of this schema can exist (default: false)

Examples

schema "homepage", unique: true do
  field :title, :text
  field :hero_image, :reference, to: "image"
end