Apostrophe CMS:过滤 apostrophe-pieces-widgets 的结果

Apostrophe CMS: filtering the Result of apostrophe-pieces-widgets

目前我的模板中有两行代码

{{ apos.singleton(data.page, 'productsLimitedBy12', 'products',{...someoptions}) }}
...
{{ apos.singleton(data.page, 'singleproduct', 'products',{...someoptions}) }}

两者都是我在 'apostrophe-pieces-widgets' 的帮助下声明的同一个小部件。

我想在撇号将它们限制为数字 12 和 1 之前过滤加载的 Pieces。如果我在 self.load 上过滤这些 pieces,我将只有 12 - filtered_pieces。但是数量应该是静态的,如果数据库中符合黑白名单标准的数量少于12个,则数量应该小于12。

基本上我想要一个黑名单和白名单,选项为“对 XYZ 可见,对 XYZ 不可见,对所有人可见”

示例:

  1. 在数组“company1、company2”中具有以下属性的用户 ABC 应该看到指定为对 company1 或 company2 可见的每个片段或对所有人可见的片段。
  2. 在数组“notCompany1、notCompany2”中具有以下属性的用户 DEF 应该可以看到不是来自 company1 或 company2 的每个片段。

我怎样才能做到这一点?是否可以包含一个过滤器,每次请求来自特定小部件的片段时,该过滤器都会添加到查询中?

编辑-1:

用于指定数字 1 或 12 的确切含义。如果我登录并访问上下文菜单并单击小部件,我将获得以下选项:Select(可以是全部,按标签或单独)和最大显示。对于第一个产品小部件,我想要 12 个,而另一个只有 1 个。

如果你指的是代码中的字符串,这些只是为了理解我有两行我有相同的小部件但有不同的限制,我调整它以便更好地理解。

快速总结一下我的工作流程:

  1. 我通过上下文菜单给一些产品一些白名单和黑名单公司
  2. 这些公司是通过连接添加到作品中的
  3. 我过滤了 products-widget/index.js 中的片段;但问题是过滤发生在撇号选择 12 或 1 件之后。我想过滤然后撇号来限制碎片。

这是我的 product/index.js(当然是修剪过的):

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

这是我保存在 aposDocs 中的数据库对象(当然已修剪):

{
    "_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"],

}

这是我的 products-widgets/index.js(当然是修剪过的)

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

另外为了快速了解我的案例:

我认为使用 self.widgetCursor 可能是我尝试实现此目标的方式。您根本不需要对 self.load 做任何事情,因为您需要在加载开始之前完成过滤。它需要在游标中发生。

widgetCursor 看起来像:

self.widgetCursor = function(req, criteria) {
  var filters = self.filters || (self.joinById && self.joinById.filters);
  return self.pieces.find(req, criteria).applyFilters(filters);
};

您应该 req.user 可以获取类似于以下内容的用户信息:

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

我不是 100% 确定这完全正确,但我很确定它足够接近开始。获得用户数据后,可以通过超级模式或完全覆盖它来将其应用于 self.widgetCursor 中的 criteria 对象。