How to add/update piece field when the user saves/commits

人盡茶涼 提交于 2021-02-10 20:50:56

问题


In an ApostropheCMS application, we have a piece type "book". The front-end users are able, from the CMS, to update fields declared in the piece's index.js.

We need to dynamically add or update a field once the user saves, namely a citations field. We use Citation.js to generate MLA, Chicago, etc. citations according to what the editor has entered in the CMS.

We don't want to make this field visible in the CMS, because it needs to always be overwritten by the Citation.js generated results. (If there is a way to add a field and hide it from the CMS, that would be a great solution!).

Our current idea is to add the field (if it's missing) or update it (if it exists) on save:

(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);
  }
});

As expected, this currently creates an infinite loop because 'apostrophe-docs:afterSave' is called after calling self.update.

  • Is there a way to pass a param to prevent that callback?
    • Otherwise, we were thinking about checking when the last update() occurred, any better suggestion?
  • Does update() not add fields that are on the piece passed to the method? Does it only care about fields defined in the index.js?

Any suggestion on how to achieve that is welcome.


回答1:


beforeSave is more likely what you should use. You won't need to call .update() if you simply add the information onto the piece before it's actually saved to the db.

To your question about visibility, you don't need to add document properties to the piece schema to be able to save them. Fields need to be in the piece schema to be edited or viewed in the UI (even if set to readOnly: true).

So in the construct step you could add something like:

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;
  }
};

You can then read the citation property on the document in code and (I'm pretty sure) in the template as well, if it is present (make sure to check for it in the template before printing).



来源:https://stackoverflow.com/questions/64850545/how-to-add-update-piece-field-when-the-user-saves-commits

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!