如何在 Keystone 的管理中重新排序字段 UI
How to reorder fields in Keystone's Admin UI
我正在尝试将 Keystone 制作成 CMS。所以,我需要 Article、Category、ImagePage、AttachmentPage 等模型。我提到的每个模型都有一个公共字段的子集,例如:标题、内容、元:{标题、描述、关键字}等等。
在 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));
现在,问题出在 Admin UI 中的字段顺序 - 不出所料,brief
、category
和 tags
排在 [=17 的字段之前=].有什么办法可以强加我想要的命令吗?喜欢 title
、brief
、content
、<the rest>
?
defaults
and defaultsDeep
改变作为参数传递给它的第一个对象(Keystone 字段的初始对象)。要拥有自己的顺序,您需要按照您希望它们在对象中出现的顺序将对象传递给 _.defaultsDeep
,因此它们在 Admin UI 中出现的顺序也是如此。
有用的是,结果对象中不会包含重复项。所以你会有这样的东西:
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));
上面的答案证明是可行的。所以我扩展并构建了它:
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;
models/common/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 },
},
// <...>
}
models/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()
函数将字段添加到列表中。 sourceFields()
获取字段集数组和未指定数量的字段定义 objects(如 ownDef
和 defs
)。
字段集是字符串或字段名称数组(定义中的键 objects)。如果它是字符串,它将是 Admin UI 中的 header,如果它是数组,那么它将是一组字段,就像数组中的字段名称一样排序 - 该函数基本上将字段定义插入到"slot" 在字段集中指定。
我正在尝试将 Keystone 制作成 CMS。所以,我需要 Article、Category、ImagePage、AttachmentPage 等模型。我提到的每个模型都有一个公共字段的子集,例如:标题、内容、元:{标题、描述、关键字}等等。
在 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));
现在,问题出在 Admin UI 中的字段顺序 - 不出所料,brief
、category
和 tags
排在 [=17 的字段之前=].有什么办法可以强加我想要的命令吗?喜欢 title
、brief
、content
、<the rest>
?
defaults
and defaultsDeep
改变作为参数传递给它的第一个对象(Keystone 字段的初始对象)。要拥有自己的顺序,您需要按照您希望它们在对象中出现的顺序将对象传递给 _.defaultsDeep
,因此它们在 Admin UI 中出现的顺序也是如此。
有用的是,结果对象中不会包含重复项。所以你会有这样的东西:
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));
上面的答案证明是可行的。所以我扩展并构建了它:
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;
models/common/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 },
},
// <...>
}
models/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()
函数将字段添加到列表中。 sourceFields()
获取字段集数组和未指定数量的字段定义 objects(如 ownDef
和 defs
)。
字段集是字符串或字段名称数组(定义中的键 objects)。如果它是字符串,它将是 Admin UI 中的 header,如果它是数组,那么它将是一组字段,就像数组中的字段名称一样排序 - 该函数基本上将字段定义插入到"slot" 在字段集中指定。