【问题标题】:Strapi V4 populate dynamic zones media not populatingStrapi V4 填充动态区域媒体未填充
【发布时间】:2022-06-21 16:17:51
【问题描述】:

使用下面建议的补丁似乎可以填充数据字段,但是没有填充媒体字段。

尝试了以下没有运气 -

* http://localhost:1337/api/pages?populate=*
* {{protocol}}://{{host}}:{{port}}/api/pages?populate[Content][populate]=images

参考 - https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/rest/populating-fields.html#component-dynamic-zones

以下示例来自 - https://forum.strapi.io/t/strapi-v4-populate-media-and-dynamiczones-from-components/12670/9

也试过这个插件(运气不好)-https://www.npmjs.com/package/strapi-plugin-populate-deep

下面带有动态区域的页面示例 -

/helpers/populate.js(这适用于除图像之外的所有数据)-

const { createCoreController } = require("@strapi/strapi/lib/factories");

function populateAttribute({ components }) {
  if (components) {
    const populate = components.reduce((currentValue, current) => {
      return { ...currentValue, [current.split(".").pop()]: { populate: "*" } };
    }, {});
    return { populate };
  }
  return { populate: "*" };
}

const getPopulateFromSchema = function (schema) {
  return Object.keys(schema.attributes).reduce((currentValue, current) => {
    const attribute = schema.attributes[current];
    if (!["dynamiczone", "component"].includes(attribute.type)) {
      return currentValue;
    }
    return {
      ...currentValue,
      [current]: populateAttribute(attribute),
    };
  }, {});
};

function createPopulatedController(uid, schema) {
  return createCoreController(uid, () => {
    console.log(schema.collectionName, JSON.stringify(getPopulateFromSchema(schema)));
    return {
      async find(ctx) {
        ctx.query = {
          ...ctx.query,
          populate: getPopulateFromSchema(schema),
        //   populate: '*',
        };
        return await super.find(ctx);
      },
      async findOne(ctx) {
        ctx.query = {
          ...ctx.query,
          populate: getPopulateFromSchema(schema),
          // populate: '*',
        };
        return await super.findOne(ctx);
      },
    };
  });
}

module.exports = createPopulatedController;

/src/api/page/controllers/pages.js -

"use strict";

const collectionType = 'page'

const schema = require(`../content-types/${collectionType}/schema.json`);
const createPopulatedController = require("../../../helpers/populate");

module.exports = createPopulatedController(`api::${collectionType}.${collectionType}`, schema);

未通过以下图片的响应 -

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "testing home page",
        "slug": "/",
        "publish_at": null,
        "createdAt": "2022-04-12T12:08:32.002Z",
        "updatedAt": "2022-04-12T15:07:11.990Z",
        "publishedAt": "2022-04-12T12:42:55.682Z",
        "locale": "en",
        "seoComponent": null,
        "block": [
          {
            "id": 1,
            "__component": "image.image-copy-full",
            "heading": "Delivering something amazing",
            "subHeading": "test sadasdf",
            "ctaButton": "test",
            "miscValues": {
              "testing": "object field"
            },
            "actionUrl": null,
            "isInternal": true,
            "isVisible": true
          },
          {
            "id": 1,
            "__component": "image.image-copy-chip",
            "heading": "A platform",
            "subHeading": "Allowing full integration",
            "ctaButton": null,
            "miscValues": null,
            "actionUrl": null,
            "isInternal": true,
            "isVisible": false
          },
          {
            "id": 1,
            "__component": "image.image-copy",
            "heading": "To transform our world",
            "subHeading": "In order to reach that scale",
            "ctaButton": null,
            "miscValues": null,
            "actionUrl": null,
            "isInternal": true
          }
        ]
      }
    }
  ],
  "meta": {
    "pagination": {
      "page": 1,
      "pageSize": 25,
      "pageCount": 1,
      "total": 1
    }
  }
}

屏幕截图中“ImageCopyFull”的架构示例 -

{
  "collectionName": "components_image_image_copy_fulls",
  "info": {
    "displayName": "ImageCopyFull",
    "icon": "file-image",
    "description": ""
  },
  "options": {},
  "attributes": {
    "heading": {
      "type": "string"
    },
    "subHeading": {
      "type": "string"
    },
    "ctaButton": {
      "type": "string"
    },
    "miscValues": {
      "type": "json"
    },
    "actionUrl": {
      "type": "string"
    },
    "isInternal": {
      "type": "boolean",
      "default": true
    },
    "image": {
      "type": "media",
      "multiple": false,
      "required": true,
      "allowedTypes": [
        "images",
        "videos",
        "audios",
        "files"
      ]
    },
    "isVisible": {
      "type": "boolean",
      "default": false
    }
  }
}

【问题讨论】:

    标签: controller strapi


    【解决方案1】:

    strapi github 下找到答案,向“Tomnovotny7”大喊,谢谢。

    在你的“page.js”下复制以下代码-

    const { isEmpty, merge } = require("lodash/fp");
    
    const getModelPopulationAttributes = (model) => {
      if (model.uid === "plugin::upload.file") {
        const { related, ...attributes } = model.attributes;
        return attributes;
      }
    
      return model.attributes;
    };
    
    const getFullPopulateObject = (modelUid, maxDepth = 20) => {
      if (maxDepth <= 1) {
        return true;
      }
      if (modelUid === "admin::user") {
        return undefined;
      }
    
      const populate = {};
      const model = strapi.getModel(modelUid);
      for (const [key, value] of Object.entries(
        getModelPopulationAttributes(model)
      )) {
        if (value) {
          if (value.type === "component") {
            populate[key] = getFullPopulateObject(value.component, maxDepth - 1);
          } else if (value.type === "dynamiczone") {
            const dynamicPopulate = value.components.reduce((prev, cur) => {
              const curPopulate = getFullPopulateObject(cur, maxDepth - 1);
              return curPopulate === true ? prev : merge(prev, curPopulate);
            }, {});
            populate[key] = isEmpty(dynamicPopulate) ? true : dynamicPopulate;
          } else if (value.type === "relation") {
            const relationPopulate = getFullPopulateObject(
              value.target,
              maxDepth - 1
            );
            if (relationPopulate) {
              populate[key] = relationPopulate;
            }
          } else if (value.type === "media") {
            populate[key] = true;
          }
        }
      }
      return isEmpty(populate) ? true : { populate };
    };
    
    const modelUid = "api::page.page";
    
    module.exports = createCoreController(modelUid, ({ strapi }) => ({
      async find(ctx) {
        const { query } = ctx;
    
        const { results, meta } = await strapi.service(modelUid).find({
          ...getFullPopulateObject(modelUid),
          ...query,
        });
    
        const sanitizedEntities = await this.sanitizeOutput(results, ctx);
    
        return {
          data: sanitizedEntities,
          meta,
        };
      },
    }));
    

    【讨论】:

      【解决方案2】:

      您可以使用市场上的Populate Deep plugin

      您只需安装包:

      yarn add strapi-plugin-populate-deep
      

      然后使用带有deep 值的填充参数,如下所示:

      /api/articles/1?populate=deep
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-08-03
        • 1970-01-01
        • 1970-01-01
        • 2012-09-17
        • 2022-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多