Skip to content

CMSEdit the real website

Schema-driven content editing for AdonisJS + Inertia + Vue + Nuxt UI sites. Staff click Edit on any section, a generated form slides out, the page previews every change, and Save commits everything at once.

Two-minute tour ​

1. Describe content as a schema. The same file defines the defaults, the editing form and the validation:

ts
// app/cms/pages/home.ts
import { f, definePage, section } from '@martipops/cms-core'

export default definePage('home', {
  hero: section('Hero', {
    title: f.text({ default: 'Fresh pizza since 1979', max: 120 }),
    image: f.image({ label: 'Photo', default: 'images/hero.webp' }),
    buttons: f.list({ label: f.text({ max: 30 }), link: f.link() }, { max: 3, itemTitle: 'label' }),
  }),
})

2. Send it from a controller:

ts
return ctx.inertia.render('home', { content: await cms.pageProps('home', ctx) })

3. Render it. Edit mode lights up on its own for signed-in editors:

vue
<CmsPage :content="content">
  <CmsSection v-slot="{ data }" name="hero">
    <h1>{{ data.title }}</h1>
  </CmsSection>
</CmsPage>

For lists of records (locations, menu items, events), defineCollection plus CmsCollection gives you collapsible item forms with add, hide, delete and reorder.

Where to next ​

ReadWhen
InstallingAdding the CMS to a new site
ArchitectureYou want the mental model: data flow, storage, drafts, guarantees
Schema referenceWriting schemas, all field types, custom field types
Server referenceconfig/cms.ts, the Cms service API, tables, testing
Client referenceComponents, slots, the plugin, the draft store
Commit protocolThe wire format: ops, refs, errors, history
DecisionsWhy it works the way it does (and what was rejected)
RoadmapWhat's next, with technical designs