Report an issue

guide注释自定义模板

自定义模板介于默认 UI 和完全自定义的 UI 之间。

# 工作原理

此解决方案允许您更改评论和建议注释的 HTML 结构。因此,您可以例如

  • 添加新的 CSS 类或 HTML 元素以实现更复杂的样式。
  • 重新排列注释视图。
  • 添加与您的自定义功能相关联的新 UI 元素。
  • 删除 UI 元素。

强烈建议您在继续之前熟悉 CKEditor 5 UI 库 API框架/架构/UI 库 指南。

以下示例基于包含协作功能的工作编辑器设置。我们强烈建议您根据 评论功能集成 指南准备好您的设置,然后再继续执行任何操作。

# 评论和建议的视图

CKEditor 5 协作功能默认使用的视图类是

这些闭源类由 npm 上的 ckeditor5-premium-features 包导出(了解更多)。

强烈建议您在继续之前熟悉 评论视图评论线程视图建议视图 的 API 文档。

# 更改视图模板

要使用自定义视图模板,您需要

  1. 通过扩展默认视图类来创建新的视图类。
  2. 通过覆盖 getTemplate() 方法来提供(或扩展)模板。
  3. 通过编辑器配置设置您的自定义视图类。我们建议在默认配置中设置它。

创建自定义视图

// ...

import { CommentView } from 'ckeditor5-premium-features';

// Create a new comment view class basing on the default view.
class MyCommentView extends CommentView {
    // Overwrite the method to provide a custom template.
    getTemplate() {
        return {
            // Provide the template definition here.
            // ...
        };
    }
}

// ...

在编辑器配置中使用自定义视图

// ...

const editorConfig = {
    // ...

    comments: {
        CommentView: MyCommentView
    },

    // ...
};

ClassicEditor.create(document.querySelector('#editor'), editorConfig);

自定义 评论建议 线程视图可以通过类似的方式设置

// ...

const editorConfig = {
    // ...

    comments: {
        CommentThreadView: MyCommentThreadView,
    },

    trackChanges: {
        SuggestionThreadView: MySuggestionThreadView
    },

    // ...
};

ClassicEditor.create(document.querySelector('#editor'), editorConfig);

# 示例:添加新按钮

以下是如何提供一个简单的自定义功能的示例,该功能需要创建新的 UI 元素和额外的样式。

提议的功能应允许将一些评论标记为重要。重要的评论在右侧应该有一个黄色边框。

要实现此功能,您需要

  • 一个 CSS 类来更改重要评论的边框。
  • 一个按钮来切换评论模型状态。
  • 模型状态和视图模板之间的集成。

# 重要评论的样式

这一步很简单。将以下样式添加到项目中的 style.css 文件中

/* style.css */

/* Yellow border for an important comment. */
.ck-comment--important {
    border-right: 3px solid hsl( 55, 98%, 48% );
}

# 创建按钮并将其添加到模板

在这一步中,您将向模板添加一些新元素。

请记住,您不需要覆盖整个模板。相反,您可以扩展它。

// main.js

// ...

import { CommentView } from 'ckeditor5-premium-features';
import { LateFocusButtonView } from 'ckeditor5-premium-features';

export default class ImportantCommentView extends CommentView {
    constructor( ...args ) {
        super( ...args );

        // Bind `isImportant` value to comment model custom attributes.
        this.bind( 'isImportant' ).to( this._model, 'attributes', attributes => !!attributes.isImportant );
    }

    getTemplate() {
        // Use the original method to get the default template.
        // The default template definition structure is described in the comment view API.
        const templateDefinition = super.getTemplate();

        // If `isImportant` is `true`, add the `ck-comment--important` class to the template.
        templateDefinition.children[ 0 ].attributes.class.push( this.bindTemplate.if( 'isImportant', 'ck-comment--important' ) );

        // Add the new button next to the other comment buttons (edit and remove).
        templateDefinition.children[ 0 ].children[ 1 ].children[ 1 ].children.add( this._createImportantButtonView(), 0 );

        return templateDefinition;
    }

    _createImportantButtonView() {
        // Create a new button view.
        const button = new LateFocusButtonView( this.locale );

        // Create an icon for the button view.
        const starIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M15.22 18.36c.18-.02.35-.1.46-.25a.6.6 0 00.11-.5l-1.12-5.32 4.12-3.66a.6.6 0 00.18-.65.63.63 0 00-.54-.42l-5.54-.6L10.58 2a.64.64 0 00-.58-.37.64.64 0 00-.58.37l-2.3 4.94-5.55.6a.63.63 0 00-.54.43.6.6 0 00.18.65l4.12 3.66-1.12 5.32c-.05.24.04.49.25.63.2.14.47.16.68.04L10 15.59l4.86 2.69c.1.06.23.09.36.08zm-.96-1.83l-3.95-2.19a.65.65 0 00-.62 0l-3.95 2.19.91-4.33a.6.6 0 00-.2-.58L3.1 8.64l4.51-.5a.64.64 0 00.51-.36L10 3.76l1.88 4.02c.09.2.28.34.5.36l4.52.5-3.35 2.98a.6.6 0 00-.2.58l.91 4.33z"/></svg>';

        // Use the localization service.
        // The feature will be translatable.
        const t = this.locale.t;

        // Set the label and the icon for the button.
        button.set( {
            icon: starIcon,
            isToggleable: true,
            tooltip: t( 'Important' ),
            withText: true
        } );

        // Add a class to the button to style it.
        button.extendTemplate( {
            attributes: {
                class: 'ck-button-important'
            }
        } );

        // The button should be enabled if the comment model is not in the read-only mode.
        // The same setting is used for other comment buttons.
        button.bind( 'isEnabled' ).to( this._model, 'isReadOnly', value => !value );

        // The button should be hidden if the comment is not editable
        // (this is true when the current user is not the comment author).
        // The same setting is used for the other comment buttons.
        button.bind( 'isVisible' ).to( this._model, 'isEditable' );

        // When the button is clicked, change the comment state in the comment model.
        // The `attributes.isImportant` value will be available together with other comment data.
        button.on( 'execute', () => {
            this._model.setAttribute( 'isImportant', !this._model.attributes.isImportant );
        } );

        return button;
    }
}

// ...

# 启用自定义视图

自定义视图将在编辑器配置中启用,如 前面所述

// main.js

// ...

const editorConfig = {
    // ...

    comments: {
        CommentView: ImportantCommentView,
        editorConfig: {
            plugins: [ Essentials, Paragraph, Bold, Italic ]
        }
    }
};

ClassicEditor.create(document.querySelector('#editor'), editorConfig);

# 实时演示