新的 ProseMirror 编辑器未插入自定义字段

您好!

我们在事件自定义标签和新的 WYSIWYG ProseMirror 编辑器方面遇到一个问题:从事件表单填充的自定义字段未出现在生成的字符串中。与 Markdown 编辑器相比,它仍然像以前一样工作。

复现步骤:

  1. 启用 Discourse Calendar 插件
  2. 在插件配置中添加一个自定义字段
  3. 打开新帖子的表单
  4. 选择 ProseMirror 编辑器
  5. 创建一个带有自定义字段值的事件(选项 > 创建事件)
  6. 验证事件
  7. 切换到 Markdown 编辑器

发生的情况

自定义字段在 [event] 标签中缺失。

预期情况

自定义字段应存在于 [event] 标签中。

备注

当执行相同操作但从 Markdown 编辑器而不是 ProseMirror 开始时,自定义字段存在于 [event] 标签中。

2 个赞

我对toolbarEvent在验证新事件时发生的情况进行了一些调查:addText()方法似乎在两种情况下都收到了正确的标记:

[event start="2025-09-26 18:00" status="public" timezone="Europe/Paris" end="2025-09-26 19:00" cf_1="abcd"]\n[/event]

如果这有帮助的话,这里是重现问题的 QUnit 测试:

// plugins/discourse-calendar/test/acceptance/post-event-builder-custom-tags-test.js
import { click, find, visit, fillIn } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import { i18n } from "discourse-i18n";

acceptance("Discourse Calendar - New event form with custom fields", function (needs) {
  needs.user({ admin: true, can_create_discourse_post_event: true });
  needs.settings({
    discourse_local_dates_enabled: true,
    calendar_enabled: true,
    discourse_post_event_enabled: true,
    discourse_post_event_allowed_on_groups: "",
    discourse_post_event_allowed_custom_fields: "my_custom_field",
    coopaname_integration_enabled: false,
  });

  test("filling the form with MD editor fills the custom fields", async function (assert) {
    await ensureEventTagHasFields(assert, 'md');
  });

  test("filling the form with WYSIWYG editor fills the custom fields", async function (assert) {
    await ensureEventTagHasFields(assert, 'wysiwyg');
  });
});

async function ensureEventTagHasFields(assert, editorType) {
  await visit("/");
  await click('#create-topic');
  const categoryChooser = selectKit(".category-chooser");
  await categoryChooser.expand();
  await categoryChooser.selectRowByValue(2);

  await switchEditorTo(editorType);

  await click(".toolbar-menu__options-trigger");
  await click(`button[title='${i18n("discourse_post_event.builder_modal.attach")}']`);
  await fillIn('input.custom-field-input', 'some value')
  await click('.d-modal__footer > button');

  await switchEditorTo('md');

  const fields = ['start', 'status', 'timezone', 'myCustomField'];
  const content = await find(".d-editor-input").value;

  fields.forEach((field) => {
    assert.true(content.includes(`${field}="`), `${field} is present in event tag`);
  });
}

async function switchEditorTo(type) {
  const editorSwitch = find('button.composer-toggle-switch');
  const isInMarkdown = editorSwitch.attributes['aria-checked'].value === 'false';
  if (isInMarkdown && type === 'wysiwyg' || !isInMarkdown && type === 'md') {
    await click(editorSwitch);
  }
}

当然,请删除测试中的这行 coopaname_integration_enabled: false, :upside_down_face:

我找不到具有相同功能的另一个插件,因此很难找出问题所在。

在验证表单时,它会调用 this.args.model.toolbarEvent.addText() 并传入正确的文本。

通过几个 console.log(TM),我找到了 text-manipulation.js#addText(),其中调用了 this.convertFromMarkdown(text)。问题似乎出在这里:存在一个强制执行的模式,其中不包含自定义字段。

仍在挖掘中 :shovel:

问题出在编辑器扩展 discourse-calendar/assets/javascripts/discourse/pre-initializers/rich-editor-extension.jsconvertFromMarkdown() 使用的属性列表在 EVENT_ATTRIBUTES 常量中定义。当将自定义字段添加到列表时,它就可以工作。

const EVENT_ATTRIBUTES = {
  // ...
  chatChannelId: { default: null },
  myCustomField: {default: null}
};

此文件中没有关于自定义字段的内容;我不知道如何用所有自定义字段来完成这个常量;该扩展似乎在早期注册。

欢迎任何建议,这使得插件在无法禁用的新编辑器下无法使用,因此我们被困在 Discourse 3.4。

目前富文本编辑器确实不支持自定义字段。我们将研究最佳的前进方向。

可以——如果你是管理员,可以通过控制台设置 SiteSettings.rich_editor = false,在类似这种情况下,它仍然是最后的手段。

1 个赞

感谢您的回复,我们暂时禁用编辑器。