### Start Blokkli Editor with BlokkliProvider Source: https://github.com/blokkli/editor/blob/main/docs/editor/overview.md This example shows how to integrate the `` component to enable the editor. The 'Edit Blocks' button will only appear if the `:can-edit` prop is true, typically controlled by user permissions. ```vue ``` -------------------------------- ### Example Grid Overlay Styling Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getGridMarkup.md An example of how to style the grid overlay using PostCSS. This includes positioning, z-index, and column layout. ```postcss .bk-grid-overlay { @apply fixed top-0 left-0 w-full z-[99999999] h-full pointer-events-none; .container { @apply grid grid-cols-12 gap-40 h-full; > div { @apply h-full border-l-[0.75px] border-l-black/40 border-r-[0.75px] border-r-black/40; } } } ``` -------------------------------- ### Install blökkli Editor Package Source: https://github.com/blokkli/editor/blob/main/docs/index.md Install the blökkli editor package using npm. ```sh npm install --save @blokkli/editor ``` -------------------------------- ### Full defineBlokkli Configuration Example Source: https://github.com/blokkli/editor/blob/main/docs/define-blokkli.md A comprehensive example demonstrating all configurable properties of defineBlokkli, including render conditions, chunk naming, complex options, global options, and detailed editor behavior settings. ```vue ``` -------------------------------- ### Example Entity Information Source: https://github.com/blokkli/editor/blob/main/docs/editor/edit-state.md An example of the 'entity' object, which provides metadata about the host entity being edited. This includes its label, publication status, and bundle label, used for features like displaying the page title. ```json { "label": "Landing page winter 2024", "status": true, "bundleLabel": "Landing Page" } ``` -------------------------------- ### Minimal defineBlokkli Example Source: https://github.com/blokkli/editor/blob/main/docs/define-blokkli.md The minimal configuration for defineBlokkli requires only the 'bundle' property, which specifies the component to be rendered. ```vue ``` -------------------------------- ### Example Mutated Options Source: https://github.com/blokkli/editor/blob/main/docs/editor/edit-state.md An example of the mutatedState.mutatedOptions object, which stores overridden options for blocks keyed by their UUID. This object is reactive, allowing instant visual feedback for option changes. ```json { "9485812c-0ecd-4699-85b2-3a031d47a0a1": { "buttonType": "secondary" }, "87098bb1-d849-4afc-8845-05ef2d08d160": { "background": "red", "anchorId": "contact-us" } } ``` -------------------------------- ### Example Mutations Array Source: https://github.com/blokkli/editor/blob/main/docs/editor/edit-state.md An example of the mutations array, which contains a history of all applied mutations. Each mutation includes a timestamp, plugin ID, and details about the plugin and its affected item. ```json [ { "timestamp": 1706109810, "pluginId": "move_blocks", "plugin": { "label": "Move 'Title' block", "affectedItemUuid": "9ab46061-c9f3-40fb-bfb1-27ba3bb628f5" } }, { "timestamp": 1706109422, "pluginId": "add_new_block", "plugin": { "label": "Add 'Text' block", "affectedItemUuid": "d8d3ad51-7c37-4a27-ad64-e04ee8a4f842" } }, { "timestamp": 1706107204, "pluginId": "add_new_block", "plugin": { "label": "Add 'Title' block", "affectedItemUuid": "9ab46061-c9f3-40fb-bfb1-27ba3bb628f5" } } ] ``` -------------------------------- ### MediaLibraryItem Example Source: https://github.com/blokkli/editor/blob/main/docs/adapter/mediaLibraryGetResults.md Defines the structure for media items returned by mediaLibraryGetResults(). Each item includes mediaId, label, context, blockBundle, and optionally a thumbnail or icon. ```typescript const items = [ { // The ID of the media item. This will be later passed // to mediaLibraryAddBlock(). mediaId: '25', // The label/title displayed in the media grid. label: 'Image of a computer', // An additional string to give the user some context. // Could be some tags, a file name, etc. context: 'Stock photo', // The resulting block bundle that will be created when // the user drag and drops this media into the page. blockBundle: 'image', // A thumbnail that is used in the media grid. thumbnail: 'https://www.example.com/image-of-a-computer.jpg', }, { mediaId: '79', label: 'Terms and conditions', context: 'PDF', blockBundle: 'document', // Instead of a thumbnail we can also provide the name of // a valid blökkli icon instead. icon: 'file', }, { mediaId: '45', label: 'A nice music video', context: 'YouTube', blockBundle: 'video', thumbnail: 'https://i3.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg', }, ] ``` -------------------------------- ### Implement getPreviewGrantUrl in Blokklí Edit Adapter Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getPreviewGrantUrl.md This snippet shows how to implement the getPreviewGrantUrl method within a Blokklí edit adapter. It returns a hardcoded example URL. Ensure the returned URL is valid and starts with 'https://'. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { getPreviewGrantUrl: () => { return 'https://example.com/backend-api/grant-access?grantToken=QNeQGCzrBfJ1E83b3kcDKll9RmMsTBDR3Ozb3jYVoAcqTphgNuZlrRmsgAHc2JUj' }, } }) ``` -------------------------------- ### Text Filter Example Source: https://github.com/blokkli/editor/blob/main/docs/adapter/mediaLibraryGetResults.md Defines a text input filter for the media library. The selected value will be a string. ```json { "type": "text", "label": "Search text", "placeholder": "Enter a search term" } ``` -------------------------------- ### Full Edit State Object Example Source: https://github.com/blokkli/editor/blob/main/docs/editor/edit-state.md A comprehensive example of the edit state object as returned by mapState(). This includes mutation history, user information, mutated content, entity details, and translation state. ```json { "currentIndex": 2, "mutations": [ { "timestamp": 1706109810, "pluginId": "move_blocks", "plugin": { "label": "Move 'Title' block", "affectedItemUuid": "9ab46061-c9f3-40fb-bfb1-27ba3bb628f5" } }, { "timestamp": 1706109422, "pluginId": "add_new_block", "plugin": { "label": "Add 'Text' block", "affectedItemUuid": "d8d3ad51-7c37-4a27-ad64-e04ee8a4f842" } }, { "timestamp": 1706107204, "pluginId": "add_new_block", "plugin": { "label": "Add 'Title' block", "affectedItemUuid": "9ab46061-c9f3-40fb-bfb1-27ba3bb628f5" } } ], "currentUserIsOwner": true, "ownerName": "John Wayne", "mutatedState": { "mutatedOptions": { "9485812c-0ecd-4699-85b2-3a031d47a0a1": { "buttonType": "secondary" }, "87098bb1-d849-4afc-8845-05ef2d08d160": { "background": "red", "anchorId": "contact-us" } }, "fields": [ { "name": "blocks", "entityType": "content", "entityUuid": "1", "list": [ { "uuid": "96f7fbda-04d9-4662-9a6c-6aa3bcf964f2", "bundle": "title", "props": { "title": "Hello world" } }, { "uuid": "9485812c-0ecd-4699-85b2-3a031d47a0a1", "bundle": "grid", "props": { "card": [] } } ] }, { "name": "cards", "entityType": "block", "entityUuid": "9485812c-0ecd-4699-85b2-3a031d47a0a1", "list": [ { "uuid": "96f7fbda-04d9-4662-9a6c-6aa3bcf964f2", "bundle": "card", "props": { "title": "Hello world", "text": "Lorem ipsum dolor" } }, { "uuid": "9485812c-0ecd-4699-85b2-3a031d47a0a1", "bundle": "card", "props": { "title": "A second card", "text": "Lorem ipsum dolor" } } ] } ], "violations": [] }, "entity": { "label": "Landing page winter 2024", "status": true, "bundleLabel": "Landing Page" }, "translationState": { "isTranslatable": true, "sourceLanguage": "en", "availableLanguages": [ { "id": "en", "name": "English" }, { "id": "de", "name": "German" }, { "id": "fr", "name": "French" }, { "id": "it", "name": "Italian" } ], "translations": [ { "id": "en", "url": "/en/subscribe-to-newsletter", "status": true }, { "id": "de", "url": "/de/anmeldung-newsletter", "status": false } ] } } ``` -------------------------------- ### Implement publish() in Blokkli Edit Adapter Source: https://github.com/blokkli/editor/blob/main/docs/adapter/publish.md Implement the publish method within the Blokkli edit adapter to handle persisting changes. This example shows how to make a POST request to a backend API endpoint for publishing. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { publish: (e) => { return $fetch(`/backend-api/edit/${ctx.value.entityUuid}/publish`, { method: 'post', }) }, } }) ``` -------------------------------- ### Basic BlokkliProvider Usage Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getFieldConfig.md This Vue component demonstrates the basic setup for BlokkliProvider and BlokkliField, showing how to associate blocks with a specific entity. ```vue ``` -------------------------------- ### Nested BlokkliField Example Source: https://context7.com/blokkli/editor/llms.txt Demonstrates how to create nested block regions using BlokkliField. The parent block passes nested block data as props to its children. ```vue ``` ```vue ``` -------------------------------- ### Initialize Blokkli Context Source: https://github.com/blokkli/editor/blob/main/docs/define-blokkli/block-context.md Call defineBlokkli() to get the context object. Specify the bundle name for the block. ```typescript const ctx = defineBlokkli({ bundle: 'title', }) ``` -------------------------------- ### Checkbox Filter Example Source: https://github.com/blokkli/editor/blob/main/docs/adapter/mediaLibraryGetResults.md Defines a simple checkbox filter for the media library. The selected value will be a boolean. ```json { "type": "checkbox", "label": "Only show published medias" } ``` -------------------------------- ### Field Configuration Allowing Only Text Blocks Source: https://github.com/blokkli/editor/blob/main/src/runtime/components/Edit/Features/Library/docs.md Example of a field configuration that initially only allows 'text' block bundles. This is a baseline before considering reusable blocks. ```typescript import type { FieldConfig } from '#blokkli/types' const fieldConfig: FieldConfig[] = [ { name: 'field_blocks', entityType: 'content', entityBundle: 'blog_post', label: 'Blocks', cardinality: -1, canEdit: true, allowedBundles: ['text'], }, ] ``` -------------------------------- ### Implement updateOptions() in Blokkli Edit Adapter Source: https://github.com/blokkli/editor/blob/main/docs/adapter/updateOptions.md Implement the updateOptions function within the Blokkli edit adapter to handle block option updates. This example shows how to send an API request to the backend with the update items. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { updateOptions: (items) => { // An array of UpdateBlockOptionEvent objects that have these properties: // { // uuid: string // key: string // value: string // } // Example data: // { // uuid: '2139b0fa-f407-4014-9d49-1c8a7f090190', // key: 'buttonType', // value: 'secondary', // } return $fetch( `/backend-api/edit/${ctx.value.entityUuid}/update-options`, { method: 'post', body: { items, }, }, ) }, } }) ``` -------------------------------- ### Render Inline Field List in Home Page Source: https://github.com/blokkli/editor/blob/main/docs/define-blokkli/render-for.md Example of using the BlokkliField component with a list of blocks and specifying 'inline' as the field list type in the home page template. ```vue ``` -------------------------------- ### Implement getAllBundles() in Blokkli Edit Adapter Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getAllBundles.md Implement the getAllBundles method to return a promise resolving with an array of block bundle definitions. Ensure all necessary types are imported. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' import types from '#blokkli/types' const bundles: types.BlockBundleDefinition[] = [ { id: 'card', label: 'Card', description: 'A block that renders a card with a title, text and a link.', allowReusable: true, isTranslatable: true, }, { id: 'horizontal_rule', label: 'Horizontal Rule', description: 'A block that renders a simple horizontal rule to separate content.', allowReusable: false, isTranslatable: false, }, // etc. ] export default defineBlokkliEditAdapter((ctx) => { return { getAllBundles: () => { return Promise.resolve(bundles) }, } }) ``` -------------------------------- ### getGridMarkup() Implementation Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getGridMarkup.md This method returns the HTML markup to display the grid overlay in the editor. It is called when the user enables the 'Grid' view overlay. The resulting markup will be rendered in a div that is a child of . The specific implementation is responsible for styling the grid. ```APIDOC ## getGridMarkup() ### Description Returns the HTML markup to display the grid overlay in the editor. This method is invoked when the user enables the "Grid" view overlay. ### Method Signature `getGridMarkup(): string` ### Returns - `string`: The HTML markup for the grid overlay. ### Example ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { getGridMarkup: () => { return `
${Array(12).fill('
').join('')}
` }, } }) ``` ``` -------------------------------- ### Example Mutated State Fields Source: https://github.com/blokkli/editor/blob/main/docs/editor/edit-state.md An example of the mutatedState.fields array, which represents all block fields, including nested ones. Blokkli uses the 'list' property from this array to render block components instead of the props passed to . ```json [ { "name": "blocks", "entityType": "content", "entityUuid": "1", "list": [ { "uuid": "96f7fbda-04d9-4662-9a6c-6aa3bcf964f2", "bundle": "title", "props": { "title": "Hello world" } }, { "uuid": "9485812c-0ecd-4699-85b2-3a031d47a0a1", "bundle": "grid", "props": { "card": [] } } ] }, { "name": "cards", "entityType": "block", "entityUuid": "9485812c-0ecd-4699-85b2-3a031d47a0a1", "list": [ { "uuid": "96f7fbda-04d9-4662-9a6c-6aa3bcf964f2", "bundle": "card", "props": { "title": "Hello world", "text": "Lorem ipsum dolor" } }, { "uuid": "9485812c-0ecd-4699-85b2-3a031d47a0a1", "bundle": "card", "props": { "title": "A second card", "text": "Lorem ipsum dolor" } } ] } ] ``` -------------------------------- ### importFromExisting() Method Source: https://github.com/blokkli/editor/blob/main/docs/adapter/importFromExisting.md This method imports blocks from a specified source entity and field. It is invoked when a user selects a source entity and fields in the 'Import from existing' dialog and submits the form. The getImportItems() method must also be implemented for this feature to function. ```APIDOC ## importFromExisting(e: { sourceUuid: string, sourceFields: string[] }) ### Description Imports blocks from the given source entity and field. ### Method POST ### Endpoint `/backend-api/edit/:entityUuid/import-from-existing` ### Parameters #### Request Body - **sourceUuid** (string) - Required - The UUID of the source entity from which to import blocks. - **sourceFields** (string[]) - Required - The fields from which to import blocks. ### Request Example ```json { "sourceUuid": "1645ba79-8770-4a0c-a58b-163a847eea22", "sourceFields": ["field_content_blocks", "field_footer_blocks"] } ``` ### Response #### Success Response (200) (Response structure not explicitly defined in the source, but typically returns imported block data) #### Response Example (No example provided in the source) ``` -------------------------------- ### Configure Mock Props for Block Creation Source: https://github.com/blokkli/editor/blob/main/docs/define-blokkli/editor.md Provides a method to generate props for a block when created from clipboard content. The method receives text input and returns an object with block props. ```vue ``` -------------------------------- ### Implement importFromExisting() in Blokkli Edit Adapter Source: https://github.com/blokkli/editor/blob/main/docs/adapter/importFromExisting.md Implement the importFromExisting method to handle block imports from a source entity and fields. This method makes a POST request to the backend API to perform the import. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { importFromExisting: (e) => { return $fetch( `/backend-api/edit/${ctx.value.entityUuid}/import-from-existing`, { method: 'post', body: { // The UUID of the source entity from which to import blocks. sourceUuid: e.sourceUuid, // e.g. "1645ba79-8770-4a0c-a58b-163a847eea22" // The fields from which to import blocks. sourceFields: e.sourceFields, // e.g. ["field_content_blocks", "field_footer_blocks"] }, }, ) }, } }) ``` -------------------------------- ### Select Filter Example Source: https://github.com/blokkli/editor/blob/main/docs/adapter/mediaLibraryGetResults.md Defines a select dropdown filter. The selected value will be a string corresponding to one of the option keys. ```json { "type": "select", "label": "Media type", "options": { "image": "Image", "video": "Video", "document": "Document" } } ``` -------------------------------- ### Implement `updateOptions()`, `duplicateBlocks()`, and `publish()` Adapter Methods Source: https://context7.com/blokkli/editor/llms.txt Provides methods for updating block options in a batched manner, duplicating blocks while preserving order, and publishing all changes to persist mutations and exit edit mode. ```typescript export default defineBlokkliEditAdapter((ctx) => { return { updateOptions: (items) => // items: Array<{ uuid: string; key: string; value: string }> // e.g. [{ uuid: 'abc', key: 'buttonType', value: 'secondary' }] $fetch(`/api/edit/${ctx.value.entityUuid}/update-options`, { method: 'POST', body: { items }, }), duplicateBlocks: (uuids: string[]) => // Duplicates preserve ordering: [A][B][C] → [A][B][C][A][B][C] $fetch(`/api/edit/${ctx.value.entityUuid}/duplicate-blocks`, { method: 'POST', body: { uuids }, }), publish: () => // Persists all mutations and removes the edit state. $fetch(`/api/edit/${ctx.value.entityUuid}/publish`, { method: 'POST', }), } }) ``` -------------------------------- ### Checkboxes Filter Example Source: https://github.com/blokkli/editor/blob/main/docs/adapter/mediaLibraryGetResults.md Defines a filter with multiple checkboxes. The selected value will be an array of strings representing the chosen options. ```json { "type": "checkboxes", "label": "Tags", "options": { "promoted": "Promoted", "marketing": "Marketing", "mood": "Mood", "stockPhoto": "Stock photo" } } ``` -------------------------------- ### Show Options Based on Other Option Values Source: https://github.com/blokkli/editor/blob/main/docs/define-blokkli/editor.md This example demonstrates using determineVisibleOptions to show the 'shadowSize' option only when the 'showAsBox' checkbox is checked. ```vue ``` -------------------------------- ### Implement getGridMarkup() in Blokkli Edit Adapter Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getGridMarkup.md This method should return the HTML markup to display the grid overlay in the editor. It is called when the user enables the "Grid" view overlay. The resulting markup will be rendered in a div that is a child of ``. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { getGridMarkup: () => { return `
${Array(12) .fill('
') .join('')}
` }, } }) ``` -------------------------------- ### Define Transformation Plugins with getTransformPlugins() Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getTransformPlugins.md Implement this method to return an array of available transformation plugins. Each plugin defines its ID, label, applicable block bundles, target block bundles, and the minimum/maximum number of blocks it can transform. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { getTransformPlugins: () => { return Promise.resolve([ // Example of a transformation that merges two or more text blocks. { // The plugin ID. id: 'merge_texts', // The label of the transformation displayed in the editor. label: 'Merge Texts', // The array of block bundles for which this transformation may apply. bundles: ['text'], // The array of block bundles that this transformation can produce. targetBundles: ['text'], // The minimum amount of blocks required. min: 2, // The maximum amount of blocks that can be transformed. max: -1, }, // Example of a transformation that fixes spelling mistakes in text blocks. { id: 'spellcheck', label: 'Fix spelling mistakes', bundles: ['text'], targetBundles: ['text'], min: 1, max: -1, }, ]) }, } }) ``` -------------------------------- ### getAllBundles() Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getAllBundles.md This method should return all generally available block bundle definitions. It's expected to return an array of `BlockBundleDefinition` objects. ```APIDOC ## getAllBundles() ### Description This method should return all generally available block bundle definitions. It's expected to return an array of `BlockBundleDefinition` objects. ### Method GET (conceptual) ### Endpoint N/A (SDK method) ### Response #### Success Response - **bundles** (Array) - An array of block bundle definitions. ### Response Example ```json [ { "id": "card", "label": "Card", "description": "A block that renders a card with a title, text and a link.", "allowReusable": true, "isTranslatable": true }, { "id": "horizontal_rule", "label": "Horizontal Rule", "description": "A block that renders a simple horizontal rule to separate content.", "allowReusable": false, "isTranslatable": false } ] ``` ``` -------------------------------- ### Implement `moveBlock()` and `deleteBlocks()` Adapter Methods Source: https://context7.com/blokkli/editor/llms.txt Handles block reordering via drag-and-drop (`moveBlock`) and deletion of single or multiple blocks (`deleteBlocks`). Both methods use POST requests to the API. ```typescript export default defineBlokkliEditAdapter((ctx) => { return { moveBlock: (e) => $fetch(`/api/edit/${ctx.value.entityUuid}/move-block`, { method: 'POST', body: { uuid: e.item.uuid, entityType: e.host.type, entityUuid: e.host.uuid, fieldName: e.host.fieldName, preceedingUuid: e.afterUuid, // undefined = move to start of field }, }), deleteBlocks: (uuids: string[]) => $fetch(`/api/edit/${ctx.value.entityUuid}/delete-blocks`, { method: 'POST', body: { uuids }, }), } }) ``` -------------------------------- ### Disable Features Based on Context Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getDisabledFeatures.md Implement getDisabledFeatures to return an array of feature names to disable. This example disables the 'comments' feature when editing entities of type 'product'. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { getDisabledFeatures: () => { if (ctx.value.entityType === 'product') { return Promise.resolve(['comments']) } return Promise.resolve([]) }, } }) ``` -------------------------------- ### Implement `addNewBlock()` Adapter Method Source: https://context7.com/blokkli/editor/llms.txt Handles the addition of new blocks to the page. It persists the block in the backend and returns the updated state. Requires a POST request to the API. ```typescript export default defineBlokkliEditAdapter((ctx) => { return { addNewBlock: (e) => $fetch(`/api/edit/${ctx.value.entityUuid}/add-block`, { method: 'POST', body: { bundle: e.type, // e.g. 'card' entityType: e.host.type, // parent entity type entityUuid: e.host.uuid, // parent entity UUID fieldName: e.host.fieldName, // e.g. 'field_content' preceedingUuid: e.afterUuid, // undefined = insert at index 0 }, }), } }) ``` -------------------------------- ### Implement getLibraryItems() in Blokkli Edit Adapter Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getLibraryItems.md This snippet shows how to implement the getLibraryItems method within a Blokkli edit adapter. It defines a list of library items and filters them based on the provided bundles. The method returns a Promise resolving to the filtered items. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' import type { LibraryItem } from '#blokkli/types' export default defineBlokkliEditAdapter((ctx) => { return { getLibraryItems: (bundles: string[]) => { const items: LibraryItem[] = [ { // The UUID of the library item. uuid: 'e011fd53-b083-4db0-a4aa-26c3602916f8', // The label of the library item. label: 'CTA Button for Newsletter', // The bundle of the reusable block. bundle: 'link', // The FieldListItem of the reusable block. The data is used to render a preview of the block. item: { uuid: '47f0bf41-bd49-47c2-a2c4-145f80abe161', bundle: 'link', props: { href: '/subscribe-now', title: 'Subscribe to our newsletter', }, }, }, { uuid: '4e7ac454-2b6b-4c45-a01c-34abdd52b792', label: 'Contact Card', bundle: 'card', item: { uuid: '3ce777ca-70a5-48fb-b220-7ac2ab052516', bundle: 'card', props: { title: 'Contact us now', text: 'Need help? We are here to support.', icon: 'phone', }, }, }, ] return Promise.resolve(items.filter((v) => bundles.includes(v.bundle))) }, } }) ``` -------------------------------- ### Define Block Options in Vue Component Source: https://github.com/blokkli/editor/blob/main/docs/data-structure/options.md Define available options for a block component using the `options` property within `defineBlokkli`. This example shows a 'size' option for a horizontal rule block. ```vue ``` -------------------------------- ### Configure Built-in Global Options in Blokkli Source: https://context7.com/blokkli/editor/llms.txt Use 'bkVisibleLanguages' to control block visibility per language or 'bkHiddenGlobally' to hide a block in all languages. These options are available without adapter configuration. ```vue ``` -------------------------------- ### getDisabledFeatures() Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getDisabledFeatures.md This method is called to determine which features should be disabled at runtime. You can use this to disable certain features based on the current context. For example, disable the `comments` feature when editing product detail pages. ```APIDOC ## getDisabledFeatures() ### Description This method is called to determine which features should be disabled at runtime. You can use this to disable certain features based on the current context. For example, disable the `comments` feature when editing product detail pages. ### Method Signature `getDisabledFeatures(): Promise` ### Return Value A promise that resolves to an array of strings, where each string is the name of a feature to be disabled. ``` -------------------------------- ### getLastChanged() Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getLastChanged.md Returns the timestamp of when the host entity was last edited. This method is called when the edit state is being previewed. When the timestamp changes, the `` will call the [loadState()](/adapter/loadState) method to get the updated state. ```APIDOC ## getLastChanged() ### Description Returns the timestamp (as a Unix epoch timestamp in seconds) of when the host entity has been last edited. ### Method Signature `getLastChanged(): Promise` ### Returns A Promise that resolves to a number representing the Unix epoch timestamp (in seconds) of the last edit. ### Example ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { getLastChanged: () => { return Promise.resolve( // Timestamp of when the state was last edited (as seconds since UNIX epoch). 1706109810, ) }, } }) ``` ``` -------------------------------- ### assistantGetResults() Source: https://github.com/blokkli/editor/blob/main/docs/adapter/assistantGetResults.md This method makes a request to an AI assistant with a given prompt and context, returning the generated text. It is called when a user initiates the 'Add with AI Assistant' action, provides a prompt, and clicks 'Generate'. ```APIDOC ## assistantGetResults() ### Description This method should make a request to an AI assistant with the given prompt and context and return the generated text from said AI assistant. The method is called when the user drag and drops the "Add with AI Assitant" action in a field, writes their prompt in the assistant sidebar pane and clicks on "Generate". ### Method POST ### Endpoint /api/gpt ### Request Body - **prompt** (string) - Required - The prompt to send to the AI assistant. ### Response #### Success Response (200) - **text** (string) - The generated text from the AI assistant. ### Request Example ```json { "prompt": "Your prompt here" } ``` ### Response Example ```json { "text": "Generated text from AI" } ``` ``` -------------------------------- ### getTransformPlugins() Method Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getTransformPlugins.md This method should return the possible transformation plugins available. The return value should be an array of `TransformPlugin` objects. The editor uses this information to allow the users to transform one or more blocks. For this feature to work, the applyTransformPlugin() method must also be implemented. ```APIDOC ## getTransformPlugins() ### Description Returns an array of available transformation plugins. These plugins are used by the editor to enable users to transform one or more blocks. The `applyTransformPlugin()` method must also be implemented for this feature to function. ### Method Signature `getTransformPlugins(): Promise` ### Return Value - `Promise`: A promise that resolves to an array of `TransformPlugin` objects. ### TransformPlugin Object Structure - **id** (string): The unique identifier for the transformation plugin. - **label** (string): The human-readable label for the transformation, displayed in the editor. - **bundles** (string[]): An array of block bundle names for which this transformation is applicable. - **targetBundles** (string[]): An array of block bundle names that this transformation can produce. - **min** (number): The minimum number of blocks required for the transformation. - **max** (number): The maximum number of blocks that can be transformed (-1 indicates no limit). ### Example Usage ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { getTransformPlugins: () => { return Promise.resolve([ // Example of a transformation that merges two or more text blocks. { // The plugin ID. id: 'merge_texts', // The label of the transformation displayed in the editor. label: 'Merge Texts', // The array of block bundles for which this transformation may apply. bundles: ['text'], // The array of block bundles that this transformation can produce. targetBundles: ['text'], // The minimum amount of blocks required. min: 2, // The maximum amount of blocks that can be transformed. max: -1, }, // Example of a transformation that fixes spelling mistakes in text blocks. { id: 'spellcheck', label: 'Fix spelling mistakes', bundles: ['text'], targetBundles: ['text'], min: 1, max: -1, }, ]) }, } }) ``` ``` -------------------------------- ### Provide Option Values in Page Component Source: https://github.com/blokkli/editor/blob/main/docs/data-structure/options.md Pass runtime values for block options using the `options` property on the block item. This example sets the 'size' option to 'large' for a horizontal rule block. ```vue ``` -------------------------------- ### Implement addLibraryItem in Blokkli Edit Adapter Source: https://github.com/blokkli/editor/blob/main/docs/adapter/addLibraryItem.md This snippet shows how to implement the addLibraryItem function within the Blokkli edit adapter. It makes a POST request to a backend API to add the library item, including details about the item and its placement. ```typescript import { defineBlokkliEditAdapter, AddReusableItemEvent, } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { addLibraryItem: (e: AddReusableItemEvent) => { return $fetch( `/backend-api/edit/${ctx.value.entityUuid}/add-library-item`, { method: 'post', body: { // The UUID of the library item being added. uuid: e.libraryItemUuid, // The parent entity type where the block is being added. // Could be the entity type of the or in case // of nested blocks, the entity type of the block. entityType: e.host.type, entityUuid: e.host.uuid, // The field name where the block is added. fieldName: e.host.fieldName, // The UUID of the block that should be before the new one. // If undefined, the block should be moved to index 0 of the // field list. preceedingUuid: e.afterUuid, }, }, ) }, } }) ``` -------------------------------- ### Vue Component with Editable Field Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getEditableFieldConfig.md Example of a Vue component defining an editable field using the v-blokkli-editable directive. The directive's argument 'field_title' must match the 'name' property in the adapter's configuration. ```vue ``` -------------------------------- ### Root Component with Nested Blocks Source: https://github.com/blokkli/editor/blob/main/docs/data-structure/nested-blocks.md Example of a root component defining a list of blocks, including a 'grid' block that contains nested 'card' blocks. Ensure the data structure correctly defines the 'bundle' and 'props' for each block. ```vue ``` -------------------------------- ### Implement takeOwnership() in Blokkli Edit Adapter Source: https://github.com/blokkli/editor/blob/main/docs/adapter/takeOwnership.md Implement the takeOwnership method to make a POST request to the backend to claim ownership of the current edit state. Ensure the backend API endpoint is correctly specified. This method should be called when a user clicks the 'take ownership' button. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { takeOwnership: () => { return $fetch( `/backend-api/edit/${ctx.value.entityUuid}/take-ownership`, { method: 'post', }, ) }, } }) ``` -------------------------------- ### Blokkli Edit Adapter Configuration Source: https://github.com/blokkli/editor/blob/main/docs/adapter/getEditableFieldConfig.md Example of a Blokkli edit adapter defining the getEditableFieldConfig method. This configuration specifies that the 'field_title' is an editable field within a 'block' entity of bundle 'title', with the label 'Title' displayed in the editor. ```typescript import { defineBlokkliEditAdapter } from '#blokkli/adapter' export default defineBlokkliEditAdapter((ctx) => { return { getEditableFieldConfig: () => { return Promise.resolve([ { // Same name as defined in v-blokkli-editable name: 'field_title', // Since the editable field is in the block, the entity type // is "block". entityType: 'block', // The bundle of the block. entityBundle: 'title', // The label displayed in the editor. label: 'Title', }, ]) }, } }) ```