get contents to display on a page
function contentsToDisplay(req, res, scsId, scId = 0, cb) {
  var zlSiteContentIn = app.models.zlSiteContentIn;
  var Role = app.models.Role;
  var compMod = require('./helpers/component-from-model')(app);

  // emit that content was requested
  if (res.locals.emiter.emit(`fetching content ${scsId}`, cb)) {
    // if a package listen, it is responsible for callback
    // also enable using scsId that is not in db to not cause error
    return;
  }

  var { themeData } = res.locals;

  // first, make sure they are allowed to view page
  // get role permission for page
  let filter = {fields: {scsPermission: true, zlSiteId: true}};
  app.models.zlSiteContentSet.findById(scsId, filter, (err, scs) => {
    if (err || !scs) return cb(`page does not exist`);
    let ctx = app.locals.authCtx(req, res);
    Role.isInRole(scs.scsPermission, ctx, (err, isInRole) => {
      if (isInRole) {
        // filter for model search
        let filter = {
          fields: {scId: true},
          include: {
            relation: 'zlSiteContent',
            scope: {
              where: {scStatus: 'publish', zlSiteId: res.locals.zlSite.zsId},
            },
          },
          where: {scsId: scsId},
        };
        zlSiteContentIn.find(filter, (err, data) => {
          // to keep list of promises
          var promises = [];
          // functions in component-from-model may need to make promises
          compMod.promises = promises;

          _.forEach(data, function(val, key) {
            if (!val || !val.zlSiteContent) return data.splice(key, 1);
            // converts from loopback object to json
            val = val.toJSON().zlSiteContent;
            if ('page content' === val.scType) {
              // overide data to this value
              data = val.scContent;
              // iterate list of page content
              if (_.isArray(data)) {
                _.forEach(data, function(subVal, subKey) {
                  // make sure there is a scId
                  subVal.scId = (subVal.scId)?subVal.scId:`pg${scsId}-cont${subKey}`;

                  prepContent(req, res, data, subVal, subKey, promises,
                    compMod, scsId, cb);
                });
              }
              // end here since only 1 active content list is used
              return false;
            } else {
              // other type (like 'post' but not yet used anywhere)
              data[key] = val.scContent;
              prepContent(req, res, data, val.scContent, key, promises,
                compMod, scsId, cb);
            }
          });
          // emit that content loaded; allowing other sources to populate further
          res.locals.emiter.emit(`loaded content ${scsId}`, data, promises);
          // when all promise met, callback
          Promise.all(promises).then(values => {
            cb(null, data);
          });
        });
      } else cb('Page Authorization failed');
    });
  });

  compMod.themeData = themeData;
}