From d5998956798d5c2dbbf8a0b21a155a0bbc567476 Mon Sep 17 00:00:00 2001 From: Daniel Lautzenheiser Date: Thu, 13 Apr 2023 13:27:13 -0400 Subject: [PATCH] feat: media library cleanup (#699) --- packages/core/dev-test/config.yml | 15 +++- packages/core/src/actions/config.ts | 68 +++++++++------- packages/core/src/actions/mediaLibrary.ts | 81 ++++++++----------- packages/core/src/backend.ts | 6 +- .../editor-control-pane/EditorControl.tsx | 5 ++ .../media-library/common/MediaLibrary.tsx | 10 ++- .../common/MediaLibraryCardGrid.tsx | 27 +++++-- packages/core/src/interface.ts | 8 +- .../core/src/lib/hooks/useFolderSupport.ts | 23 ++++++ packages/core/src/lib/hooks/useMediaFiles.ts | 12 ++- packages/core/src/lib/hooks/useMediaInsert.ts | 17 +--- packages/core/src/lib/registry.ts | 2 +- packages/core/src/lib/util/collection.util.ts | 17 +++- packages/core/src/lib/util/media.util.ts | 4 +- packages/core/src/reducers/mediaLibrary.ts | 8 +- packages/core/src/valueObjects/AssetProxy.ts | 6 +- .../core/src/widgets/file/withFileControl.tsx | 8 +- packages/core/test/data/widgets.mock.ts | 1 + packages/demo/package.json | 2 +- packages/demo/public/config.yml | 14 +++- packages/docs/content/docs/beta-features.mdx | 32 +------- .../docs/content/docs/collection-overview.mdx | 36 +++++---- .../docs/content/docs/collection-types.mdx | 5 ++ .../content/docs/configuration-options.mdx | 35 +++----- .../docs/content/docs/custom-previews.mdx | 12 +-- packages/docs/content/docs/custom-widgets.mdx | 1 + .../docs/content/docs/migration-guide-v2.mdx | 25 ++++-- packages/docs/content/docs/widget-boolean.mdx | 4 +- packages/docs/content/docs/widget-code.mdx | 2 +- packages/docs/content/docs/widget-color.mdx | 2 +- .../docs/content/docs/widget-datetime.mdx | 2 +- packages/docs/content/docs/widget-file.mdx | 14 ++-- packages/docs/content/docs/widget-hidden.mdx | 2 +- packages/docs/content/docs/widget-image.mdx | 14 ++-- packages/docs/content/docs/widget-list.mdx | 2 +- packages/docs/content/docs/widget-map.mdx | 2 +- .../docs/content/docs/widget-markdown.mdx | 33 +++----- packages/docs/content/docs/widget-number.mdx | 2 +- packages/docs/content/docs/widget-object.mdx | 2 +- .../docs/content/docs/widget-relation.mdx | 2 +- packages/docs/content/docs/widget-select.mdx | 2 +- packages/docs/content/docs/widget-string.mdx | 2 +- packages/docs/content/docs/widget-text.mdx | 2 +- packages/docs/content/docs/widgets.mdx | 2 +- .../headers/components/LinkedHeader.tsx | 1 - .../table_of_contents/DocsTableOfContents.tsx | 35 ++++++-- 46 files changed, 332 insertions(+), 275 deletions(-) create mode 100644 packages/core/src/lib/hooks/useFolderSupport.ts diff --git a/packages/core/dev-test/config.yml b/packages/core/dev-test/config.yml index fca22d73..b7618768 100644 --- a/packages/core/dev-test/config.yml +++ b/packages/core/dev-test/config.yml @@ -2,7 +2,8 @@ backend: name: test-repo site_url: 'https://example.com' media_folder: assets/uploads -media_library_folder_support: true +media_library: + folder_support: true locale: en i18n: # Required and can be one of multiple_folders, multiple_files or single_file @@ -142,6 +143,7 @@ collections: label: Pattern Validation widget: code pattern: ['.{12,}', 'Must have at least 12 characters'] + allow_input: true required: false - name: language label: Language Selection @@ -279,12 +281,13 @@ collections: label: Choose URL widget: file required: false - media_library: - choose_url: true + choose_url: true - name: image label: Image file: _widgets/image.json description: Image widget + media_library: + folder_support: false fields: - name: required label: Required Validation @@ -302,8 +305,12 @@ collections: label: Choose URL widget: image required: false + choose_url: true + - name: folder_support + label: Folder Support + widget: image media_library: - choose_url: true + folder_support: true - name: list label: List file: _widgets/list.yml diff --git a/packages/core/src/actions/config.ts b/packages/core/src/actions/config.ts index 7c41ed77..dee13f7e 100644 --- a/packages/core/src/actions/config.ts +++ b/packages/core/src/actions/config.ts @@ -19,39 +19,26 @@ import type { AnyAction } from 'redux'; import type { ThunkDispatch } from 'redux-thunk'; import type { BaseField, + Collection, + CollectionFile, Config, Field, I18nInfo, - ListField, LocalBackend, - ObjectField, UnknownField, } from '../interface'; import type { RootState } from '../store'; -function isObjectField( - field: Field, -): field is ObjectField { - return 'fields' in (field as ObjectField); -} - -function isFieldList(field: Field): field is ListField { - return 'types' in (field as ListField) || 'field' in (field as ListField); -} - -function traverseFieldsJS( - fields: F[], - updater: (field: T) => T, -): F[] { +function traverseFields(fields: Field[], updater: (field: Field) => Field): Field[] { return fields.map(field => { const newField = updater(field); - if (isObjectField(newField)) { - return { ...newField, fields: traverseFieldsJS(newField.fields, updater) }; - } else if (isFieldList(newField) && newField.types) { - return { ...newField, types: traverseFieldsJS(newField.types, updater) }; + if ('fields' in newField && newField.fields) { + return { ...newField, fields: traverseFields(newField.fields, updater) } as Field; + } else if (newField.widget === 'list' && newField.types) { + return { ...newField, types: traverseFields(newField.types, updater) } as Field; } - return newField; + return newField as Field; }); } @@ -68,12 +55,21 @@ function getConfigUrl() { return 'config.yml'; } -function setDefaultPublicFolderForField(field: T) { - if ('media_folder' in field && !('public_folder' in field)) { - return { ...field, public_folder: field.media_folder }; - } - return field; -} +const setFieldDefaults = + (collection: Collection, collectionFile?: CollectionFile) => (field: Field) => { + if ('media_folder' in field && !('public_folder' in field)) { + return { ...field, public_folder: field.media_folder }; + } + + if (field.widget === 'image' || field.widget === 'file') { + field.media_library = { + ...((collectionFile ?? collection).media_library ?? {}), + ...(field.media_library ?? {}), + }; + } + + return field; + }; function setI18nField(field: T) { if (field[I18N] === true) { @@ -100,9 +96,9 @@ function getI18nDefaults(collectionOrFileI18n: boolean | I18nInfo, defaultI18n: function setI18nDefaultsForFields(collectionOrFileFields: Field[], hasI18n: boolean) { if (hasI18n) { - return traverseFieldsJS(collectionOrFileFields, setI18nField); + return traverseFields(collectionOrFileFields, setI18nField); } else { - return traverseFieldsJS(collectionOrFileFields, field => { + return traverseFields(collectionOrFileFields, field => { const newField = { ...field }; delete newField[I18N]; return newField; @@ -174,6 +170,11 @@ export function applyDefaults(originalConfig: Config) { collection.editor = { preview: config.editor.preview, frame: config.editor.frame }; } + collection.media_library = { + ...(config.media_library ?? {}), + ...(collection.media_library ?? {}), + }; + if (i18n && collectionI18n) { collectionI18n = getI18nDefaults(collectionI18n, i18n); collection[I18N] = collectionI18n; @@ -199,7 +200,7 @@ export function applyDefaults(originalConfig: Config) { } if ('fields' in collection && collection.fields) { - collection.fields = traverseFieldsJS(collection.fields, setDefaultPublicFolderForField); + collection.fields = traverseFields(collection.fields, setFieldDefaults(collection)); } collection.folder = trim(collection.folder, '/'); @@ -215,8 +216,13 @@ export function applyDefaults(originalConfig: Config) { file.public_folder = file.media_folder; } + file.media_library = { + ...(collection.media_library ?? {}), + ...(file.media_library ?? {}), + }; + if (file.fields) { - file.fields = traverseFieldsJS(file.fields, setDefaultPublicFolderForField); + file.fields = traverseFields(file.fields, setFieldDefaults(collection, file)); } let fileI18n = file[I18N]; diff --git a/packages/core/src/actions/mediaLibrary.ts b/packages/core/src/actions/mediaLibrary.ts index d86c2d73..c9a89439 100644 --- a/packages/core/src/actions/mediaLibrary.ts +++ b/packages/core/src/actions/mediaLibrary.ts @@ -34,9 +34,11 @@ import type { ThunkDispatch } from 'redux-thunk'; import type { BaseField, Collection, + CollectionFile, DisplayURLState, Field, ImplementationMediaFile, + MediaField, MediaFile, MediaLibrarInsertOptions, MediaLibraryConfig, @@ -55,50 +57,50 @@ export function openMediaLibrary( replaceIndex?: number; config?: MediaLibraryConfig; collection?: Collection; + collectionFile?: CollectionFile; field?: EF; insertOptions?: MediaLibrarInsertOptions; } = {}, ) { - return (dispatch: ThunkDispatch) => { - const { + const { + controlID, + value, + alt, + config = {}, + allowMultiple, + forImage, + replaceIndex, + collection, + collectionFile, + field, + insertOptions, + } = payload; + + return { + type: MEDIA_LIBRARY_OPEN, + payload: { controlID, + forImage, value, alt, - config = {}, allowMultiple, - forImage, replaceIndex, - collection, - field, + config, + collection: collection as Collection, + collectionFile: collectionFile as CollectionFile, + field: field as Field, insertOptions, - } = payload; - - dispatch( - mediaLibraryOpened({ - controlID, - forImage, - value, - alt, - allowMultiple, - replaceIndex, - config, - collection: collection as Collection, - field: field as Field, - insertOptions, - }), - ); - }; + }, + } as const; } export function closeMediaLibrary() { - return (dispatch: ThunkDispatch) => { - dispatch(mediaLibraryClosed()); - }; + return { type: MEDIA_LIBRARY_CLOSE } as const; } export function insertMedia( mediaPath: string | string[], - field: Field | undefined, + field: MediaField | undefined, alt?: string, currentFolder?: string, ) { @@ -401,25 +403,6 @@ export function loadMediaDisplayURL(file: MediaFile) { }; } -function mediaLibraryOpened(payload: { - controlID?: string; - forImage?: boolean; - value?: string | string[]; - alt?: string; - replaceIndex?: number; - allowMultiple?: boolean; - config?: MediaLibraryConfig; - collection?: Collection; - field?: Field; - insertOptions?: MediaLibrarInsertOptions; -}) { - return { type: MEDIA_LIBRARY_OPEN, payload } as const; -} - -function mediaLibraryClosed() { - return { type: MEDIA_LIBRARY_CLOSE } as const; -} - export function mediaInserted(mediaPath: string | string[], alt?: string) { return { type: MEDIA_INSERT, payload: { mediaPath, alt } } as const; } @@ -432,7 +415,7 @@ export function mediaLoading(page: number) { } export interface MediaOptions { - field?: Field; + field?: MediaField; page?: number; canPaginate?: boolean; dynamicSearch?: boolean; @@ -545,8 +528,8 @@ export async function getMediaDisplayURL( } export type MediaLibraryAction = ReturnType< - | typeof mediaLibraryOpened - | typeof mediaLibraryClosed + | typeof openMediaLibrary + | typeof closeMediaLibrary | typeof mediaInserted | typeof removeInsertedMedia | typeof mediaLoading diff --git a/packages/core/src/backend.ts b/packages/core/src/backend.ts index d8bc1955..c1879232 100644 --- a/packages/core/src/backend.ts +++ b/packages/core/src/backend.ts @@ -57,9 +57,9 @@ import type { Entry, EntryData, EntryDraft, - Field, FilterRule, ImplementationEntry, + MediaField, PersistArgs, SearchQueryResponse, SearchResponse, @@ -247,7 +247,7 @@ export interface MediaFile { draft?: boolean; url?: string; file?: File; - field?: Field; + field?: MediaField; queryOrder?: unknown; isViewableImage?: boolean; type?: string; @@ -807,7 +807,7 @@ export class Backend> = ({ dynamicSearchQuery, page, collection, + collectionFile, field, value: initialValue, alt: initialAlt, @@ -463,6 +465,8 @@ const MediaLibrary: FC> = ({ const hasSelection = hasMedia && !isEmpty(selectedFile); + const folderSupport = useFolderSupport({ config, collection, collectionFile, field }); + return ( <>
@@ -484,7 +488,7 @@ const MediaLibrary: FC> = ({ px-5 pt-4 `, - config?.media_library?.folder_support && + folderSupport && ` pb-4 border-b @@ -517,7 +521,7 @@ const MediaLibrary: FC> = ({ placeholder={t('mediaLibrary.mediaLibraryModal.search')} disabled={!dynamicSearchActive && !hasFilteredFiles} /> - {config?.media_library?.folder_support ? ( + {folderSupport ? (
> = ({ ) : null}
- {config?.media_library?.folder_support ? ( + {folderSupport ? (
-```yaml -- label: 'Featured Image' - name: 'thumbnail' - widget: 'image' - default: '/uploads/chocolate-dogecoin.jpg' - media_library: - max_file_size: 512000 # in bytes, only for default media library -``` +## Media Library Folders -```js -{ - label: 'Featured Image', - name: 'thumbnail', - widget: 'image', - default: '/uploads/chocolate-dogecoin.jpg', - media_library: { - max_file_size: 512000 // in bytes, only for default media library - }, -}, -``` +Adds support for viewing subfolders and creating new subfolders in the media library, under your configured `media_folder`. - +See [Media Library](/docs/configuration-options#media-library) for more information. ## Summary string template transformations @@ -188,9 +170,3 @@ Static CMS can provide a side by side interface for authoring content in multipl For repositories stored on Gitea, the gitea backend allows CMS users to log in directly with their Gitea account. Note that all users must have push access to your content repository for this to work. See [Gitea Backend](/docs/gitea-backend) for more information. - -## Media Library Folders - -Adds support for viewing subfolders and creating new subfolders in the media library, under your configured `media_folder`. - -See [Media Library Folders](/docs/configuration-options#media-library-folders) for more information. diff --git a/packages/docs/content/docs/collection-overview.mdx b/packages/docs/content/docs/collection-overview.mdx index 86102521..b17d9cc9 100644 --- a/packages/docs/content/docs/collection-overview.mdx +++ b/packages/docs/content/docs/collection-overview.mdx @@ -31,7 +31,7 @@ weight: 9 | view_filters | ViewFilter | | _Optional_. See [view_filters](#view_filters) below | | view_groups | ViewGroup | | _Optional_. See [view_groups](#view_groups) below | -## `identifier_field` +## Identifier Field Static CMS expects every entry to provide a field named `"title"` that serves as an identifier for the entry. The identifier field serves as an entry's title when viewing a list of entries, and is used in [slug](#slug) creation. If you would like to use a field other than `"title"` as the identifier, you can set `identifier_field` to the name of the other field. @@ -53,7 +53,7 @@ collections: [ -## `extension` and `format` +## Extension and Format These settings determine how collection files are parsed and saved. Both are optional—Static CMS will attempt to infer your settings based on existing items in the collection. If your collection is empty, or you'd like more control, you can set these fields explicitly. @@ -69,11 +69,11 @@ You may also specify a custom `extension` not included in the list above, as lon - `yaml-frontmatter`: same as the `frontmatter` format above, except frontmatter will be both parsed and saved only as YAML, followed by unparsed body text. The default delimiter for this option is `---`. - `json-frontmatter`: same as the `frontmatter` format above, except frontmatter will be both parsed and saved as JSON, followed by unparsed body text. The default delimiter for this option is `{` `}`. -## `frontmatter_delimiter` +## Frontmatter Delimiter -If you have an explicit frontmatter format declared, this option allows you to specify a custom delimiter like `~~~`. If you need different beginning and ending delimiters, you can use an array like `["(", ")"]`. +If you have an explicit frontmatter format declared, the `frontmatter_delimiter` option allows you to specify a custom delimiter like `~~~`. If you need different beginning and ending delimiters, you can use an array like `["(", ")"]`. -## `slug` +## Slug For folder collections where users can create new items, the `slug` option specifies a template for generating new filenames based on a file's creation date and `title` field. (This means that all collections with `create: true` must have a `title` field (a different field can be used via [`identifier_field`](#identifier_field)). @@ -131,7 +131,7 @@ slug: '{{year}}-{{month}}-{{day}}_{{fields.slug}}', -## `fields` +## Fields _Ignored if [Files Collection](/docs/collection-types#file-collections)_ @@ -164,9 +164,9 @@ fields: [ -## `editor` +## Editor -This setting changes options for the editor view of a collection or a file inside a files collection. It has the following options: +The `editor` setting changes options for the editor view of a collection or a file inside a files collection. It has the following options: | Name | Type | Default | Description | | ------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------ | @@ -191,9 +191,9 @@ editor: { **Note**: Setting this as a top level configuration will set the default for all collections -## `summary` +## Summary -This setting allows the customization of the collection table view. Similar to the `slug` field, a string with templates can be used to include values of different fields, e.g. `{{title}}`. This option over-rides the default of `title` field and `identifier_field`. +The `summary` setting allows the customization of the collection table view. Similar to the `slug` field, a string with templates can be used to include values of different fields, e.g. `{{title}}`. This option over-rides the default of `title` field and `identifier_field`. **Available Template Tags** @@ -216,9 +216,9 @@ summary: 'Version: {{version}} - {{title}}', -## `sortable_fields` +## Sortable Fields -An optional object with the following options: +The `sortable_fields` setting is an optional object with the following options: | Name | Type | Default | Description | | ------- | --------------------- | ------- | ----------------------------------------------------------------------------------------------------------------- | @@ -275,9 +275,9 @@ sortable_fields: { -## `view_filters` +## View Filters -An optional list of predefined view filters to show in the UI. +The `view_filters` setting is an optional list of predefined view filters to show in the UI. Defaults to an empty list. @@ -317,9 +317,9 @@ view_filters: [ -## `view_groups` +## View Groups -An optional list of predefined view groups to show in the UI. +The `view_groups` setting is an optional list of predefined view groups to show in the UI. Defaults to an empty list. @@ -349,3 +349,7 @@ view_groups: [ ``` + +## Media Library + +The `media_library` settings allows customization of the media library at the collection level. See [Media Library](/docs/configuration-options#media-library) for more details. diff --git a/packages/docs/content/docs/collection-types.mdx b/packages/docs/content/docs/collection-types.mdx index 7f0f498b..d615c530 100644 --- a/packages/docs/content/docs/collection-types.mdx +++ b/packages/docs/content/docs/collection-types.mdx @@ -392,6 +392,8 @@ collections: - name: about label: About Page file: site/content/about.yml + media_library: + folder_support: true fields: - name: title label: Title @@ -444,6 +446,9 @@ collections: [ name: 'about', label: 'About Page', file: 'site/content/about.yml', + media_library: { + folder_support: true + }, fields: [ { name: 'title', label: 'Title', widget: 'string' }, { name: 'intro', label: 'Intro', widget: 'markdown' }, diff --git a/packages/docs/content/docs/configuration-options.mdx b/packages/docs/content/docs/configuration-options.mdx index ca5438fc..139d9f60 100644 --- a/packages/docs/content/docs/configuration-options.mdx +++ b/packages/docs/content/docs/configuration-options.mdx @@ -67,16 +67,22 @@ Based on the settings above, if a user used an image widget field called `avatar This setting can be set to an absolute URL e.g. `https://netlify.com/media` should you wish, however in general this is not advisable as content should have relative paths to other content. -## Media Library +## Media Library -Media library integrations are configured via the `media_library` property, and its value should be an object with at least a `name` property. A `config` property can also be used for options that should be passed to the library in use. +The `media_library` settings allows customization of the media library. -**Example:** +### Options + +| Name | Type | Default | Description | +| -------------- | ------- | -------- | -------------------------------------------------------------------------------------- | +| max_file_size | number | `512000` | _Optional_. The max size, in bytes, of files that can be uploaded to the media library | +| folder_support | boolean | `false` | _Optional_. Enables directory navigation and folder creation in your media library | + +### Example ```yaml media_library: - choose_url: true, max_file_size: 512000 folder_support: true ``` @@ -84,7 +90,6 @@ media_library: ```js { media_library: { - choose_url: "true,", max_file_size: 512000, folder_support: true } @@ -93,26 +98,6 @@ media_library: -### Media Library Folders - -The `folder_support` flag enables support for viewing subfolders and creating new subfolders in the media library, under your configured `media_folder`. - - -```yaml -media_library: - folder_support: true -``` - -```js -{ - media_library: { - folder_support: true; - } -} -``` - - - ## Site URL The `site_url` setting should provide a URL to your published site. May be used by Static CMS for various functionality. Used together with a collection's `preview_path` to create links to live content. diff --git a/packages/docs/content/docs/custom-previews.mdx b/packages/docs/content/docs/custom-previews.mdx index 17555e0d..d0f41e05 100644 --- a/packages/docs/content/docs/custom-previews.mdx +++ b/packages/docs/content/docs/custom-previews.mdx @@ -16,7 +16,7 @@ However, although possible, it may be cumbersome or even impractical to add a Re `registerPreviewTemplate` allows you to create a template that overrides the entire editor preview for a given collection. -### `registerPreviewTemplate` Params +### Params | Param | Type | Description | | --------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | @@ -36,7 +36,7 @@ The following parameters will be passed to your `react_component` during render: | widgetsFor | Function | Given a field name, returns the rendered previews of that field's nested child widgets and values | | theme | 'light'
\| 'dark' | The current theme being used by the app | -#### `registerPreviewTemplate` Example +#### Example @@ -346,7 +346,7 @@ CMS.registerPreviewStyle('.main { color: blue; border: 1px solid gree; }', { raw `registerPreviewCard` allows you to create a card template that overrides the cards displayed in the collection view. -### `registerPreviewCard` Params +### Params | Param | Type | Description | | --------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | @@ -362,7 +362,7 @@ The following parameters will be passed to your `react_component` during render: | widgetsFor | Function | Given a field name, returns the rendered previews of that field's nested child widgets and values | | theme | 'light'
\| 'dark' | The current theme being used by the app | -#### `registerPreviewTemplate` Example +#### Example @@ -544,7 +544,7 @@ CMS.registerPreviewTemplate('posts', PostPreview); `registerFieldPreview` allows you to create a custom preview for a specific field in the table view for collections. -### `registerFieldPreview` Params +### Params | Param | Type | Description | | -------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | @@ -561,7 +561,7 @@ The following parameters will be passed to your `component` during render: | value | Function | The current value of the field for the given entry | | theme | 'light'
\| 'dark' | The current theme being used by the app | -#### `registerFieldPreview` Example +#### Example diff --git a/packages/docs/content/docs/custom-widgets.mdx b/packages/docs/content/docs/custom-widgets.mdx index 8c2eb16d..987e2ab0 100644 --- a/packages/docs/content/docs/custom-widgets.mdx +++ b/packages/docs/content/docs/custom-widgets.mdx @@ -46,6 +46,7 @@ The react component that renders the control. It receives the following props: | onChange | function | Function to be called when the value changes. Accepts a valid widget value | | field | object | The field configuration for the current widget. See [Widget Options](/docs/widgets#common-widget-options) | | collection | object | The collection configuration for the current widget. See [Collections](/docs/collection-overview) | +| collectionFile | object | The collection file configuration for the current widget if entry is part of a [File Collection](/docs/collection-types#file-collections) | | config | object | The current Static CMS config. See [configuration options](/docs/configuration-options) | | entry | object | Object with a `data` field that contains the current value of all widgets in the editor | | path | string | `.` separated string donating the path to the current widget within the entry | diff --git a/packages/docs/content/docs/migration-guide-v2.mdx b/packages/docs/content/docs/migration-guide-v2.mdx index 5750601d..020fb81c 100644 --- a/packages/docs/content/docs/migration-guide-v2.mdx +++ b/packages/docs/content/docs/migration-guide-v2.mdx @@ -192,16 +192,20 @@ collections: ## External Media Libraries -External media integrations (Cloudinary, Netlify Large Media and Uploadcare) have been removed as part of an ongoing to effect to narrow the focus of Static CMS. With [Decap](https://decapcms.org/) (previously Netlify CMS) being supported again its not as critical for Static CMS to support every possible option. +External media integrations (Cloudinary, Netlify Large Media and Uploadcare) have been removed as part of an ongoing to effect to narrow the focus of Static CMS. With [Decap](https://decapcms.org/) (previously Netlify CMS) being supported again its not as critical for Static CMS to support every possible option. The external media integrations have been broken for sometime, and would require a lot of effort to get them back to the level already available in Decap. So, in order to focus our efforts on other features, it has been decided to remove all external media integrations. This brings with it some breaking changes for the `media_library` config property. -**Old Config** +**Old Config (for Image or File Field)** ```yaml +name: thumbnail +label: Featured Image +widget: image +default: /uploads/chocolate-dogecoin.jpg media_library: choose_url: true config: @@ -210,6 +214,10 @@ media_library: ```js { + name: "thumbnail", + label: "Featured Image", + widget: "image", + default: "/uploads/chocolate-dogecoin.jpg", media_library: { choose_url: true, config: { @@ -225,15 +233,23 @@ media_library: ```yaml +name: thumbnail +label: Featured Image +widget: image +default: /uploads/chocolate-dogecoin.jpg +choose_url: true media_library: - choose_url: true max_file_size: 512000 ``` ```js { + name: "thumbnail", + label: "Featured Image", + widget: "image", + default: "/uploads/chocolate-dogecoin.jpg", + choose_url: true, media_library: { - choose_url: true, max_file_size: 512000 } } @@ -243,7 +259,6 @@ media_library: Also the `clearMediaControl` and `removeMediaControl` widget control props have been removed as they were only used for the external media library integrations. - ## Other Breaking Changes - [Card previews](/docs/custom-previews#collection-card-preview) now are only used for the card view. The `viewStyle` property has been removed. [Field previews](/docs/custom-previews#field-preview) can be used to change the table view. diff --git a/packages/docs/content/docs/widget-boolean.mdx b/packages/docs/content/docs/widget-boolean.mdx index 33081790..4ee08191 100644 --- a/packages/docs/content/docs/widget-boolean.mdx +++ b/packages/docs/content/docs/widget-boolean.mdx @@ -10,7 +10,7 @@ weight: 10 The boolean widget translates a toggle switch input to a `true` or `false` value. -## Widget options +## Widget Options For common options, see [Common widget options](/docs/widgets#common-widget-options). @@ -35,4 +35,4 @@ widget: 'boolean', default: true, ``` - \ No newline at end of file + diff --git a/packages/docs/content/docs/widget-code.mdx b/packages/docs/content/docs/widget-code.mdx index 585b7ff3..a138cbfa 100644 --- a/packages/docs/content/docs/widget-code.mdx +++ b/packages/docs/content/docs/widget-code.mdx @@ -10,7 +10,7 @@ weight: 11 The code widget provides a code editor (powered by [Codemirror](https://codemirror.net)) with optional syntax awareness. Can output the raw code value or an object with the selected language and the raw code value. -## Widget options +## Widget Options For common options, see [Common widget options](/docs/widgets#common-widget-options). diff --git a/packages/docs/content/docs/widget-color.mdx b/packages/docs/content/docs/widget-color.mdx index cc7c2f94..0d0aa3a0 100644 --- a/packages/docs/content/docs/widget-color.mdx +++ b/packages/docs/content/docs/widget-color.mdx @@ -10,7 +10,7 @@ weight: 12 The color widget translates a color picker to a color string. -## Widget options +## Widget Options For common options, see [Common widget options](/docs/widgets#common-widget-options). diff --git a/packages/docs/content/docs/widget-datetime.mdx b/packages/docs/content/docs/widget-datetime.mdx index 5ea0711d..9b3dd3b2 100644 --- a/packages/docs/content/docs/widget-datetime.mdx +++ b/packages/docs/content/docs/widget-datetime.mdx @@ -10,7 +10,7 @@ weight: 13 The datetime widget translates a datetime picker to a datetime string. -## Widget options +## Widget Options For common options, see [Common widget options](/docs/widgets#common-widget-options). diff --git a/packages/docs/content/docs/widget-file.mdx b/packages/docs/content/docs/widget-file.mdx index e63878da..a2eb00fd 100644 --- a/packages/docs/content/docs/widget-file.mdx +++ b/packages/docs/content/docs/widget-file.mdx @@ -10,15 +10,17 @@ weight: 14 The file widget allows editors to upload a file or select an existing one from the media library. The path to the file will be saved to the field as a string. -## Widget options +## Widget Options For common options, see [Common widget options](/docs/widgets#common-widget-options). -| Name | Type | Default | Description | -| ------------- | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -| default | string | `null` | _Optional_. The default value for the field. Accepts a string. | -| media_folder | string | | _Optional_. Specifies the folder path where uploaded files should be saved, relative to the base of the repo | -| public_folder | string | | _Optional_. Specifies the folder path where the files uploaded by the media library will be accessed, relative to the base of the built site | +| Name | Type | Default | Description | +| ------------- | --------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| default | string | `null` | _Optional_. The default value for the field. Accepts a string. | +| media_folder | string | | _Optional_. Specifies the folder path where uploaded files should be saved, relative to the base of the repo | +| public_folder | string | | _Optional_. Specifies the folder path where the files uploaded by the media library will be accessed, relative to the base of the built site | +| media_library | Media Library Options | `{}` | _Optional_. Media library settings to apply when the media library is opened by the current widget. See [Media Library](/docs/configuration-options#media-library) | +| choose_url | boolean | `false` | _Optional_. When set to `false`, the "Insert from URL" button will be hidden | ## Example diff --git a/packages/docs/content/docs/widget-hidden.mdx b/packages/docs/content/docs/widget-hidden.mdx index c838ae73..8ae06ef2 100644 --- a/packages/docs/content/docs/widget-hidden.mdx +++ b/packages/docs/content/docs/widget-hidden.mdx @@ -10,7 +10,7 @@ weight: 15 Hidden widgets do not display in the UI. In folder collections that allow users to create new items, you will often want to set a default for hidden fields, so they will be set without requiring an input. -## Widget options +## Widget Options For common options, see [Common widget options](/docs/widgets#common-widget-options). diff --git a/packages/docs/content/docs/widget-image.mdx b/packages/docs/content/docs/widget-image.mdx index c73241ee..73238dd9 100644 --- a/packages/docs/content/docs/widget-image.mdx +++ b/packages/docs/content/docs/widget-image.mdx @@ -10,15 +10,17 @@ weight: 16 The file widget allows editors to upload a file or select an existing one from the media library. The path to the file will be saved to the field as a string. -## Widget options +## Widget Options For common options, see [Common widget options](/docs/widgets#common-widget-options). -| Name | Type | Default | Description | -| ------------- | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -| default | string | `null` | _Optional_. The default value for the field. Accepts a string. | -| media_folder | string | | _Optional_. Specifies the folder path where uploaded files should be saved, relative to the base of the repo | -| public_folder | string | | _Optional_. Specifies the folder path where the files uploaded by the media library will be accessed, relative to the base of the built site | +| Name | Type | Default | Description | +| ------------- | --------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| default | string | `null` | _Optional_. The default value for the field. Accepts a string. | +| media_folder | string | | _Optional_. Specifies the folder path where uploaded files should be saved, relative to the base of the repo | +| public_folder | string | | _Optional_. Specifies the folder path where the files uploaded by the media library will be accessed, relative to the base of the built site | +| media_library | Media Library Options | `{}` | _Optional_. Media library settings to apply when the media library is opened by the current widget. See [Media Library](/docs/configuration-options#media-library) | +| choose_url | boolean | `false` | _Optional_. When set to `false`, the "Insert from URL" button will be hidden | ## Example diff --git a/packages/docs/content/docs/widget-list.mdx b/packages/docs/content/docs/widget-list.mdx index 38eea6a5..825f73ae 100644 --- a/packages/docs/content/docs/widget-list.mdx +++ b/packages/docs/content/docs/widget-list.mdx @@ -10,7 +10,7 @@ weight: 17 The list widget allows you to create a repeatable item in the UI which saves as a list of widget values. You can choose any widget as a child of a list widget—even other lists. -## Widget options +## Widget Options For common options, see [Common widget options](/docs/widgets#common-widget-options). diff --git a/packages/docs/content/docs/widget-map.mdx b/packages/docs/content/docs/widget-map.mdx index 4c7c35c8..0b0303f0 100644 --- a/packages/docs/content/docs/widget-map.mdx +++ b/packages/docs/content/docs/widget-map.mdx @@ -10,7 +10,7 @@ weight: 18 The map widget allows you to edit spatial data using an interactive map. Spatial data for a single piece of geometry saves as a GeoJSON string in WGS84 projection. -## Widget options +## Widget Options For common options, see [Common widget options](/docs/widgets#common-widget-options). diff --git a/packages/docs/content/docs/widget-markdown.mdx b/packages/docs/content/docs/widget-markdown.mdx index 5cf10487..243e58cd 100644 --- a/packages/docs/content/docs/widget-markdown.mdx +++ b/packages/docs/content/docs/widget-markdown.mdx @@ -16,20 +16,13 @@ _Please note:_ If you want to use your markdown editor to fill a markdown file c For common options, see [Common widget options](/docs/widgets#common-widget-options). -| Name | Type | Default | Description | -| ------------- | --------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -| default | string | `''` | _Optional_. The default value for the field. Accepts markdown content | -| media_library | Media Library Options | `{}` | _Optional_. Media library settings to apply when a media library is opened by the current widget. See [Media Library Options](#media-library-options) | -| media_folder | string | | _Optional_. Specifies the folder path where uploaded files should be saved, relative to the base of the repo | -| public_folder | string | | _Optional_. Specifies the folder path where the files uploaded by the media library will be accessed, relative to the base of the built site | - -### Media Library Options - -| Name | Type | Default | Description | -| -------------- | ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -| allow_multiple | boolean | `true` | _Optional_. When set to `false`, prevents multiple selection for any media library extension, but must be supported by the extension in use | -| config | string | `{}` | _Optional_. A configuration object that will be passed directly to the media library being used - available options are determined by the library | -| choose_url | string
\| boolean | `true` | _Optional_. When set to `false`, the "Insert from URL" button will be hidden | +| Name | Type | Default | Description | +| ------------- | --------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| default | string | `''` | _Optional_. The default value for the field. Accepts markdown content | +| media_folder | string | | _Optional_. Specifies the folder path where uploaded files should be saved, relative to the base of the repo | +| public_folder | string | | _Optional_. Specifies the folder path where the files uploaded by the media library will be accessed, relative to the base of the built site | +| media_library | Media Library Options | `{}` | _Optional_. Media library settings to apply when the media library is opened by the current widget. See [Media Library](/docs/configuration-options#media-library) | +| choose_url | boolean | `false` | _Optional_. When set to `false`, the "Insert from URL" button will be hidden | ## Example @@ -161,11 +154,7 @@ CMS.registerShortcode('youtube', { preview: ({ src }) => { return ( -