我正在尝试将Keystone变成CMS。所以,我需要Article,Category,ImagePage,AttachmentPage等模型。我提到的每个模型都有一个常见字段的子集,如:title,content,meta:{title,description,keywords}等。
在Keystone中,模型的构造如下:
Article.add(fieldsCollectionObject)
所以我在外部文件中定义了公共字段:
var T = require('keystone').Field.Types;
module.exports = {
title: { type: T.Text, required: true },
content: { type: T.Html, wysiwyg: true, height: 400 },
meta: {
title: { type: T.Text },
desc: { type: T.Textarea, height: 50 },
keywords: { type: T.Text },
},
publishedDate: { type: T.Date, index: true, dependsOn: { state: 'published' } },
state: { type: T.Select, options: 'draft, published, archived', default: 'draft', index: true },
};
并且在我的模型文件中要求它:
const _ = require('lodash');
const pageDef = require('./common/Page.js');
const keystone = require('keystone');
const T = keystone.Field.Types;
<...>
Article.add(_.defaultsDeep({
brief: { type: T.Html, wysiwyg: true, height: 150 },
category: { type: T.Relationship, ref: 'Category', many: false, collapse: true },
tags: { type: T.Relationship, ref: 'Tag', many: true },
}, defs.authored, pageDef));
现在,问题在于管理界面中的字段顺序 - 毫不奇怪brief
,category
和tags
在pageDef
的字段之前。有没有办法强加我想要的订单?与title
,brief
,content
,<the rest>
?
答案 0 :(得分:1)
defaults
和defaultsDeep
将作为参数传递的第一个对象变为它(Keystone字段的初始对象)。要拥有自己的订单,您需要按照希望它们出现在对象中的顺序将对象传递给_.defaultsDeep
,从而将它们显示在管理界面中的顺序。
有用的是,重复的项目不会包含在结果对象中。所以你会有这样的事情:
const _ = require('lodash');
const pageDef = require('./common/Page.js');
const keystone = require('keystone');
const T = keystone.Field.Types;
//....
let articleDef = {
brief: { type: T.Html, wysiwyg: true, height: 150 },
category: { type: T.Relationship, ref: 'Category', many: false, collapse: true },
tags: { type: T.Relationship, ref: 'Tag', many: true };
};
Article.add(_.defaultsDeep({
title: pageDef.title,
brief: articleDef.brief,
content: pageDef.content},
pageDef, articleDef));
答案 1 :(得分:1)
上面的答案原来是要走的路。所以我扩展并建立在它上面:
LIB / util.js中
const _ = require('lodash');
class Util {
static sourceFields (fields, ...sources) {
const source = _.defaultsDeep(...sources);
const result = [];
for (let fieldSet of fields) {
result.push(_.isArray(fieldSet) ? _.pick(source, fieldSet) : fieldSet);
}
return result;
}
}
module.exports = Util;
模型/普通/ traits.js
var T = require('keystone').Field.Types;
module.exports = {
title: { type: T.Text, required: true },
content: { type: T.Html, wysiwyg: true, height: 400 },
indexImage: { type: T.CloudinaryImage },
meta: {
title: { type: T.Text },
desc: { type: T.Textarea, height: 50 },
keywords: { type: T.Text },
},
// <...>
}
模型/ Article.js
const util = require('../lib/utils.js');
const defs = require('./common/traits.js');
const keystone = require('keystone');
const T = keystone.Field.Types;
// < var Article declaration... >
const ownDef = {
brief: { type: T.Html, wysiwyg: true, height: 150 },
category: { type: T.Relationship, ref: 'Category', many: false, collapse: true },
tags: { type: T.Relationship, ref: 'Tag', many: true },
images: { type: T.Relationship, ref: 'Image', many: true, collapse: true },
attachments: { type: T.Relationship, ref: 'Attachment', many: true, collapse: true },
};
Article.add(...util.sourceFields([
'Content', ['title', 'brief', 'content', 'indexImage', 'category', 'tags'],
'Media', ['images', 'attachments'],
'SEO', ['meta'],
'Status', ['pageType', 'author', 'state', 'publishedDate'],
], ownDef, defs));
所以,在traits.js
中,我在Article.js
中定义了常用字段 - 我只在文章模型中使用的字段。然后,在文章模型中,我在sourceFields()
函数的帮助下将字段添加到List中。 sourceFields()
获取一组字段集和未指定数量的字段定义对象(例如ownDef
和defs
)。
字段集是字符串或字段名称数组(定义对象中的键)。如果是字符串,它将成为管理界面中的标题,如果它是数组,那么它就像一组字段一样排序,就像数组中的字段名一样 - 该函数基本上是插入的字段定义到&#34;插槽&#34;在fieldset中指定。