[data-reveal]{opacity:1!important;transform:none!important}
CMS Interfaces

CMS Base Documentation

Overview

The cms-base interface is the component vocabulary of the CMS: forms, tables, charts and cards, layout containers, trees, the data types behind every field, and the shared prop types they all draw from.

Every component here is a builder. Form({...}), TableView(controller, {...}) and ChartLine({...}) do not render anything — they return a ComponentBuilder from the cms interface, which is a serializable description of a component: its name, its options, and its children. You assign that description to a static field of a page class, and the frontend reads the page's tree and draws it. The options you set are therefore data, and the components that need data are given a fetchUrl and a submitUrl pointing back at routes you declare on the same page or on a data controller.

Two consequences shape the whole interface. First, a component's contract is its props interface: what you can express is exactly what the props allow, which is why this reference documents them field by field. Second, anything the frontend must receive has to survive serialization, so a builder that accepts a nested Component — a modal target, a kanban card, a chart inside a card — stores its serialized form instead.

The CMS documentation carries task-shaped chapters on the same components, organised around what you are building. This folder is the contract behind them: the exact symbol names, option fields and return types.

Subpath Map

@antelopejs-private/cms/interfaces/cms-base is the root barrel and re-exports most of the modules below. The ones marked as not in the barrel are imported from their own subpath.

SubpathHoldsIn the root barrelDocumented in
typesBase props, colours, sizes, buttons, action targets, row-action rules, guards, watch actions, enumsyesShared Types
formForm, FormComponents, schema helpersyesForms
table-viewTableView, @Column, TableViewRoutes, guards, row actionsyesTables
chartChart builders, series and point shapes, chart propsyesCharts and Widgets
chart-cardChartCardyesCharts and Widgets
kpi-cardKpiCardyesCharts and Widgets
top-list-cardTopListCardyesCharts and Widgets
period-selectorPeriodSelectoryesCharts and Widgets
gridGrid, GridRowyesLayout and Containers
stackHStack, VStack, SpaceryesLayout and Containers
tabTabyesLayout and Containers
layoutsDefaultLayout, EmptyLayoutyesLayout and Containers
placeholderPlaceholderyesLayout and Containers
customCustomComponentnoLayout and Containers
treeTree, TreeNode, TreeEventsyesTree
data-typesDataType, the registration decorators, DefaultDataTypes, DefaultDataCompareTypes, StatusTypenoData Types
searchableSearchable, SearchableMetayesHelpers
export-jobsrunExportJob and the export-job lifecycleyesHelpers
tenant-export-archivestartTenantExportJob, buildTenantExportArchiveyesHelpers
helpers/file-refsFile and image reference trackingnoHelpers
helpers/archive-mode-helpersapplyArchiveModeDefaultRulesnoHelpers

Within types, four modules are outside that subpath's barrel and are imported from types/action-target, types/row-action, types/row-action-operators and types/guards; the guard types and RowActionRule are also re-exported by table-view.

Key Features

  • Builders that produce data — Every component function returns a ComponentBuilder, so a page's UI is a plain value you can factor, reuse and compose with .child().
  • Forms from typed fields — A field names a DataType, and the type supplies both the input component and the Zod schema; Form compiles the field list into one schema and ships its JSON Schema form with the component.
  • Tables from data controllersTableView reads a controller's data-api metadata and its @Column declarations to build the columns, the new / edit / view forms, and the permission-carrying actions in one call.
  • Server-enforced row rules and guards — Row-action rules are a small algebra evaluated on both sides, and guards run inside the mutating routes, so what the row menu offers is what the server accepts.
  • A chart and widget set with a shared period scope — Twelve chart types plus KPI, chart and top-list cards; one PeriodSelector id ties them to the same range and comparison.
  • Layout without a frontend build — Grids, stacks, tabs and page layouts arrange components, and CustomComponent names a Vue component when the vocabulary runs out.
  • An extensible data-type registry@RegisterDataType and @RegisterDataCompareMode add your own types and filter operators to the catalogue the forms, columns and filters draw from.
  • Shared prop vocabulary — Colours, sizes, HTTP methods, action targets, readonly behaviour and watch actions are declared once in types and reused by every component.

Dependencies

This interface relies on the following AntelopeJS packages:

It also builds on sibling interfaces of the same package: cms/component for Component and ComponentBuilder, cms/page for the page a component is registered on, cms/permissions for the action permissions a table view declares, and cms-auth for the authenticated user its routes receive.

Quick Start

A page declaring one component. The Form builder describes the fields; the two routes on the same class serve and accept the values.

import { Get, JSONBody, Post } from "@antelopejs/interface-api";
import { GetModel } from "@antelopejs/interface-database-decorators";
import {
  PageController,
  pagesCategory,
  RegisterPage,
} from "@antelopejs-private/cms/interfaces/cms/page";
import { DefaultDataTypes } from "@antelopejs-private/cms/interfaces/cms-base/data-types";
import { Form } from "@antelopejs-private/cms/interfaces/cms-base/form";
import { DefaultLayout } from "@antelopejs-private/cms/interfaces/cms-base/layouts";
import { HttpMethod } from "@antelopejs-private/cms/interfaces/cms-base/types";
import { SettingsModel } from "./db";

@RegisterPage()
export class SettingsPage extends PageController(
  "settings",
  {
    urlSlug: "settings",
    displayName: "Settings",
    description: "Module configuration",
    icon: "i-ph-gear",
    category: pagesCategory,
  },
  DefaultLayout(),
) {
  static form = Form({
    title: "Settings",
    fetchUrl: "/settings/",
    submitUrl: "/settings/",
    submitUrlMethod: HttpMethod.post,
    fields: [
      {
        id: "enabled",
        label: "Enabled",
        type: new DefaultDataTypes.BooleanType(),
      },
      {
        id: "retentionDays",
        label: "Retention (days)",
        type: new DefaultDataTypes.NumberType({ min: 0 }),
        required: true,
      },
    ],
  });

  settingsModel = GetModel(SettingsModel);

  @Get("/")
  read() {
    return this.settingsModel.get();
  }

  @Post("/")
  async write(@JSONBody() body: unknown) {
    await this.settingsModel.table.update(body as Record<string, unknown>);
  }
}

The page registers itself at import time, and its routes are mounted under the page's slug — which is why the form fetches from and submits to /settings/. Nothing else is needed: Form has already serialized each field into an input-component description and compiled the two data types into one schema, which it carries in the component options alongside the URLs.

Documentation Sections

  • Shared Types - Base props, colours, sizes, action targets, row-action rules, guards and the small enums.
  • Forms - The Form builder, fields and groups, input components and the validation schema.
  • Tables - Table views over a data controller: columns, routes, row actions, guards, displays and generated forms.
  • Charts and Widgets - Chart types and props, chart cards, KPI cards, top lists and the period selector.
  • Layout and Containers - Grids, stacks, tabs, page layouts, the placeholder and the custom-component escape hatch.
  • Tree - Hierarchical nodes, selection behaviour and lazy loading.
  • Data Types - The DataType contract, the registries, the default catalogue and a custom type.
  • Helpers - Searchable columns, export jobs, file references and the archive-mode defaults.