Reputation: 77
How to code the beforeSave() handler for the apostrophe widget? This code in the widget index.js does not work for me:
module.exports = {
extend: 'apostrophe-widgets',
label: 'My widget',
addFields: [
{
name: 'label',
type: 'string',
label: 'Caption',
required: true
}
],
construct: function(self, options) {
self.beforeSave = function(callback) {
console.log("beforeSave");
return callback();
}
}
};
When I save an instance of a widget, the log does not change. Is it possible to code your own beforeSave() handler for widgets as for pieces?
Upvotes: 2
Views: 249
Reputation: 7572
A widget is just one part of a document, and documents are saved to the database as a unit, not individual widgets. So there is no beforeSave
.
However if what you want to do is take some action each time a widget is sanitized for potential inclusion in a document that may be saved, take a look at the sanitize
method:
self.sanitize = function(req, input, callback) {
var output = self.apos.schemas.newInstance(self.schema);
var schema = self.allowedSchema(req);
output._id = self.apos.launder.id(input._id) || self.apos.utils.generateId();
return self.apos.schemas.convert(req, schema, 'form', input, output, function(err) {
if (err) {
return callback(err);
}
output.type = self.name;
return callback(null, output);
});
};
Notice how this method takes input
, which is the data the browser provided, and runs it through apos.schemas.convert
to copy only the valid data to output
. Then it sends output
to its callback.
We can use the "super pattern" to make a change at the end of this process. For instance, rich text widgets usually don't have a schema, they just have a content
property containing markup. But, they might have a schema too on some sites. So here is how the apostrophe-rich-text-widgets
module uses the "super pattern" to extend the sanitize
method to accept the additional content, without losing the ability to save schema content:
var superSanitize = self.sanitize;
self.sanitize = function(req, input, callback) {
return superSanitize(req, input, function(err, output) {
if (err) {
return callback(err);
}
output.content = sanitizeHtml(input.content, self.options.sanitizeHtml);
return callback(null, output);
});
};
Notice that:
superSanitize
. Then a new function is assigned as the method.superSanitize
is called. If it fails we deal with that first.output
is modified. Any changes you make to output
will go directly into the widget in the document, so make sure you validate any content you are accepting from input
. Browsers (and scripts written by hackers) can lie.(null, output)
.Upvotes: 2