I have currently the two lines of Code in my Template
{{ apos.singleton(data.page, 'productsLimitedBy12', 'products',{...someoptions}) }}
...
{{ apos.singleton(data.page, 'singleproduct', 'products',{...someoptions}) }}
Both are the same widget that I declare with the help of 'apostrophe-pieces-widgets'.
I want to filter the loaded Pieces before apostrophe limits them to the number 12 and 1. If I filter the pieces on self.load, I will only have 12 - filtered_pieces
. But the amount should be static and only less than 12 if there are less than 12 pieces in the DB that fit the blacklist and whitelist criteria.
Basically I want to have a black- and whitelist for pieces, with the options "visible for XYZ, not visible for XYZ, visible for all"
Example:
How can I achieve that? Is it possible to include a filter that will be added to the query every time the pieces from a specific widget were requested?
EDIT-1:
For specifying what I exactly mean with the number 1 or 12. If I am logged in with access to the context menu and click on the widget, I get the following options: Select (which can be all, by tag or individually) and maximum displayed. For the first product widget I want 12 pieces for the other only 1.
If you meant the strings in the code, these were just for understanding that I have two lines where I have the same widgets but with different limits, I adjusted it for a better understanding.
To quickly summarize my Workflow:
Here is my product/index.js (trimmed of course):
module.exports = {
extend: 'apostrophe-pieces',
name: 'product',
label: 'product',
pluralLabel: 'products',
contextual: true,
addFields: [
{
name: 'title',
label: 'Title',
type: 'string',
required: true
},
{
name: '_companySelection',
withType: 'company',
label: 'Company-Selection',
type: 'joinByArray',
filters: {
areas: false,
joins: false,
projection: {
_id: 1,
title: 1
}
}
},
{
name: '_companySelectionNOT',
withType: 'company',
label: 'Company-Selection NOT',
type: 'joinByArray',
filters: {
areas: false,
joins: false,
projection: {
_id: 1,
title: 1
}
}
},
],
arrangeFields: [
{}
],
construct: function (self, options) {
self.beforeSave = function (req, piece, options, callback) {
// foo()
return callback();
};
}
};
Here is my database Object saved in aposDocs (trimmed of course):
{
"_id": "ckfwbczu5002035ziaa8a2pzp",
"priority": 100000,
"validFrom": "2020-10-01",
"validUntil": "2020-12-31",
"trash": false,
"title": "EXAMPLE",
"createdAt": {
"$date": "2020-10-05T09:10:16.685Z"
},
"updatedAt": {
"$date": "2020-12-04T11:21:29.692Z"
},
"companySelectionIds": ['ck2q9raez01i04kous6fo59hj'],
"companySelectionNOTIds": ["cjn0e31up02ydm8otk4h4uhwq"],
}
And here is my products-widgets/index.js (trimmed of course)
module.exports = {
extend: 'apostrophe-pieces-widgets',
filters: {
projection: {
...projectobj
}
},
label: 'Product Widget',
alias: 'products',
construct: function (self, options) {
var superLoad = self.load;
self.addHelpers({...helpers})
self.load = function (req, widgets, callback) {
var currentUser = req.data.user;
return superLoad(req, widgets, function (err) {
if (err) return callback(err);
else {
widgets._pieces = filtered(user,widgets._pieces);
callback()
}
});
};
}
};
Also for a quick understanding regarding my cases:
I think using self.widgetCursor
might be how I would try to achieve this. You wouldn't need to do anything with self.load
at all since you need the filtering to be done before loading has begun. It needs to happen in the cursor.
widgetCursor
looks like:
self.widgetCursor = function(req, criteria) {
var filters = self.filters || (self.joinById && self.joinById.filters);
return self.pieces.find(req, criteria).applyFilters(filters);
};
You should have req.user
available to get the user info similar to:
// Possibly could be `self.apos.users.find`
var userCursor = self.apos.docs.getManager('user').find(req, { _id: req.user._id }, {
_companySelection: 1,
_companySelectionNOT: 1
});
const user = userCursor.toObject();
I'm not 100% sure that's exactly right, but I'm pretty sure it's close enough to get started. Once you have the user data it can be applied to the criteria
object in self.widgetCursor
, either through the super pattern or overriding it completely.