Feature/docs (#67)

This commit is contained in:
Daniel Lautzenheiser
2022-11-04 17:41:12 -04:00
committed by GitHub
parent 7a1ec55a5c
commit 81ca566b5e
152 changed files with 1862 additions and 3832 deletions

View File

@ -1,471 +0,0 @@
backend:
name: azure
branch: master
repo: organization/project/repo # replace with actual path
tenant_id: tenantId # replace with your tenantId
app_id: appId # replace with your appId
media_folder: static/media
public_folder: /media
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.
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: markdown
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: markdown
- 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: markdown
- label: Datetime
name: datetime
widget: datetime
- label: Color
name: color
widget: color
- label: Color string editable and alpha enabled
name: colorEditable
widget: color
enable_alpha: true
allow_input: 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: markdown
- label: Datetime
name: datetime
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: markdown
- label: Datetime
name: datetime
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: markdown
- label: Datetime
name: datetime
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: 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: 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: Image
name: image
widget: image
- label: File
name: file
widget: file

View File

@ -1,12 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Static CMS - Azure Development Test</title>
</head>
<body>
<script src="/static-cms-core.js"></script>
<script type="module" src="/index.js"></script>
</body>
</html>

View File

@ -497,6 +497,8 @@ collections:
label: Site Settings
file: _data/settings.json
description: General Site Settings
editor:
preview: true
fields:
- label: Number of posts on frontpage
name: front_limit
@ -526,6 +528,8 @@ collections:
label: Authors
file: _data/authors.yml
description: Author descriptions
editor:
preview: true
fields:
- name: authors
label: Authors

View File

@ -1,98 +1,104 @@
// Register all the things
CMS.init();
const PostPreview = createClass({
render: function () {
var entry = this.props.entry;
return h(
'div',
const PostPreview = ({ entry, widgetFor }) => {
return h(
'div',
{},
h('div', { className: 'cover' }, h('h1', {}, entry.data.title), widgetFor('image')),
h('p', {}, h('small', {}, 'Written ' + entry.data.date)),
h('div', { className: 'text' }, widgetFor('body')),
);
};
const GeneralPreview = ({ widgetsFor, getAsset, entry }) => {
const title = entry.data.site_title;
const posts = entry.data.posts;
const thumb = posts && posts.thumb;
const [thumbUrl, setThumbUrl] = useState('');
useEffect(() => {
let alive = true;
const loadThumb = async () => {
const thumbAsset = await getAsset(thumb);
if (alive) {
setThumbUrl(thumbAsset.toString());
}
};
loadThumb();
return () => {
alive = false;
};
}, [thumb]);
return h(
'div',
{},
h('h1', {}, title),
h(
'dl',
{},
h(
h('dt', {}, 'Posts on Frontpage'),
h('dd', {}, widgetsFor('posts').widgets.front_limit ?? 0),
h('dt', {}, 'Default Author'),
h('dd', {}, widgetsFor('posts').data?.author ?? 'None'),
h('dt', {}, 'Default Thumbnail'),
h('dd', {}, thumb && h('img', { src: thumbUrl })),
),
);
};
const AuthorsPreview = ({ widgetsFor }) => {
return h(
'div',
{},
h('h1', {}, 'Authors'),
widgetsFor('authors').map(function (author, index) {
return h(
'div',
{ className: 'cover' },
h('h1', {}, entry.data.title),
this.props.widgetFor('image'),
),
h('p', {}, h('small', {}, 'Written ' + entry.data.date)),
h('div', { className: 'text' }, this.props.widgetFor('body')),
);
},
});
{ key: index },
h('hr', {}),
h('strong', {}, author.data.name),
author.widgets.description,
);
}),
);
};
// TODO Hook this back up, getAsset returns a promise now
const GeneralPreview = createClass({
render: function () {
const entry = this.props.entry;
const title = entry.data.site_title;
const posts = entry.data.posts;
const thumb = posts && posts.thumb;
const RelationKitchenSinkPostPreview = ({ fieldsMetaData }) => {
// 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 post = fieldsMetaData && fieldsMetaData.posts.value;
const style = { border: '2px solid #ccc', borderRadius: '8px', padding: '20px' };
return post
? h(
'div',
{ style: style },
h('h2', {}, 'Related Post'),
h('h3', {}, post.title),
h('img', { src: post.image }),
h('p', {}, (post.body ?? '').slice(0, 100) + '...'),
)
: null;
};
return h(
'div',
{},
h('h1', {}, title),
h(
'dl',
{},
h('dt', {}, 'Posts on Frontpage'),
h('dd', {}, this.props.widgetsFor('posts').widgets.front_limit || 0),
h('dt', {}, 'Default Author'),
h('dd', {}, this.props.widgetsFor('posts').data.author || 'None'),
h('dt', {}, 'Default Thumbnail'),
h('dd', {}, thumb && h('img', { src: this.props.getAsset(thumb).toString() })),
),
);
},
});
const AuthorsPreview = createClass({
render: function () {
return h(
'div',
{},
h('h1', {}, 'Authors'),
this.props.widgetsFor('authors').map(function (author, index) {
return h(
'div',
{ key: index },
h('hr', {}),
h('strong', {}, author.data.name),
author.widgets.description,
);
}),
);
},
});
const RelationKitchenSinkPostPreview = 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.posts.value;
const style = { border: '2px solid #ccc', borderRadius: '8px', padding: '20px' };
return post
? h(
'div',
{ style: style },
h('h2', {}, 'Related Post'),
h('h3', {}, post.title),
h('img', { src: post.image }),
h('p', {}, (post.body ?? '').slice(0, 100) + '...'),
)
: null;
},
});
const CustomPage = () => {
return h('div', {}, 'I am a custom page!');
};
CMS.registerPreviewStyle('.toastui-editor-contents h1 { color: blue }', { raw: true });
CMS.registerPreviewTemplate('posts', PostPreview);
// CMS.registerPreviewTemplate('general', GeneralPreview);
CMS.registerPreviewTemplate('general', GeneralPreview);
CMS.registerPreviewTemplate('authors', AuthorsPreview);
// Pass the name of a registered control to reuse with a new widget preview.
CMS.registerWidget('relationKitchenSinkPost', 'relation', RelationKitchenSinkPostPreview);
@ -104,3 +110,11 @@ CMS.registerAdditionalLink({
icon: 'page',
},
});
CMS.registerAdditionalLink({
id: 'custom-page',
title: 'Custom Page',
data: CustomPage,
options: {
icon: 'page',
},
});