【发布时间】:2022-01-18 10:01:01
【问题描述】:
我可以在常规页面字段中使用标签,没有任何问题。在块内(流域内)使用标签时,UI 工作并且标签被保存但当前页面标签在管理中加载页面时不显示。 这是因为当前值不在模板中,而是在通过telepath 加载的 JSON 中。
我可以确认标签已保存并出现在传递给页面源中initBlockWidget 的数据中,但这些被忽略了。此外,如果我使用常规文本字段而不是标签小部件,我可以在管理员中看到保存的值。
这是我拥有的代码(在使用telepath 重构之前已经足够了)。
from wagtail.admin.widgets import AdminTagWidget
class TagBlock(TextBlock):
@cached_property
def field(self):
field_kwargs = {"widget": AdminTagWidget()}
field_kwargs.update(self.field_options)
return forms.CharField(**field_kwargs)
我认为我需要以某种方式完成以下链接才能使其正常工作:https://docs.wagtail.io/en/stable/reference/streamfield/widget_api.html#form-widget-client-side-api
我已经试过了:
class AdminTagWidgetAdapter(WidgetAdapter):
class Media:
js = [
"wagtailadmin/js/vendor/tag-it.js",
"js/admin/admin-tag-widget-adapter.js",
]
register(AdminTagWidgetAdapter(), AdminTagWidget)
在js/admin/admin-tag-widget-adapter.js下:
console.log("adapter"); // this shows up in the console
class BoundWidget { // copied from wagtail source code
constructor(element, name, idForLabel, initialState) {
var selector = ':input[name="' + name + '"]';
this.input = element.find(selector).addBack(selector); // find, including element itself
this.idForLabel = idForLabel;
this.setState(initialState);
}
getValue() {
return this.input.val();
}
getState() {
return this.input.val();
}
setState(state) {
this.input.val(state);
}
getTextLabel(opts) {
const val = this.getValue();
if (typeof val !== 'string') return null;
const maxLength = opts && opts.maxLength;
if (maxLength && val.length > maxLength) {
return val.substring(0, maxLength - 1) + '…';
}
return val;
}
focus() {
this.input.focus();
}
}
// my code here:
class AdminTagWidget {
constructor(html, idPattern) {
this.html = html;
this.idPattern = idPattern;
}
boundWidgetClass = BoundWidget;
render(placeholder, name, id, initialState) {
console.log("RENDER", placeholder, name, id, initialState); // this does not show
var html = this.html.replace(/__NAME__/g, name).replace(/__ID__/g, id);
var idForLabel = this.idPattern.replace(/__ID__/g, id);
var dom = $(html);
$(placeholder).replaceWith(dom);
// eslint-disable-next-line new-cap
return new this.boundWidgetClass(dom, name, idForLabel, initialState);
}
}
console.log("here") // does show in the console
// variants I've tried:
//window.telepath.register('wagtail.admin.widgets.tags.AdminTagWidget', AdminTagWidget);
//window.telepath.register('wagtail.widgets.AdminTagWidget', AdminTagWidget);
window.telepath.register('path.where.its.used.AdminTagWidget', AdminTagWidget)
我的自定义渲染方法的日志没有显示。看来我没有在window.telepath.register 中调用正确的路径,但我不知道字符串应该是什么......
我什至不确定这是否是正确的前进方向。
注意事项:
- 它适用于常规领域,问题是关于块中的标签
- 我使用的是 Wagtail 版本 2.13.2,但我也尝试过使用 2.15,没有任何区别。
- 在控制台中,我可以记录 window.telepath 并查看我的自定义小部件。它只是没有“应用于”任何东西
【问题讨论】:
标签: tags wagtail wagtail-streamfield telepath