我设法将一个带有css类按钮的块引用添加到了draftail (下面的代码),它工作得很好。到目前为止,唯一的问题是,如果我尝试在编辑器中使用标准链接按钮在该块引用文本内链接到一个单词,我会得到一个JS错误(也是在下面)
我试图改编文档中的股票示例,但我猜我搞砸了一些东西。
wagtail_hooks.py中的代码
def poquote_entity_decorator(props):
"""
Draft.js ContentState to database HTML.
Converts the poquote entities into a blockquote with class tag.
"""
return DOM.create_element('blockquote', {
'class': 'pullout',
}, props['children'])
class PoQuoteEntityElementHandler(InlineEntityElementHandler):
"""
Database HTML to Draft.js ContentState.
Converts the blockquote tag into a PoQuote entity, with the right
data.
"""
mutability = 'IMMUTABLE'
def get_attribute_data(self, attrs):
return {
'poquote': attrs['class'],
}
@hooks.register('insert_editor_js')
def draftail_editor_js():
js_files = [
'wagtailadmin/js/draftail.js',
'js/draftail.js',
]
js_includes = format_html_join('\n', '<script src="{0}{1}">
</script>',
((settings.STATIC_URL, filename) for filename in js_files)
)
return js_includes
@hooks.register('register_rich_text_features')
def register_poquote_feature(features):
features.default_features.append('poquote')
"""
Registering the `poquote` feature, which uses the `POQUOTE`
Draft.js entity type,
and is stored as HTML with a `<blockquote class='pullout'>` tag.
"""
feature_name = 'poquote'
type_ = 'POQUOTE'
control = {
'type': type_,
'icon': 'icon icon-form',
'description': 'Pull Out Quote',
}
features.register_editor_plugin(
'draftail', feature_name,
draftail_features.EntityFeature(control)
)
features.register_converter_rule('contentstate', feature_name, {
# Note here that the conversion is more complicated than for
blocks and inline styles.
'from_database_format': {'blockquote[class]':
PoQuoteEntityElementHandler(type_)},
'to_database_format': {'entity_decorators': {type_:
poquote_entity_decorator}},
})
和JS
const React = window.React;
const Modifier = window.DraftJS.Modifier;
const EditorState = window.DraftJS.EditorState;
// Not a real React component – just creates the entities as soon as
it is rendered.
class PoqSource extends React.Component {
componentDidMount() {
const { editorState, entityType, onComplete } = this.props;
const content = editorState.getCurrentContent();
const selection = editorState.getSelection();
const anchorKey = selection.getAnchorKey();
const currentBlock = content.getBlockForKey(anchorKey);
const start = selection.getStartOffset();
const end = selection.getEndOffset();
const selectedText = currentBlock.getText().slice(start,
end);
// Uses the Draft.js API to create a new entity with the right
data.
const contentWithEntity =
content.createEntity(entityType.type, 'IMMUTABLE', {
poq: selectedText,
});
const entityKey = contentWithEntity.getLastCreatedEntityKey();
// We also add some text for the entity to be activated on.
const text = `${selectedText}`;
const newContent = Modifier.replaceText(content, selection,
text, null, entityKey);
const nextState = EditorState.push(editorState, newContent,
'insert-characters');
onComplete(nextState);
}
render() {
return null;
}
}
const Poq = (props) => {
const { entityKey, contentState } = props;
const data = contentState.getEntity(entityKey).getData();
return React.createElement('blockquote', {className: 'pullout'},
props.children);
};
window.draftail.registerPlugin({
type: 'POQUOTE',
source: PoqSource,
decorator: Poq,
});
错误:
vendor.js:1 TypeError: Cannot read property 'startsWith' of undefined
at h (VM7359 draftail.js:1)
at n.value (VM7359 draftail.js:1)
at commitLifeCycles (vendor.js:1)
at e (vendor.js:1)
at x (vendor.js:1)
at w (vendor.js:1)
at batchedUpdates (vendor.js:1)
at Z (vendor.js:1)
at It (vendor.js:1)
l @ vendor.js:1
vendor.js:1 Uncaught TypeError: Cannot read property 'startsWith' of
undefined
at h (VM7359 draftail.js:1)
at n.value (VM7359 draftail.js:1)
at commitLifeCycles (vendor.js:1)
at e (vendor.js:1)
at x (vendor.js:1)
at w (vendor.js:1)
at batchedUpdates (vendor.js:1)
at Z (vendor.js:1)
at It (vendor.js:1)
vendor.js:1 TypeError: Cannot read property 'startsWith' of undefined
at h (VM7359 draftail.js:1)
at n.value (VM7359 draftail.js:1)
at commitLifeCycles (vendor.js:1)
at e (vendor.js:1)
at x (vendor.js:1)
at w (vendor.js:1)
at batchedUpdates (vendor.js:1)
at Z (vendor.js:1)
at It (vendor.js:1)
l @ vendor.js:1
vendor.js:1 Uncaught TypeError: Cannot read property 'startsWith' of
undefined
at h (VM7359 draftail.js:1)
at n.value (VM7359 draftail.js:1)
at commitLifeCycles (vendor.js:1)
at e (vendor.js:1)
at x (vendor.js:1)
at w (vendor.js:1)
at batchedUpdates (vendor.js:1)
at Z (vendor.js:1)
at It (vendor.js:1)
发布于 2018-03-23 06:29:31
如果您想要的只是一个块作为<blockquote class='pullout'>my text</blockquote>
,那么有一种不需要编写JavaScript代码的更简单的方法。
首先,从official documentation中关于块的示例开始,使用blockquote:
from wagtail.admin.rich_text.converters.html_to_contentstate import BlockElementHandler
@hooks.register('register_rich_text_features')
def register_blockquote_feature(features):
"""
Registering the `blockquote` feature, which uses the `blockquote` Draft.js block type,
and is stored as HTML with a `<blockquote>` tag.
"""
feature_name = 'blockquote'
type_ = 'blockquote'
tag = 'blockquote'
control = {
'type': type_,
'label': '❝',
'description': 'Blockquote',
# Optionally, we can tell Draftail what element to use when displaying those blocks in the editor.
'element': 'blockquote',
}
features.register_editor_plugin(
'draftail', feature_name, draftail_features.BlockFeature(control)
)
features.register_converter_rule('contentstate', feature_name, {
'from_database_format': {tag: BlockElementHandler(type_)},
'to_database_format': {'block_map': {type_: tag}},
})
可以使用Draftail-block--blockquote
类编写样式以在编辑器中显示这些块。
然后,您需要调整转换器规则,以便使用pullout
类将其存储为<blockquote class='pullout'>my text</blockquote>
:
features.register_converter_rule('contentstate', feature_name, {
'from_database_format': {'blockquote[class]': BlockElementHandler(type_)},
'to_database_format': {
'block_map': {
type_: {
'element': tag,
'props': {
'class': 'pullout',
},
},
},
},
})
当然,如果您愿意,您可以使用poquote
类型和-或功能名称,而不需要使用blockquote
。
https://stackoverflow.com/questions/49302754
复制相似问题