注释自定义模板
自定义模板介于默认 UI 和完全自定义的 UI 之间。
# 工作原理
此解决方案允许您更改评论和建议注释的 HTML 结构。因此,您可以例如
- 添加新的 CSS 类或 HTML 元素以实现更复杂的样式。
- 重新排列注释视图。
- 添加与您的自定义功能相关联的新 UI 元素。
- 删除 UI 元素。
强烈建议您在继续之前熟悉 CKEditor 5 UI 库 API 和 框架/架构/UI 库 指南。
以下示例基于包含协作功能的工作编辑器设置。我们强烈建议您根据 评论功能集成 指南准备好您的设置,然后再继续执行任何操作。
# 评论和建议的视图
CKEditor 5 协作功能默认使用的视图类是
CommentThreadView
– 生成评论线程注释的 UI。CommentView
– 展示单个评论。SuggestionThreadView
– 生成建议注释的 UI。
这些闭源类由 npm 上的 ckeditor5-premium-features
包导出(了解更多)。
# 更改视图模板
要使用自定义视图模板,您需要
- 通过扩展默认视图类来创建新的视图类。
- 通过覆盖
getTemplate()
方法来提供(或扩展)模板。 - 通过编辑器配置设置您的自定义视图类。我们建议在默认配置中设置它。
创建自定义视图
// ...
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);
# 实时演示
我们每天都在努力使我们的文档保持完整。您是否发现了过时信息?是否缺少内容?请通过我们的 问题追踪器 报告。
随着 42.0.0 版本的发布,我们重写了大部分文档以反映新的导入路径和功能。感谢您的反馈,帮助我们确保文档的准确性和完整性。