【问题标题】:How to reorder fields in Keystone's Admin UI如何在 Keystone 的管理 UI 中重新排序字段
【发布时间】:2017-03-17 17:31:04
【问题描述】:

我正在尝试将 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));

现在,问题在于管理 UI 中的字段顺序 - 不出所料,briefcategorytags 排在来自 pageDef 的字段之前。有没有办法强加我想要的命令?喜欢titlebriefcontent&lt;the rest&gt;

【问题讨论】:

    标签: node.js lodash keystonejs


    【解决方案1】:

    defaultsdefaultsDeep 改变作为参数传递给它的第一个对象(Keystone 字段的初始对象)。要拥有自己的顺序,您需要按照您希望它们在对象中出现的顺序以及它们在管理 UI 中出现的顺序将对象传递给 _.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));
    

    【讨论】:

    • 就是这样!我坚持搜索一些字段定义属性,例如“ordering:x”或其他东西,但您的解决方案更简单但更聪明。我将其扩展为涵盖将实体页面划分为带有标题的部分,但当然要归功于您:) 感谢您的帮助!
    【解决方案2】:

    上面的答案原来是要走的路。所以我扩展并建立在它之上:

    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() 获取一组字段集和未指定数量的字段定义对象(如 ownDefdefs)。

    字段集是字符串或字段名称数组(定义对象中的键)。如果它是字符串,它将是 Admin UI 中的标题,如果它是数组,那么它将是一组字段,就像数组中的字段名称一样 - 该函数基本上将字段定义插入到 fieldset 中指定的“槽”中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-04
      • 1970-01-01
      • 2012-03-17
      相关资源
      最近更新 更多