Skip to content

Commit

Permalink
Mutation API (#374)
Browse files Browse the repository at this point in the history
* Setup transactions

* Interim

* Well, database tests pass but init broke?

* Generating here is not actually useful

* Interim

* Test file uploads

* Handle image uploads in upload tranaction

* Interim

* Update docs

* Attempt to create a fluent interface for filtering and selecting. Next we'll try to match that for mutations so things will hopefully feel intuitive

* Make mutations more or less immutable and bundle the operations under the Mutate namespace

* Interim

* Query docs

* Rich text edit parser

* Docs

* The one place where we ts-ignore....
  • Loading branch information
benmerckx committed Feb 8, 2024
1 parent e5854c8 commit df4a9a9
Show file tree
Hide file tree
Showing 66 changed files with 2,242 additions and 535 deletions.
6 changes: 3 additions & 3 deletions apps/dev/cms.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import alinea from 'alinea'
import {Entry, createCMS} from 'alinea/core'
import alinea, {Query} from 'alinea'
import {createCMS} from 'alinea/core'
import {IcRoundTranslate} from 'alinea/ui/icons/IcRoundTranslate'
import {IcRoundUploadFile} from 'alinea/ui/icons/IcRoundUploadFile'
import {position} from './src/PositionField'
Expand Down Expand Up @@ -96,7 +96,7 @@ const Fields = alinea.document('Fields', {
entry: alinea.entry('Internal link'),
entryWithCondition: alinea.entry('With condition', {
help: `Show only entries of type Fields`,
condition: Entry.type.is('Fields')
condition: Query.whereType('Fields')
}),
linkMultiple: alinea.link.multiple('Mixed links, multiple'),
image: alinea.image('Image link'),
Expand Down
198 changes: 198 additions & 0 deletions apps/web/content/pages/docs/content/editing-content.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
{
"title": "Editing content",
"navigationTitle": "",
"body": [
{
"type": "paragraph",
"textAlign": "left",
"content": [
{
"type": "text",
"text": "Your CMS instance has methods to create and update content. During development these will update the file system directly, while in production the changes will result in a new git commit."
}
]
},
{
"type": "heading",
"textAlign": "left",
"level": 2,
"content": [
{
"type": "text",
"text": "Creating Entries"
}
]
},
{
"type": "paragraph",
"textAlign": "left",
"content": [
{
"type": "text",
"text": "New Entries can be created using the `create` function."
}
]
},
{
"id": "2bww0XuSHzm0f72kxNM5cQlVLvI",
"type": "CodeBlock",
"code": "import {Edit} from 'alinea'\n\n// Start a transaction to create a new entry of type BlogPost\nconst post = Edit.create(BlogPost).set({\n title: 'A new blog post',\n body: 'Hello world'\n})\n\n// The new entry ID can be read before comitting\nconsole.log(`Creating post with id: ${post.id}`)\n\n// Save the changes\nawait cms.commit(post)",
"fileName": "",
"language": ""
},
{
"type": "heading",
"textAlign": "left",
"level": 3,
"content": [
{
"type": "text",
"text": "Creating child Entries"
}
]
},
{
"type": "paragraph",
"textAlign": "left",
"content": [
{
"type": "text",
"text": "To nest new Entries correctly it's possible to set the parent id, or construct directly from a parent update."
}
]
},
{
"id": "2c4tj6ItJDix4tpGojE9LGn0fTo",
"type": "CodeBlock",
"code": "import {Edit} from 'alinea'\n\nconst blog = Edit.create(Blog).set({title: 'Blog'})\nconst posts = postData.map(data =>\n blog.createChild(BlogPost).set({title: data.title})\n)\n// Or, if you're adding to an existing parent\n// blog.create(BlogPost).setParent(blogId).set({title: data.title})\nawait cms.commit(blog, ...posts)",
"fileName": "",
"language": ""
},
{
"type": "heading",
"textAlign": "left",
"level": 2,
"content": [
{
"type": "text",
"text": "Update Fields"
}
]
},
{
"type": "paragraph",
"textAlign": "left",
"content": [
{
"type": "text",
"text": "Entry fields can be edited using the `edit` function. Optionally pass the entry Type as a second argument so the field values are typed correctly."
}
]
},
{
"id": "2bx3AJ8D93WgmthX8tiEqZura9X",
"type": "CodeBlock",
"code": "import {Edit, Query} from 'alinea'\n\n// Select the first blog post\nconst blogPostId = await cms.get(Query(BlogPost).select(Query.id))\n\n// Edit a field and save\nconst update = Edit(blogPostId, BlogPost).set({\n body: 'New body text'\n})\n\nawait cms.commit(update)",
"fileName": "",
"language": ""
},
{
"type": "heading",
"textAlign": "left",
"level": 3,
"content": [
{
"type": "text",
"text": "Constructing field values"
}
]
},
{
"type": "paragraph",
"textAlign": "left",
"content": [
{
"type": "text",
"text": "Some fields contain values that are more complex than a string. The Edit namespace contains helper functions to construct these. In this example we construct the value of a List Field."
}
]
},
{
"id": "2c4t1IBcmwpjaS3YqNaJQxRpWss",
"type": "CodeBlock",
"code": "const richTextField = richText('Item body text');\nconst listField = list('My list field', {\n schema: {\n Text: type('Text', {\n title: text('Item title'),\n text: richText,\n })\n }\n})\nconst rowText = Edit.richText(richTextField)\n .addHtml(`\n <h1>Main heading</h1>\n <p>A rich text value parsed from HTML.</p>\n `)\n .value()\nconst listValue = Edit.list(listField)\n .add('Text', {\n title: 'The row title',\n text: rowText,\n })\n .value()\nconst update = Edit(entryId, TypeWithList).set({\n list: listValue\n})",
"fileName": "",
"language": ""
},
{
"type": "heading",
"textAlign": "left",
"level": 2,
"content": [
{
"type": "text",
"text": "File uploads"
}
]
},
{
"type": "paragraph",
"textAlign": "left",
"content": [
{
"type": "text",
"text": "Files can be uploaded using the upload function."
}
]
},
{
"id": "2bx3SNjDfXQsRSkJYEUX5GY3qg9",
"type": "CodeBlock",
"code": "import {Edit} from 'alinea'\n\nconst file = new File(['content'], 'test.txt')\nconst upload = Edit.upload(file)\n\n// The new entry ID can be read before comitting\nconsole.log(`Creating post with id: ${upload.id}`)\n\n// Upload file and save file metadata\nawait cms.commit(upload)",
"fileName": "",
"language": ""
},
{
"type": "heading",
"textAlign": "left",
"level": 3,
"content": [
{
"type": "text",
"text": "Creating image previews"
}
]
},
{
"type": "paragraph",
"textAlign": "left",
"content": [
{
"type": "text",
"text": "Alinea can create all the metadata for images (such as previews) by passing a `createPreview` function. On the server this will use the `sharp` package to read image data. The package will need to be installed separately."
}
]
},
{
"id": "2bxKAtZiQcruhSmRPO9PldQZ3mR",
"type": "CodeBlock",
"code": "import {Edit} from 'alinea'\nimport {createPreview} from 'alinea/core/media/CreatePreview'\nimport fs from 'node:fs'\n\nconst file = new File([\n fs.readFileSync('./test.png')\n], 'test.png')\nconst upload = Edit.upload(file, {createPreview})\nawait cms.commit(upload)",
"fileName": "",
"language": ""
}
],
"metadata": {
"title": "",
"description": "",
"openGraph": {
"title": "",
"image": {},
"description": ""
}
},
"@alinea": {
"entryId": "2bwoBrTOuERj2E8r7yuNglC0H6G",
"type": "Doc",
"index": "a1G"
}
}
Loading

0 comments on commit df4a9a9

Please sign in to comment.