豪翔天下

Change My World by Program

0%

Strapi CMS 使用手册

  • Roadmap: 真的有好多还没开发完成的实用功能

安装与配置

常用命令

1
export PORT=3000 && npm run develop	# 更改启动端口

自定义Role及权限

  • 免费版不能在web端直接进行配置,不过可以修改数据库,看一下数据库的表结构就能很好修改了,但问题是每次修改了types结构以后需要重新分配role的权限,否则权限会丢失,可以使用以下代码在重新启动应用时自动更新权限,但还是有个问题,如果应用不完全重启,仍然不会更新,因为应用没有完全重启的话admin的也不会更新的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // config/functions/bootstrap.js
    "use strict";

    const lodash = require('lodash');

    // Prevent permissions loss
    const setDefaultRolePermissions = async () => {
    const adminRole = await strapi.query("role", "admin").findOne({id: 1});
    const customRoles = await strapi.query("role", "admin").find({id_gt: 3});

    customRoles.forEach(customRole => {
    console.log(`Check ${customRole.name} permissions`);
    customRole.permissions.forEach(permission => {
    // compare permission fields with adminRole
    const realPermission = adminRole.permissions.find(p => p.action === permission.action && p.subject === permission.subject)
    if (permission.properties.fields && permission.action.includes('plugins::content-manager.explorer') &&(permission.properties.fields.length !== realPermission.properties.fields.length ||
    permission.properties.fields.length !== lodash.uniq(permission.properties.fields.concat( realPermission.properties.fields)).length)) {
    strapi.query("permission", "admin").update({id: permission.id}, {properties: realPermission.properties})
    }
    })
    })
    };


    module.exports = async () => {
    setTimeout(setDefaultRolePermissions, 3000); // 使用timeout是因为刚重启的时候数据库还没根据新的结构更新
    };

升级步骤

升级非常简单,直接在composer.json里面全局替换,例如将3.5.2全部替换成3.6.1,在执行以下命令即可

1
2
npm install
rm -rf .cache && rm -rf build/

修改admin系统文件

  • 只需要参照node_modules/strapi-admin/中的目录结构,在根目录新建admin文件夹与其保持一致,任何想要覆盖的都可以放在这里
  • 替换logo,可以在admin/src/assets/images中放置

其他特性

定时获取外部数据

  • 支持定时从外部获取数据并存储到数据库中,不过我没玩儿过,可以参考这里

外部插件

Cloudinary支持官方文档

集成步骤

  1. 安装npm install strapi-provider-upload-cloudinary graphql --save

  2. config/plugins.js中添加upload配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    module.exports = ({ env }) => ({
    // ...
    upload: {
    provider: 'cloudinary',
    providerOptions: {
    cloud_name: env('CLOUDINARY_NAME'),
    api_key: env('CLOUDINARY_KEY'),
    api_secret: env('CLOUDINARY_SECRET'),
    },
    },
    // ...
    });

支持上传至指定目录

  • 官方的这个插件默认不支持指定上传目录,可以关注这个issue,也不知道他们怎么想的,如果要支持自定义目录或者其他clodinary配置,可以用strapi-provider-upload-cloudinary-folderoptions,但是它有个问题就是upload from url的时候会把那个url当成目录层级,可是url本身放到url中会报错

  • 第二种方法就是自己修改一下官方那个插件即可,挺简单的:

    1. 修改package.json添加依赖: strapi-provider-upload-cloudinary-folder: "file:providers/strapi-provider-upload-cloudinary-folder"
    2. 修改config/plugin.js,将upload.provider修改为cloudinary-folder,并且在providerOptions中添加参数folder: env('CLOUDINARY_DEFAULT_FOLDER')
  • 复制package.json内容到providers/strapi-provider-upload-cloudinary-folder/package.json并修改namestrapi-provider-upload-cloudinary-folder

  • 复制index.js内容到providers/provider-upload-cloudinary-folder/index.js简单修改一下将配置传入:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    init(config) {
    cloudinary.config(config);
    const folder = config.folder;

    return {
    upload(file, customConfig = {}) {
    return new Promise((resolve, reject) => {
    const config = {
    resource_type: 'auto',
    public_id: file.hash,
    folder,
    };

    ...
    }
    }

strapi-tinymce 集成tinymce

集成步骤

  1. 安装npm install --save @tinymce/tinymce-react

  2. tiny下载tinymce源码到public目录下,即目录结构为public/tinymce

  3. 执行strapi generate:plugin wysiwyg生成新的富文本插件

  4. 仓库中的content-manager/admin/src/components复制到plugins/wysiwyg/admin/src

  5. 修改plugins/wysiwyg/admin/src/index.js将最后的返回值修改为我们自己的组件

    1
    2
    strapi.registerField({ type: 'wysiwyg', Component: WysiwygWithErrors});
    return strapi.registerPlugin(plugin);
  6. 如果要editor支持所有的html tag,可以在plugins/wysiwyg/admin/src/components/WysiwygWithErros/Tinymce.jsinit属性中添加

    1
    2
    extended_valid_elements: "*[*]",
    non_empty_elements: "td,th,iframe,video,audio,object,script,pre,code,area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,source,wbr,track, svg,defs,pattern,desc,metadata,g,mask,path,line,marker,rect,circle,ellipse,polygon,polyline,linearGradient,radialGradient,stop,image,view,text,textPath,title,tspan,glyph,symbol,switch,use",

实现/集成color picker功能

  • 仓库见Strapi_ColorPicker_Plugin,他还写了个文档

  • 由于原本的代码不能直接用,所以这里记录下具体集成步骤:

    1. 将上面仓库代码中的api/plugins/colorPicker复制到我们项目的plugins/目录下

    2. 修改plugins/colorpicker/admin/src/components/colorPicker/index.js的如下代码:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      const Title = styled.h5`
      margin-bottom: 1rem;
      color: #333740;
      text-transform: capitalize; // title增加首字母大写样式
      `;

      const updateColorValue = (colorValue) => {
      props.onChange({ target: { name: props.name, value: colorValue } }); // 名字修改为属性本来的名字,这样用于组件的时候也不会有bug
      };

      <Title>{props.name.split('.').slice(-1)[0]}</Title> // title也用本来的名字,只是首字母大写而已
    3. 最重要的,一定要npm run build一下

    4. 由于strapi对自定义字段还未支持完成,所以现在新加的字段不会在UI上面显示,如果要将某个字段修改为colorpicker类型,需要手动在components下面的scheme中进行修改:

      1
      2
      3
      4
      "color": {
      "type": "colorpicker",
      "columnType": "string"
      }

实现网页菜单配置

  • 目前我没找到一个比较好的菜单配置插件
  • 目前component不支持嵌套自身,所以我只能自己做两个component: TopMenu(title, url, subMenus), SubMenu(title, url),只能二级,如果多级只能再加新的component

TroubleShooting

  • The file is too big: 这一般是nginx的限制,上传的文件太大了,需要修改nginx的配置client_max_body_size 10m
  • 如果新建的内容访问接口是404: 一般是因为没有发布publish
  • relationship 关联对象拖动排序无效: 明明保存时提交的字段的顺序都是正确的,但是提交后又是原来的顺序了,目前是还没修复,但是可以先把所有的关联删除了,保存后再重新新建就行了
  • 无法嵌套实用components: 网页上不行,但是直接修改component的json文件一般是可以的,但有时候也不能用,还是得等官方支持才行
  • error TypeError: Cannot read property ‘attributes’ of undefined: 可能是某个组件没上传导致的,如果报错行数在./node_moduels/strapi-plugin-documentation/services/Documentation.js:592:42直接去里面把component打印出来吧
坚持原创技术分享,谢谢支持

欢迎关注我的其它发布渠道