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?
- Otherwise, we were thinking about checking when the last
- Does
update()
not add fields that are on the piece passed to the method? Does it only care about fields defined in theindex.js
?
Any suggestion on how to achieve that is welcome.