Skip to content

Commit 0230f6c

Browse files
committed
Add push api.
1 parent d76afc4 commit 0230f6c

77 files changed

Lines changed: 1282 additions & 394 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
- Add rss support @robgietema
110110
- Add feed content type @robgietema
111111
- Add video content type @robgietema
112+
- Add push api @robgietema
112113

113114
### Bugfix
114115

docs/ai.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ $ CREATE EXTENSION IF NOT EXISTS vector;
2828

2929
## Setup the config
3030

31-
Next step is setup the AI models in the config. You can do so by adding following settings to your `config.js` file:
31+
Next step is setup the AI models in the config. You can do so by adding following settings to your `config.ts` file:
3232

3333
```ts
3434
export const config = {

docs/examples/controlpanels/get_types.res

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ Content-Type: application/json
6666
"id": "Site",
6767
"count": 1,
6868
"meta_type": "Site"
69+
},
70+
{
71+
"@id": "http://localhost:8080/@controlpanels/dexterity-types/Video",
72+
"@type": "Video",
73+
"title": "Video",
74+
"description": "Videos can be referenced in pages.",
75+
"id": "Video",
76+
"count": 0,
77+
"meta_type": "Video"
6978
}
7079
],
7180
"title": "Content Types",

docs/examples/types/list.res

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,10 @@ Content-Type: application/json
3636
"@id": "http://localhost:8080/@types/Site",
3737
"addable": false,
3838
"title": "Site"
39+
},
40+
{
41+
"@id": "http://localhost:8080/@types/Video",
42+
"addable": false,
43+
"title": "Video"
3944
}
4045
]

docs/examples/types/list_i18n.res

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,10 @@ Content-Type: application/json
3636
"@id": "http://localhost:8080/@types/Site",
3737
"addable": false,
3838
"title": "Site"
39+
},
40+
{
41+
"@id": "http://localhost:8080/@types/Video",
42+
"addable": false,
43+
"title": "Video"
3944
}
4045
]

docs/examples/vocabularies/get_types.res

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ Content-Type: application/json
3131
{
3232
"title": "Site",
3333
"token": "Site"
34+
},
35+
{
36+
"title": "Video",
37+
"token": "Video"
3438
}
3539
],
36-
"items_total": 7
40+
"items_total": 8
3741
}

docs/push.md

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
---
2+
nav_order: 9
3+
permalink: /usage/push
4+
parent: Push API
5+
---
6+
7+
# Push API
8+
9+
When you want to synchronize content of you website with an external source you can use the Push API. The Push API provides a webhook which will be called whenever content changes in your website.
10+
11+
## Config
12+
13+
To enable the Push API you can add the following to the config file:
14+
15+
```ts
16+
export const config = {
17+
...
18+
push: {
19+
enabled: true,
20+
user: 'admin',
21+
password: 'admin',
22+
url: 'https://somehost/push',
23+
},
24+
...
25+
};
26+
```
27+
28+
The user and password are optional but will be used to call the url with basic auth.
29+
30+
## Events
31+
32+
The `url` will be called when an event on a content object happens. The following events are used: `add`, `update`, `delete`, `copy`, `move`.
33+
34+
### Add
35+
36+
An example of the `add` event, the catalog is expanded by default:
37+
38+
```json
39+
{
40+
"method": "add",
41+
"path": "/events/event-3",
42+
"data": {
43+
"start": "2026-04-01T07:00:00.334Z",
44+
"title": "Event 3",
45+
"blocks": {
46+
"5cea07ab-983b-4c86-aba1-6de06e0647c5": { "@type": "title" },
47+
"6632cf31-4816-4403-a34e-d9d91a60037d": { "@type": "slate" }
48+
},
49+
"open_end": false,
50+
"attendies": [],
51+
"whole_day": false,
52+
"relatedItems": [],
53+
"blocks_layout": {
54+
"items": [
55+
"5cea07ab-983b-4c86-aba1-6de06e0647c5",
56+
"6632cf31-4816-4403-a34e-d9d91a60037d"
57+
]
58+
},
59+
"@components": {
60+
"catalog": {
61+
"@id": "http://localhost:3000/events/event-3/@catalog",
62+
"@type": "Event",
63+
"title": "Event 3",
64+
"getId": "event-3",
65+
"Creator": "admin",
66+
"UID": "844890e6-6d78-49cf-bf5c-c66653b50182",
67+
"path": "/events/event-3",
68+
"Description": null,
69+
"Title": "Event 3",
70+
"Subject": null,
71+
"is_folderish": true,
72+
"exclude_from_nav": false,
73+
"Type": "Event",
74+
"id": "event-3",
75+
"portal_type": "Event",
76+
"review_state": "private",
77+
"modified": "2026-04-23T16:23:26.000Z",
78+
"Date": "2026-04-23T16:23:26.000Z",
79+
"expires": null,
80+
"created": "2026-04-23T16:23:26.000Z",
81+
"effective": null,
82+
"getObjSize": 353,
83+
"listCreators": ["admin"],
84+
"mime_type": null,
85+
"CreationDate": "2026-04-23T16:23:26.000Z",
86+
"EffectiveDate": null,
87+
"ExpirationDate": null,
88+
"ModificationDate": "2026-04-23T16:23:26.000Z",
89+
"image_field": "",
90+
"image_scales": {},
91+
"start": "2026-01-01T08:00:00.105Z",
92+
"end": null,
93+
"recurrence": null,
94+
"hasPreviewImage": false
95+
},
96+
"actions": { "@id": "http://localhost:3000/events/@actions" },
97+
"breadcrumbs": { "@id": "http://localhost:3000/events/@breadcrumbs" },
98+
"navigation": { "@id": "http://localhost:3000/events/@navigation" },
99+
"navroot": { "@id": "http://localhost:3000/events/@navroot" },
100+
"related": { "@id": "http://localhost:3000/events/@related" },
101+
"types": { "@id": "http://localhost:3000/events/@types" },
102+
"workflow": { "@id": "http://localhost:3000/events/@workflow" },
103+
"translations": { "@id": "http://localhost:3000/events/@translations" },
104+
"inherit": { "@id": "http://localhost:3000/events/@inherit" }
105+
},
106+
"@id": "http://localhost:3000/events/event-3",
107+
"@type": "Event",
108+
"id": "event-3",
109+
"created": "2026-04-23T16:17:13.000Z",
110+
"modified": "2026-04-23T16:17:13.000Z",
111+
"UID": "61420b8c-f766-459d-9409-f7da72db6615",
112+
"owner": "admin",
113+
"layout": "view",
114+
"is_folderish": true,
115+
"review_state": "private",
116+
"lock": { "locked": false, "stealable": true }
117+
}
118+
}
119+
```
120+
121+
### Update
122+
123+
An example of the `update` event, the catalog is expanded by default:
124+
125+
```json
126+
{
127+
"method": "update",
128+
"path": "/events/event-3",
129+
"data": {
130+
"start": "2026-04-01T07:00:00.334Z",
131+
"title": "New Event 3",
132+
"blocks": {
133+
"5cea07ab-983b-4c86-aba1-6de06e0647c5": { "@type": "title" },
134+
"6632cf31-4816-4403-a34e-d9d91a60037d": { "@type": "slate" }
135+
},
136+
"open_end": false,
137+
"attendies": [],
138+
"whole_day": false,
139+
"relatedItems": [],
140+
"blocks_layout": {
141+
"items": [
142+
"5cea07ab-983b-4c86-aba1-6de06e0647c5",
143+
"6632cf31-4816-4403-a34e-d9d91a60037d"
144+
]
145+
},
146+
"@components": {
147+
"catalog": {
148+
"@id": "http://localhost:3000/events/event-3/@catalog",
149+
"@type": "Event",
150+
"title": "New Event 3",
151+
"getId": "event-3",
152+
"Creator": "admin",
153+
"UID": "844890e6-6d78-49cf-bf5c-c66653b50182",
154+
"path": "/events/event-3",
155+
"Description": null,
156+
"Title": "Event 3",
157+
"Subject": null,
158+
"is_folderish": true,
159+
"exclude_from_nav": false,
160+
"Type": "Event",
161+
"id": "event-3",
162+
"portal_type": "Event",
163+
"review_state": "private",
164+
"modified": "2026-04-23T16:23:26.000Z",
165+
"Date": "2026-04-23T16:23:26.000Z",
166+
"expires": null,
167+
"created": "2026-04-23T16:23:26.000Z",
168+
"effective": null,
169+
"getObjSize": 353,
170+
"listCreators": ["admin"],
171+
"mime_type": null,
172+
"CreationDate": "2026-04-23T16:23:26.000Z",
173+
"EffectiveDate": null,
174+
"ExpirationDate": null,
175+
"ModificationDate": "2026-04-23T16:23:26.000Z",
176+
"image_field": "",
177+
"image_scales": {},
178+
"start": "2026-01-01T08:00:00.105Z",
179+
"end": null,
180+
"recurrence": null,
181+
"hasPreviewImage": false
182+
},
183+
"actions": { "@id": "http://localhost:3000/events/@actions" },
184+
"breadcrumbs": { "@id": "http://localhost:3000/events/@breadcrumbs" },
185+
"navigation": { "@id": "http://localhost:3000/events/@navigation" },
186+
"navroot": { "@id": "http://localhost:3000/events/@navroot" },
187+
"related": { "@id": "http://localhost:3000/events/@related" },
188+
"types": { "@id": "http://localhost:3000/events/@types" },
189+
"workflow": { "@id": "http://localhost:3000/events/@workflow" },
190+
"translations": { "@id": "http://localhost:3000/events/@translations" },
191+
"inherit": { "@id": "http://localhost:3000/events/@inherit" }
192+
},
193+
"@id": "http://localhost:3000/events/event-3",
194+
"@type": "Event",
195+
"id": "event-3",
196+
"created": "2026-04-23T16:17:13.000Z",
197+
"modified": "2026-04-23T16:17:13.000Z",
198+
"UID": "61420b8c-f766-459d-9409-f7da72db6615",
199+
"owner": "admin",
200+
"layout": "view",
201+
"is_folderish": true,
202+
"review_state": "private",
203+
"lock": { "locked": false, "stealable": true }
204+
}
205+
}
206+
```
207+
208+
### Delete
209+
210+
An example of the delete event:
211+
212+
```json
213+
{
214+
"method": "delete",
215+
"path": "/events/event-1",
216+
"data": null
217+
}
218+
```
219+
220+
### Copy
221+
222+
An example of the copy event:
223+
224+
```json
225+
{
226+
"method": "copy",
227+
"path": "/events/event-1",
228+
"data": {
229+
"target": "/news/event-1"
230+
}
231+
}
232+
```
233+
234+
### Move
235+
236+
An example of the move event:
237+
238+
```json
239+
{
240+
"method": "move",
241+
"path": "/events/event-1",
242+
"data": {
243+
"target": "/news/event-1"
244+
}
245+
}
246+
```

locales/bg.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)