877 lines
25 KiB
JavaScript
877 lines
25 KiB
JavaScript
// Register all the things
|
|
window.CMS.registerBackend('git-gateway', window.CMS.GitGatewayBackend);
|
|
window.CMS.registerBackend('proxy', window.CMS.ProxyBackend);
|
|
window.CMS.registerBackend('test-repo', window.CMS.TestBackend);
|
|
window.CMS.registerWidget([
|
|
window.CMS.StringWidget.Widget(),
|
|
window.CMS.NumberWidget.Widget(),
|
|
window.CMS.TextWidget.Widget(),
|
|
window.CMS.ImageWidget.Widget(),
|
|
window.CMS.FileWidget.Widget(),
|
|
window.CMS.SelectWidget.Widget(),
|
|
window.CMS.MarkdownWidget.Widget(),
|
|
window.CMS.ListWidget.Widget(),
|
|
window.CMS.ObjectWidget.Widget(),
|
|
window.CMS.RelationWidget.Widget(),
|
|
window.CMS.BooleanWidget.Widget(),
|
|
window.CMS.DateTimeWidget.Widget(),
|
|
window.CMS.ColorStringWidget.Widget(),
|
|
]);
|
|
window.CMS.registerEditorComponent(window.CMS.imageEditorComponent);
|
|
window.CMS.registerEditorComponent({
|
|
id: 'code-block',
|
|
label: 'Code Block',
|
|
widget: 'code',
|
|
type: 'code-block',
|
|
});
|
|
window.CMS.registerLocale('en', window.CMS.locales.en);
|
|
|
|
Object.keys(window.CMS.images).forEach(iconName => {
|
|
window.CMS.registerIcon(iconName, window.h(window.CMS.Icon, { type: iconName }));
|
|
});
|
|
|
|
window.CMS.init({
|
|
config: {
|
|
backend: {
|
|
name: 'test-repo',
|
|
},
|
|
site_url: 'https://example.com',
|
|
media_folder: 'assets/uploads',
|
|
publish_mode: 'editorial_workflow',
|
|
collections: [
|
|
{
|
|
name: 'posts',
|
|
label: 'Posts',
|
|
label_singular: 'Post',
|
|
description:
|
|
'The description is a great place for tone setting, high level information, and editing guidelines that are specific to a collection.\n',
|
|
folder: '_posts',
|
|
slug: '{{year}}-{{month}}-{{day}}-{{slug}}',
|
|
summary: '{{title}} -- {{year}}/{{month}}/{{day}}',
|
|
sortable_fields: {
|
|
fields: ['title', 'date'],
|
|
default: {
|
|
field: 'title'
|
|
}
|
|
},
|
|
create: true,
|
|
view_filters: [
|
|
{
|
|
label: 'Posts With Index',
|
|
field: 'title',
|
|
pattern: 'This is post #',
|
|
},
|
|
{
|
|
label: 'Posts Without Index',
|
|
field: 'title',
|
|
pattern: 'front matter post',
|
|
},
|
|
{
|
|
label: 'Drafts',
|
|
field: 'draft',
|
|
pattern: true,
|
|
},
|
|
],
|
|
view_groups: [
|
|
{
|
|
label: 'Year',
|
|
field: 'date',
|
|
pattern: '\\d{4}',
|
|
},
|
|
{
|
|
label: 'Drafts',
|
|
field: 'draft',
|
|
},
|
|
],
|
|
fields: [
|
|
{
|
|
label: 'Title',
|
|
name: 'title',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Draft',
|
|
name: 'draft',
|
|
widget: 'boolean',
|
|
default: false,
|
|
},
|
|
{
|
|
label: 'Publish Date',
|
|
name: 'date',
|
|
widget: 'datetime',
|
|
date_format: 'yyyy-MM-dd',
|
|
time_format: 'HH:mm',
|
|
format: 'yyyy-MM-dd HH:mm',
|
|
},
|
|
{
|
|
label: 'Cover Image',
|
|
name: 'image',
|
|
widget: 'image',
|
|
required: false,
|
|
},
|
|
{
|
|
label: 'Body',
|
|
name: 'body',
|
|
widget: 'text',
|
|
hint: 'Main content goes here.',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'faq',
|
|
label: 'FAQ',
|
|
folder: '_faqs',
|
|
create: true,
|
|
fields: [
|
|
{
|
|
label: 'Question',
|
|
name: 'title',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Answer',
|
|
name: 'body',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
name: 'posts',
|
|
label: 'Posts',
|
|
label_singular: 'Post',
|
|
widget: 'list',
|
|
summary: "{{fields.post | split('|', '$1')}}",
|
|
fields: [
|
|
{
|
|
label: 'Related Post',
|
|
name: 'post',
|
|
widget: 'relationKitchenSinkPost',
|
|
collection: 'posts',
|
|
display_fields: ['title', 'date'],
|
|
search_fields: ['title', 'body'],
|
|
value_field: '{{title}}|{{date}}',
|
|
}
|
|
]
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'settings',
|
|
label: 'Settings',
|
|
delete: false,
|
|
editor: {
|
|
preview: false,
|
|
},
|
|
files: [
|
|
{
|
|
name: 'general',
|
|
label: 'Site Settings',
|
|
file: '_data/settings.json',
|
|
description: 'General Site Settings',
|
|
fields: [
|
|
{
|
|
label: 'Number of posts on frontpage',
|
|
name: 'front_limit',
|
|
widget: 'number',
|
|
min: 1,
|
|
max: 10,
|
|
},
|
|
{
|
|
label: 'Global title',
|
|
name: 'site_title',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Post Settings',
|
|
name: 'posts',
|
|
widget: 'object',
|
|
fields: [
|
|
{
|
|
label: 'Number of posts on frontpage',
|
|
name: 'front_limit',
|
|
widget: 'number',
|
|
min: 1,
|
|
max: 10,
|
|
},
|
|
{
|
|
label: 'Default Author',
|
|
name: 'author',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Default Thumbnail',
|
|
name: 'thumb',
|
|
widget: 'image',
|
|
required: false,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'authors',
|
|
label: 'Authors',
|
|
file: '_data/authors.yml',
|
|
description: 'Author descriptions',
|
|
fields: [
|
|
{
|
|
name: 'authors',
|
|
label: 'Authors',
|
|
label_singular: 'Author',
|
|
widget: 'list',
|
|
fields: [
|
|
{
|
|
label: 'Name',
|
|
name: 'name',
|
|
widget: 'string',
|
|
hint: 'First and Last',
|
|
},
|
|
{
|
|
label: 'Description',
|
|
name: 'description',
|
|
widget: 'text',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'kitchenSink',
|
|
label: 'Kitchen Sink',
|
|
folder: '_sink',
|
|
create: true,
|
|
fields: [
|
|
{
|
|
label: 'Related Post',
|
|
name: 'post',
|
|
widget: 'relationKitchenSinkPost',
|
|
collection: 'posts',
|
|
display_fields: ['title', 'date'],
|
|
search_fields: ['title', 'body'],
|
|
value_field: 'title',
|
|
},
|
|
{
|
|
label: 'Title',
|
|
name: 'title',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Boolean',
|
|
name: 'boolean',
|
|
widget: 'boolean',
|
|
default: true,
|
|
},
|
|
{
|
|
label: 'Map',
|
|
name: 'map',
|
|
widget: 'map',
|
|
},
|
|
{
|
|
label: 'Text',
|
|
name: 'text',
|
|
widget: 'text',
|
|
hint: 'Plain text, not markdown',
|
|
},
|
|
{
|
|
label: 'Number',
|
|
name: 'number',
|
|
widget: 'number',
|
|
hint: 'To infinity and beyond!',
|
|
},
|
|
{
|
|
label: 'Markdown',
|
|
name: 'markdown',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Datetime',
|
|
name: 'datetime',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Date',
|
|
name: 'date',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Color',
|
|
name: 'color',
|
|
widget: 'color',
|
|
},
|
|
{
|
|
label: 'Color string editable and alpha enabled',
|
|
name: 'colorEditable',
|
|
widget: 'color',
|
|
enableAlpha: true,
|
|
allowInput: true,
|
|
},
|
|
{
|
|
label: 'Image',
|
|
name: 'image',
|
|
widget: 'image',
|
|
},
|
|
{
|
|
label: 'File',
|
|
name: 'file',
|
|
widget: 'file',
|
|
},
|
|
{
|
|
label: 'Select',
|
|
name: 'select',
|
|
widget: 'select',
|
|
options: ['a', 'b', 'c'],
|
|
},
|
|
{
|
|
label: 'Select multiple',
|
|
name: 'select_multiple',
|
|
widget: 'select',
|
|
options: ['a', 'b', 'c'],
|
|
multiple: true,
|
|
},
|
|
{
|
|
label: 'Select numeric',
|
|
name: 'select_numeric',
|
|
widget: 'select',
|
|
options: [
|
|
{
|
|
label: 'One',
|
|
value: 1,
|
|
},
|
|
{
|
|
label: 'Two',
|
|
value: 2,
|
|
},
|
|
{
|
|
label: 'Three',
|
|
value: 3,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Hidden',
|
|
name: 'hidden',
|
|
widget: 'hidden',
|
|
default: 'hidden',
|
|
},
|
|
{
|
|
label: 'Object',
|
|
name: 'object',
|
|
widget: 'object',
|
|
collapsed: true,
|
|
fields: [
|
|
{
|
|
label: 'Related Post',
|
|
name: 'post',
|
|
widget: 'relationKitchenSinkPost',
|
|
collection: 'posts',
|
|
search_fields: ['title', 'body'],
|
|
value_field: 'title',
|
|
},
|
|
{
|
|
label: 'String',
|
|
name: 'string',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Boolean',
|
|
name: 'boolean',
|
|
widget: 'boolean',
|
|
default: false,
|
|
},
|
|
{
|
|
label: 'Text',
|
|
name: 'text',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
label: 'Number',
|
|
name: 'number',
|
|
widget: 'number',
|
|
},
|
|
{
|
|
label: 'Markdown',
|
|
name: 'markdown',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
label: 'Datetime',
|
|
name: 'datetime',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Date',
|
|
name: 'date',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Image',
|
|
name: 'image',
|
|
widget: 'image',
|
|
},
|
|
{
|
|
label: 'File',
|
|
name: 'file',
|
|
widget: 'file',
|
|
},
|
|
{
|
|
label: 'Select',
|
|
name: 'select',
|
|
widget: 'select',
|
|
options: ['a', 'b', 'c'],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'List',
|
|
name: 'list',
|
|
widget: 'list',
|
|
fields: [
|
|
{
|
|
label: 'String',
|
|
name: 'string',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Boolean',
|
|
name: 'boolean',
|
|
widget: 'boolean',
|
|
},
|
|
{
|
|
label: 'Text',
|
|
name: 'text',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
label: 'Number',
|
|
name: 'number',
|
|
widget: 'number',
|
|
},
|
|
{
|
|
label: 'Markdown',
|
|
name: 'markdown',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
label: 'Datetime',
|
|
name: 'datetime',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Date',
|
|
name: 'date',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Image',
|
|
name: 'image',
|
|
widget: 'image',
|
|
},
|
|
{
|
|
label: 'File',
|
|
name: 'file',
|
|
widget: 'file',
|
|
},
|
|
{
|
|
label: 'Select',
|
|
name: 'select',
|
|
widget: 'select',
|
|
options: ['a', 'b', 'c'],
|
|
},
|
|
{
|
|
label: 'Object',
|
|
name: 'object',
|
|
widget: 'object',
|
|
fields: [
|
|
{
|
|
label: 'String',
|
|
name: 'string',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Boolean',
|
|
name: 'boolean',
|
|
widget: 'boolean',
|
|
},
|
|
{
|
|
label: 'Text',
|
|
name: 'text',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
label: 'Number',
|
|
name: 'number',
|
|
widget: 'number',
|
|
},
|
|
{
|
|
label: 'Markdown',
|
|
name: 'markdown',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
label: 'Datetime',
|
|
name: 'datetime',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Date',
|
|
name: 'date',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Image',
|
|
name: 'image',
|
|
widget: 'image',
|
|
},
|
|
{
|
|
label: 'File',
|
|
name: 'file',
|
|
widget: 'file',
|
|
},
|
|
{
|
|
label: 'Select',
|
|
name: 'select',
|
|
widget: 'select',
|
|
options: ['a', 'b', 'c'],
|
|
},
|
|
{
|
|
label: 'List',
|
|
name: 'list',
|
|
widget: 'list',
|
|
fields: [
|
|
{
|
|
label: 'Related Post',
|
|
name: 'post',
|
|
widget: 'relationKitchenSinkPost',
|
|
collection: 'posts',
|
|
search_fields: ['title', 'body'],
|
|
value_field: 'title',
|
|
},
|
|
{
|
|
label: 'String',
|
|
name: 'string',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Boolean',
|
|
name: 'boolean',
|
|
widget: 'boolean',
|
|
},
|
|
{
|
|
label: 'Text',
|
|
name: 'text',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
label: 'Number',
|
|
name: 'number',
|
|
widget: 'number',
|
|
},
|
|
{
|
|
label: 'Markdown',
|
|
name: 'markdown',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
label: 'Datetime',
|
|
name: 'datetime',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Date',
|
|
name: 'date',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Image',
|
|
name: 'image',
|
|
widget: 'image',
|
|
},
|
|
{
|
|
label: 'File',
|
|
name: 'file',
|
|
widget: 'file',
|
|
},
|
|
{
|
|
label: 'Select',
|
|
name: 'select',
|
|
widget: 'select',
|
|
options: ['a', 'b', 'c'],
|
|
},
|
|
{
|
|
label: 'Hidden',
|
|
name: 'hidden',
|
|
widget: 'hidden',
|
|
default: 'hidden',
|
|
},
|
|
{
|
|
label: 'Object',
|
|
name: 'object',
|
|
widget: 'object',
|
|
fields: [
|
|
{
|
|
label: 'String',
|
|
name: 'string',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Boolean',
|
|
name: 'boolean',
|
|
widget: 'boolean',
|
|
},
|
|
{
|
|
label: 'Text',
|
|
name: 'text',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
label: 'Number',
|
|
name: 'number',
|
|
widget: 'number',
|
|
},
|
|
{
|
|
label: 'Markdown',
|
|
name: 'markdown',
|
|
widget: 'text',
|
|
},
|
|
{
|
|
label: 'Datetime',
|
|
name: 'datetime',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Date',
|
|
name: 'date',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Image',
|
|
name: 'image',
|
|
widget: 'image',
|
|
},
|
|
{
|
|
label: 'File',
|
|
name: 'file',
|
|
widget: 'file',
|
|
},
|
|
{
|
|
label: 'Select',
|
|
name: 'select',
|
|
widget: 'select',
|
|
options: ['a', 'b', 'c'],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Typed List',
|
|
name: 'typed_list',
|
|
widget: 'list',
|
|
types: [
|
|
{
|
|
label: 'Type 1 Object',
|
|
name: 'type_1_object',
|
|
widget: 'object',
|
|
fields: [
|
|
{
|
|
label: 'String',
|
|
name: 'string',
|
|
widget: 'string',
|
|
},
|
|
{
|
|
label: 'Boolean',
|
|
name: 'boolean',
|
|
widget: 'boolean',
|
|
},
|
|
{
|
|
label: 'Text',
|
|
name: 'text',
|
|
widget: 'text',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Type 2 Object',
|
|
name: 'type_2_object',
|
|
widget: 'object',
|
|
fields: [
|
|
{
|
|
label: 'Number',
|
|
name: 'number',
|
|
widget: 'number',
|
|
},
|
|
{
|
|
label: 'Select',
|
|
name: 'select',
|
|
widget: 'select',
|
|
options: ['a', 'b', 'c'],
|
|
},
|
|
{
|
|
label: 'Datetime',
|
|
name: 'datetime',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Markdown',
|
|
name: 'markdown',
|
|
widget: 'text',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Type 3 Object',
|
|
name: 'type_3_object',
|
|
widget: 'object',
|
|
fields: [
|
|
{
|
|
label: 'Date',
|
|
name: 'date',
|
|
widget: 'datetime',
|
|
},
|
|
{
|
|
label: 'Image',
|
|
name: 'image',
|
|
widget: 'image',
|
|
},
|
|
{
|
|
label: 'File',
|
|
name: 'file',
|
|
widget: 'file',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
});
|
|
|
|
const PostPreview = window.createClass({
|
|
render: function () {
|
|
var entry = this.props.entry;
|
|
return window.h(
|
|
'div',
|
|
{},
|
|
window.h(
|
|
'div',
|
|
{ className: 'cover' },
|
|
window.h('h1', {}, entry.getIn(['data', 'title'])),
|
|
this.props.widgetFor('image'),
|
|
),
|
|
window.h('p', {}, window.h('small', {}, 'Written ' + entry.getIn(['data', 'date']))),
|
|
window.h('div', { className: 'text' }, this.props.widgetFor('body')),
|
|
);
|
|
},
|
|
});
|
|
|
|
const GeneralPreview = window.createClass({
|
|
render: function () {
|
|
const entry = this.props.entry;
|
|
const title = entry.getIn(['data', 'site_title']);
|
|
const posts = entry.getIn(['data', 'posts']);
|
|
const thumb = posts && posts.get('thumb');
|
|
|
|
return window.h(
|
|
'div',
|
|
{},
|
|
window.h('h1', {}, title),
|
|
window.h(
|
|
'dl',
|
|
{},
|
|
window.h('dt', {}, 'Posts on Frontpage'),
|
|
window.h('dd', {}, this.props.widgetsFor('posts').getIn(['widgets', 'front_limit']) || 0),
|
|
|
|
window.h('dt', {}, 'Default Author'),
|
|
window.h('dd', {}, this.props.widgetsFor('posts').getIn(['data', 'author']) || 'None'),
|
|
|
|
window.h('dt', {}, 'Default Thumbnail'),
|
|
window.h(
|
|
'dd',
|
|
{},
|
|
thumb && window.h('img', { src: this.props.getAsset(thumb).toString() }),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
});
|
|
const AuthorsPreview = window.createClass({
|
|
render: function () {
|
|
return window.h(
|
|
'div',
|
|
{},
|
|
window.h('h1', {}, 'Authors'),
|
|
this.props.widgetsFor('authors').map(function (author, index) {
|
|
return window.h(
|
|
'div',
|
|
{ key: index },
|
|
window.h('hr', {}),
|
|
window.h('strong', {}, author.getIn(['data', 'name'])),
|
|
author.getIn(['widgets', 'description']),
|
|
);
|
|
}),
|
|
);
|
|
},
|
|
});
|
|
|
|
const RelationKitchenSinkPostPreview = window.createClass({
|
|
render: function () {
|
|
// When a post is selected from the relation field, all of it's data
|
|
// will be available in the field's metadata nested under the collection
|
|
// name, and then further nested under the value specified in `value_field`.
|
|
// In this case, the post would be nested under "posts" and then under
|
|
// the title of the selected post, since our `value_field` in the config
|
|
// is "title".
|
|
const { value, fieldsMetaData } = this.props;
|
|
const post = fieldsMetaData && fieldsMetaData.getIn(['posts', value]);
|
|
const style = { border: '2px solid #ccc', borderRadius: '8px', padding: '20px' };
|
|
return post
|
|
? window.h(
|
|
'div',
|
|
{ style: style },
|
|
window.h('h2', {}, 'Related Post'),
|
|
window.h('h3', {}, post.get('title')),
|
|
window.h('img', { src: post.get('image') }),
|
|
window.h('p', {}, post.get('body', '').slice(0, 100) + '...'),
|
|
)
|
|
: null;
|
|
},
|
|
});
|
|
|
|
const previewStyles = `
|
|
html,
|
|
body {
|
|
color: #444;
|
|
font-size: 14px;
|
|
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
}
|
|
|
|
body {
|
|
padding: 20px;
|
|
}
|
|
|
|
h1 {
|
|
margin-top: 20px;
|
|
color: #666;
|
|
font-weight: bold;
|
|
font-size: 32px;
|
|
}
|
|
|
|
img {
|
|
max-width: 100%;
|
|
}
|
|
`;
|
|
|
|
window.CMS.registerPreviewTemplate('posts', PostPreview);
|
|
window.CMS.registerPreviewTemplate('general', GeneralPreview);
|
|
window.CMS.registerPreviewTemplate('authors', AuthorsPreview);
|
|
window.CMS.registerPreviewStyle(previewStyles, { raw: true });
|
|
// Pass the name of a registered control to reuse with a new widget preview.
|
|
window.CMS.registerWidget('relationKitchenSinkPost', 'relation', RelationKitchenSinkPostPreview);
|
|
window.CMS.registerAdditionalLink('example', 'Example.com', 'https://example.com', 'page');
|