Strapi Slug 系统的建立
Strapi Slug 系统的建立
在前一篇文章的基础上进行,即Docker上的Strapi如何建立Slug系统,本文给出了修改步骤。
本文针对中文标题的生成,用到两个库:pinyin
和 slugify
。
- 手动添加依赖到
package.js
- 删除
node_modules
、package-lock.js
- 修改并保存对应
api
的model
中的文件 重新运行容器(程序自动检测文件的修改,会自动重启,不需要手动重启)docker restart my-strapi
别想着通过 docker exec -it my-strapi /bin/bash
或者 docker exec -it my-strapi npm install --save slugify
会出现莫名其妙的错误,总之,删依赖然后重新 npm install
是万能解决方案。
请根据步骤进行,后文给出步骤2和步骤3的具体内容。
"slugify": "^1.6.5",
"pinyin": "^2.10.2"
这是本文写作时的最新版本号。
在 api 文件夹的对应位置,本文是strapi/api/post/models/post.js
,写下钩子:
const slugify = require('slugify');
const pinyin = require("pinyin");
module.exports = {
lifecycles: {
async beforeCreate(data) {
if (data.title) {
data.slug = slugify(pinyin(data.title, {
style: pinyin.STYLE_NORMAL
}), {
lower: true
});
}
},
async beforeUpdate(params, data) {
if (data.title) {
data.slug = slugify(pinyin(data.title, {
style: pinyin.STYLE_NORMAL
}), {
lower: true
});
}
}
}
}
场景:
category
中设置了引用类型,一个 category
对应一个 type
,一个 type
有多个 category
。
那么 category
创建时的 slug
需要查询 type
获取对应的 code
。
原因是 hook 中只能获取 type
的 id
即category
的type
字段保存的是对应type
的id
。
在使用 strapi
暴露的 query.findOne
方法时,不尽人意,因为会获取到不必要的字段,需要投影查询也就是SQL常用的 select。
官方文档 Models | Strapi 中,给出了如何自定义查询的方法,此时需要使用对应的底层 ORM 模型,使用query.model
方法然后使用对应的ORM方法即可,ORM模型提供了 SQL 和 MongoDB 两种,这里我们自然选择 MongoDB。
给出代码:
const slugify = require('slugify');
const pinyin = require("pinyin");
module.exports = {
lifecycles: {
async beforeCreate(data) {
if (data.name) {
let words = pinyin(data.name, {
style: pinyin.STYLE_NORMAL
})
words = [].concat(...words)
if (data.type) {
// 使用 strapi query model 来自定义查询; 注意使用对应的 ORM 语法,查询id的时候应该是 _id
let type = await strapi.query('type').model.findOne({ _id: data.type }, "code").exec();
if (type) {
words.unshift(type.code);
}
}
words = words.join(' ');
data.slug = slugify(words, {
lower: true
});
}
},
async beforeUpdate(params, data) {
if (data.name) {
let words = pinyin(data.name, {
style: pinyin.STYLE_NORMAL
})
words = [].concat(...words)
if (data.type) {
// 使用 strapi query model 来自定义查询; 注意使用对应的 ORM 语法,查询id的时候应该是 _id
let type = await strapi.query('type').model.findOne({ _id: data.type }, "code").exec();
if (type) {
words.unshift(type.code);
}
}
words = words.join(' ');
data.slug = slugify(words, {
lower: true
});
}
}
}
}
核心语句是:await strapi.query('type').model.findOne({ _id: data.type }, "code").exec();
,其中的 findOne
方法是 mongoosejs 官方文档中查询到的,包括使用字符串进行投影的"code"
。这里要注意的是查询的是底层MongoDB数据库,打开看看,发现其中并没有保存id
字段,有的只是_id
,这一点需要注意,否则查询结果可能为 null
。
Thanks to: