Generate Momentum CMS Collection
Create a new collection file following project conventions.
Arguments
$ARGUMENTS - Collection name (e.g., "posts", "products", "pages")
Steps
Create the collection file at src/collections/<name>.collection.ts
Use this template:
import {
defineCollection,
text,
richText,
number,
date,
checkbox,
select,
relationship,
} from '@momentumcms/core';
export const <PascalName> = defineCollection({
slug: '<kebab-name>',
admin: {
useAsTitle: 'title', // or 'name' - the field to display as title
defaultColumns: ['title', 'createdAt'],
group: 'Content', // Admin sidebar group
},
access: {
read: () => true,
create: ({ req }) => !!req.user,
update: ({ req }) => req.user?.role === 'admin',
delete: ({ req }) => req.user?.role === 'admin',
},
hooks: {
beforeChange: [],
afterChange: [],
},
fields: [
text('title', { required: true }),
// Add more fields as needed
],
});
- Add to momentum config. In
src/momentum.config.ts, import and add to collections array:
import { <PascalName> } from './collections/<name>.collection';
// In config:
collections: [Posts, <PascalName>],
- Remind user to run schema generation:
npx drizzle-kit generate
npx drizzle-kit push
Field Types Available
text(name, options) - Short text (minLength, maxLength)
textarea(name, options) - Multi-line text (rows, minLength, maxLength)
richText(name, options) - Rich text editor
number(name, options) - Numeric value (min, max, step)
date(name, options) - Date/datetime
checkbox(name, options) - Boolean
select(name, { options: [...] }) - Dropdown (hasMany for multi-select)
radio(name, { options: [...] }) - Radio buttons
email(name, options) - Email with validation
upload(name, { relationTo: 'media' }) - File upload
relationship(name, { collection: () => Ref }) - Reference to another collection
array(name, { fields: [...] }) - Array of objects (minRows, maxRows)
group(name, { fields: [...] }) - Nested object
blocks(name, { blocks: [...] }) - Content blocks
json(name, options) - Raw JSON
point(name, options) - Geolocation (lat/lng)
slug(name, { from: 'title' }) - Auto-generated slug
Layout Fields (visual only, no data storage)
tabs(name, { tabs: [{ label, fields }] }) - Tabbed sections
collapsible(name, { fields, defaultOpen }) - Expandable section
row(name, { fields }) - Horizontal row
Access Control Helpers
import {
allowAll,
denyAll,
isAuthenticated,
hasRole,
hasAnyRole,
isOwner,
and,
or,
not,
} from '@momentumcms/core';
1---2name: collection-23description: Generate a new Momentum CMS collection with fields, access control, and hooks4---5
6# Generate Momentum CMS Collection
7
8Create a new collection file following project conventions.
9
10## Arguments
11
12- `$ARGUMENTS` - Collection name (e.g., "posts", "products", "pages")
13
14## Steps
15
161. Create the collection file at `src/collections/<name>.collection.ts`
17
182. Use this template:
19
20```typescript
21import {
22 defineCollection,
23 text,
24 richText,
25 number,
26 date,
27 checkbox,
28 select,
29 relationship,
30} from '@momentumcms/core';
31
32export const <PascalName> = defineCollection({
33 slug: '<kebab-name>',
34
35 admin: {
36 useAsTitle: 'title', // or 'name' - the field to display as title
37 defaultColumns: ['title', 'createdAt'],
38 group: 'Content', // Admin sidebar group
39 },
40
41 access: {
42 read: () => true,
43 create: ({ req }) => !!req.user,
44 update: ({ req }) => req.user?.role === 'admin',
45 delete: ({ req }) => req.user?.role === 'admin',
46 },
47
48 hooks: {
49 beforeChange: [],
50 afterChange: [],
51 },
52
53 fields: [
54 text('title', { required: true }),
55 // Add more fields as needed
56 ],
57});
58```
59
603. Add to momentum config. In `src/momentum.config.ts`, import and add to `collections` array:
61
62```typescript
63import { <PascalName> } from './collections/<name>.collection';
64
65// In config:
66collections: [Posts, <PascalName>],
67```
68
694. Remind user to run schema generation:
70
71```bash
72npx drizzle-kit generate
73npx drizzle-kit push
74```
75
76## Field Types Available
77
78- `text(name, options)` - Short text (minLength, maxLength)
79- `textarea(name, options)` - Multi-line text (rows, minLength, maxLength)
80- `richText(name, options)` - Rich text editor
81- `number(name, options)` - Numeric value (min, max, step)
82- `date(name, options)` - Date/datetime
83- `checkbox(name, options)` - Boolean
84- `select(name, { options: [...] })` - Dropdown (hasMany for multi-select)
85- `radio(name, { options: [...] })` - Radio buttons
86- `email(name, options)` - Email with validation
87- `upload(name, { relationTo: 'media' })` - File upload
88- `relationship(name, { collection: () => Ref })` - Reference to another collection
89- `array(name, { fields: [...] })` - Array of objects (minRows, maxRows)
90- `group(name, { fields: [...] })` - Nested object
91- `blocks(name, { blocks: [...] })` - Content blocks
92- `json(name, options)` - Raw JSON
93- `point(name, options)` - Geolocation (lat/lng)
94- `slug(name, { from: 'title' })` - Auto-generated slug
95
96## Layout Fields (visual only, no data storage)
97
98- `tabs(name, { tabs: [{ label, fields }] })` - Tabbed sections
99- `collapsible(name, { fields, defaultOpen })` - Expandable section
100- `row(name, { fields })` - Horizontal row
101
102## Access Control Helpers
103
104```typescript
105import {
106 allowAll,
107 denyAll,
108 isAuthenticated,
109 hasRole,
110 hasAnyRole,
111 isOwner,
112 and,
113 or,
114 not,
115} from '@momentumcms/core';
116```