首页 > 解决方案 > 用户保存/提交时如何添加/更新片段字段

问题描述

在 ApostropheCMS 应用程序中,我们有一个片段类型“书”。前端用户可以从 CMS 更新文章中声明的字段index.js

我们需要在用户保存后动态添加或更新一个字段,即一个citations字段。我们使用Citation.js根据编辑在 CMS 中输入的内容生成 MLA、Chicago 等引文。

我们不想让这个字段在 CMS 中可见,因为它总是需要被 Citation.js 生成的结果覆盖。(如果有办法添加一个字段并将其从 CMS 中隐藏,那将是一个很好的解决方案!)。

我们当前的想法是在保存时添加字段(如果缺少)或更新(如果存在):

(mostly) pseudo code
self.on('apostrophe-docs:afterSave', 'updateBook', async (req) => {
  const { piece } = req;

  // fetch citations
  const citations = { ... };

  // create update piece
  const updated = _.cloneDeep(piece);
  updated.citations = citations;

  // check if citations field already present
  if (!('citations' in piece)) {
    // add citations field

    // should method be different if field doesnt exist yet?
    self.update(req, updated);

  } else {
    // check when citations were last updated to ensure enough time diff to update

    // update citations field if all is well
    self.update(req, updated);
  }
});

正如预期的那样,这当前会创建一个无限循环,因为'apostrophe-docs:afterSave'在调用self.update.

欢迎就如何实现这一目标提出任何建议。

标签: node.jsapostrophe-cms

解决方案


beforeSave更有可能是您应该使用的。.update()如果您只是在将信息实际保存到数据库之前将信息添加到片段中,则无需调用。

对于有关可见性的问题,您无需将文档属性添加到片段模式即可保存它们。字段需要位于片段模式中才能在 UI 中编辑或查看(即使设置为readOnly: true)。

因此,在构造步骤中,您可以添加如下内容:

self.on('books:beforeSave', 'populateCitation');

self.populateCitation = function (req, piece, options) {
  // Being extra safe here.
  if (piece.type !== 'book') {
    return;
  }
  // Let's pretend `bookInfo` 
  if (piece.bookInfo) {
    // `getCitation` would be a method using Citation.js
    const citationInfo = getCitation(piece.bookInfo);
    piece.citation = citationInfo;
  }
};

然后,您可以citation在代码中读取文档上的属性,并且(我很确定)也可以在模板中读取属性(如果存在)(确保在打印之前在模板中检查它)。


推荐阅读