- Roadmap: 真的有好多还没开发完成的实用功能
安装与配置
常用命令
1 | export PORT=3000 && npm run develop # 更改启动端口 |
配置文件
1 | // config/server.js, Server相关配置 |
自定义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
;
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 | npm install |
修改admin系统文件
- 只需要参照
node_modules/strapi-admin/
中的目录结构,在根目录新建admin文件夹与其保持一致,任何想要覆盖的都可以放在这里 - 替换logo,可以在
admin/src/assets/images
中放置
其他特性
Controllers
1 | return ctx.badRequest({ error: 'Parameter is empty' }) // 返回400错误 |
Services
1 | await strapi.query('user', 'users-permissions').findOne({id:13}) // 查询用户 |
Hooks
Middlewares
- 有一些自带的中间件: favicon、public、session、logger、parser、gzip、responseTime、poweredBy,安全相关的有csp、p3p、hsts、xframe、xss、cors、ip(可以设置黑白名单)
Functions
./config/functions
目录下,这里面的函数可以用trapi.config.functions['fileName']()
来调用bootstrap.js
每启动都会执行
定时获取外部数据
- 支持定时从外部获取数据并存储到数据库中,不过我没玩儿过,可以参考这里
API集成
- 这里列举了各个前端如何使用API的方法
- 调用API如果开启了认证,那么就得用一个user来用接口登录获取jwt token,并且这里的user和登录用户不一样,需要重新注册才行,并且默认都可以注册,注册了一个后可以在
USERS & PERMISSIONS PLUGIN -> Advanced Settings
去关闭注册功能
graphql
- 服务端需要先安装
strapi install graphql
,客户端也需要安装npm install @apollo/client graphql
1 | // 登录获取jwt token |
外部插件
Cloudinary支持官方文档
集成步骤
安装
npm install strapi-provider-upload-cloudinary graphql --save
在
config/plugins.js
中添加upload
配置:1
2
3
4
5
6
7
8
9
10
11
12module.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中会报错第二种方法就是自己修改一下官方那个插件即可,挺简单的:
- 修改
package.json
添加依赖:strapi-provider-upload-cloudinary-folder: "file:providers/strapi-provider-upload-cloudinary-folder"
- 修改
config/plugin.js
,将upload.provider
修改为cloudinary-folder
,并且在providerOptions
中添加参数folder: env('CLOUDINARY_DEFAULT_FOLDER')
- 修改
复制package.json内容到
providers/strapi-provider-upload-cloudinary-folder/package.json
并修改name
为strapi-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
16init(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
集成步骤
安装
npm install --save @tinymce/tinymce-react
从tiny下载
tinymce
源码到public
目录下,即目录结构为public/tinymce
执行
strapi generate:plugin wysiwyg
生成新的富文本插件将仓库中的
content-manager/admin/src/components
复制到plugins/wysiwyg/admin/src
下修改
plugins/wysiwyg/admin/src/index.js
将最后的返回值修改为我们自己的组件1
2strapi.registerField({ type: 'wysiwyg', Component: WysiwygWithErrors});
return strapi.registerPlugin(plugin);如果要editor支持所有的html tag,可以在
plugins/wysiwyg/admin/src/components/WysiwygWithErros/Tinymce.js
的init
属性中添加1
2extended_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,他还写了个文档
由于原本的代码不能直接用,所以这里记录下具体集成步骤:
将上面仓库代码中的
api/plugins/colorPicker
复制到我们项目的plugins/
目录下修改
plugins/colorpicker/admin/src/components/colorPicker/index.js
的如下代码:1
2
3
4
5
6
7
8
9
10
11const 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也用本来的名字,只是首字母大写而已最重要的,一定要
npm run build
一下由于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文件一般是可以的,但有时候也不能用,还是得等官方支持才行:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 例如如果网页上不能选择某个component,那么可以直接修改其json文件,在attributes里面添加字段
{
"collectionName": "components_common_main_menus",
"info": {
"name": "MainMenu",
"icon": "braille",
"description": ""
},
"options": {},
"attributes": {
"text": {
"type": "string"
},
"dropdownMenus": {
"type": "component",
"repeatable": true,
"component": "common.dropdown-menu"
}
}
}error TypeError: Cannot read property ‘attributes’ of undefined: 可能是某个组件没上传导致的,如果报错行数在
./node_moduels/strapi-plugin-documentation/services/Documentation.js:592:42
直接去里面把component
打印出来吧