guide编辑器包

# 概述

编辑器包是预配置的、可直接使用的 CKEditor 5 的源代码,它经过压缩并构建为单个文件。要使用 文档存储导入和导出连接优化 功能,您需要将应用程序中的编辑器文件的确切副本上传到 CKEditor 云服务服务器。

CKEditor 云服务使用您的编辑器包将协作会话中的操作转换为数据。因此,CKEditor 云服务可以确保用户之间以及存储数据之间的数据一致性。此外,如果您的编辑器包使用了一些可以输出自定义数据的自定义插件,CKEditor 云服务将能够正确处理这些数据。

每当您更改编辑器包或其配置中的内容时,也应该在 CKEditor 云服务服务器上更新它。如果用户使用的编辑器版本与上传到服务器的版本不同,可能会导致数据丢失,甚至编辑器崩溃。

# 构建编辑器包

首先,您需要创建一个编辑器包。您可以按照我们的分步 编辑器捆绑指南 操作,或者使用现成的 编辑器包示例

# 上传编辑器包

如果您已经构建了满足 要求 的编辑器,您可以将其与编辑器配置一起上传到 CKEditor 云服务。编辑器上传过程需要使用 CKEditor 云服务 REST API 的 POST /editors 方法。

对 CKEditor 云服务 REST API 发出的每个请求都需要包含额外的标头:X-CS-TimestampX-CS-Signature。有关更多详细信息,请参阅 请求签名 指南。

三个参数传递到此方法的正文

  • bundle – 您的压缩编辑器代码,以字符串形式传递。
  • config – 这是 CKEditor 云服务中编辑器将使用的编辑器配置。这应该与您的应用程序中使用的配置相同,尤其是在它可以改变数据输出时。
  • test_data – 这是您上传到 CKEditor 云服务服务器的编辑器生成的真实文档内容。它有助于检测您的任何自定义插件是否错误地修改了文档内容,或者是否传递了无效的配置。此参数是可选的,但强烈建议使用它。您应该确保您的测试数据是使用您实现的所有自定义插件创建的。

上传请求的正文应如下所示

{
    "bundle": "the content of editor bundle file",
    "config": {
        "cloudServices": {
            "bundleVersion": "unique_editor_bundle_version"
        },
        "removePlugins": [ "myCustomAutoSavePlugin" ],
        ... other config options
    },
    "test_data": "<p>example output from your editor</p>"
}

config.cloudServices 对象中的 bundleVersion 属性是必需的。

请记住,上传的编辑器包仅在分配给它的环境中可用。如果您将相同的编辑器用于不同的环境,则必须为每个环境单独上传。

# 编辑器配置

上传过程中设置的 bundleVersion 属性充当唯一的构建标识符。它告诉 CKEditor 云服务在用户启动协作会话时应该使用哪个编辑器。您需要确保您的应用程序中的编辑器配置也具有 bundleVersion 属性,并且其值与上传到 CKEditor 云服务服务器的编辑器相匹配。具有设置 bundleVersion 的示例编辑器配置如下所示

return CKEditorCS
    .create( document.querySelector( '.collaboration-demo__editable' ), {
        cloudServices: {
            tokenUrl: 'TOKEN_URL',
            uploadUrl: 'UPLOAD_URL',
            webSocketUrl: 'WEBSOCKET_URL',
            bundleVersion: 'editor-1.0.0'
        },
        collaboration: {
            channelId: 'CHANNEL_ID'
        },
        toolbar: [
            // Toolbar items
        ],
        // Other config options
    } );

上传到 CKEditor 云服务服务器的编辑器配置应采用 JSON 格式。因此,在某些情况下,需要在发送之前修改 config 对象

  • 需要 DOM 元素的特定插件的属性应设置为 null
  • 通用 HTML 支持 配置中的正则表达式值应转换为字符串,例如 "/.*/"

# 多根编辑器构建

对于 多根 编辑器构建,上传请求主体需要一个额外的 is_multi_root_editor 字段,该字段设置为 true。该字段表示上传的编辑器是多根构建。此外,test_data 属性被期望是一个字符串化的 JSON 结构,其中键是根名称,值是特定根的 HTML 内容。此外,如果您想使用根的属性,则必须在编辑器配置中为每个根提供示例值。

{
    "bundle": "the content of a multi-root editor bundle file",
    "config": {
        "cloudServices": {
            "bundleVersion": "unique_multiroot_editor_bundle_version"
        },
        "removePlugins": [
            "myCustomAutoSavePlugin"
        ],
        "rootsAttributes": {
            "main": {
            "order": 1
            }
        },
        ... other config options
    },
    "test_data": "{\"header\":\"<p>Multi-root document header.</p>\",\"footer\":\"<p>Multi-root document footer.</p>\"}",
    "is_multi_root_editor": true
}

# 示例

请遵循以下示例,了解如何将编辑器包正确上传到 CKEditor 云服务。此示例使用 Node.js 和 npm,因此需要安装这些工具。它还假设您已经 构建了编辑器包。此示例将继续使用上一个示例中的文件。

  1. 在您的终端中,使用 cd 命令进入解压缩的文件夹,并使用 npm i axios 命令安装 axios 包。

  2. 在解压缩的文件夹中创建一个新的 upload.js 文件,内容如下

const crypto = require( 'crypto' );
const fs = require( 'fs' );
const path = require( 'path' );
const axios = require( 'axios' );

// Update with your credentials and application endpoint
const environmentId = 'txQ9sTfqmXUyWU5LmDbr';
const apiSecret = '4zZBCQoPfRZ7Rr7TEnGAuRsGgbfF58Eg0PA8xcLD2kvPhjGjy4VGgB8k0hXn';
const applicationEndpoint = 'https://33333.cke-cs.com';

const apiEndpoint = `${ applicationEndpoint }/api/v5/${ environmentId }/editors/`;
const editorBundle = fs.readFileSync( path.resolve( './build/ckeditor.js' ) );

const body = {
    bundle: editorBundle.toString(),
    config: {
        cloudServices: {
            bundleVersion: 'editor-1.0.0' // Set a unique name for the uploaded bundle
        },
        toolbar: [
            // Toolbar items
        ],
        // Other config options
    }
};

const CSTimestamp = Date.now();
const axiosConfig = {
    headers: {
        'X-CS-Timestamp': CSTimestamp,
        'X-CS-Signature': generateSignature( apiSecret, 'POST', apiEndpoint, CSTimestamp, body )
    }
};

axios.post( apiEndpoint, body, axiosConfig )
    .then( response => {
        console.log ( response.status );
    } ).catch( error => {
        console.log( error.message );
        console.log( error.response.data );
    } );

function generateSignature( apiSecret, method, uri, timestamp, body ) {
    const url = new URL( uri );
    const path = url.pathname + url.search;
    const hmac = crypto.createHmac( 'SHA256', apiSecret );

    hmac.update( `${ method.toUpperCase() }${ path }${ timestamp }` );

    if ( body ) {
        hmac.update( Buffer.from( JSON.stringify( body ) ) );
    }

    return hmac.digest( 'hex' );
}

使用 node upload.js 命令运行上述代码。

您应该在控制台中看到 201 状态代码。您可以再次运行 node upload.js 以确保包已经上传。在这种情况下,您将收到 409 错误,并显示消息 Editor editor-1.0.0 already exists

# 更新编辑器包

如上例所示,无法覆盖 CKEditor 云服务服务器上的编辑器包。但是,您可能会遇到需要重新构建编辑器的场景,例如在添加新插件、更新 CKEditor 5 版本或修复自定义插件中的错误时。您应该按照以下步骤开始使用新的编辑器包

  1. 使用对配置或插件的必要更改重新构建您的编辑器。
  2. 使用新的 bundleVersion 值上传新的编辑器包,该值对于您的环境是新且唯一的。
  3. 将您的应用程序中的编辑器配置中的 bundleVersion 更新为与步骤 2 中的新值匹配。
  4. 等待活动协作会话 自动删除,或者使用 CKEditor 云服务 REST API 的 DELETE /collaborations/{document_id} 手动删除它们。
  5. 在您的新编辑器中打开文档。

使用特定 bundleVersion 启动的协作会话只能由具有相同 bundleVersion 值的编辑器打开。因此,您无法使用新编辑器连接到以前编辑的文档,而无需重新初始化协作会话(步骤 4 和 5)。

为了确保数据一致性,您应该在每次编辑器发生更改时在 CKEditor 云服务上更新编辑器包。当更改与转换或数据输出相关时,这一点尤其重要。