diff --git a/packages/core/src/components/common/modal/Modal.css b/packages/core/src/components/common/modal/Modal.css index d9858a245..09b38027b 100644 --- a/packages/core/src/components/common/modal/Modal.css +++ b/packages/core/src/components/common/modal/Modal.css @@ -2,7 +2,7 @@ @apply fixed inset-0 overflow-y-auto - z-50 + z-[100] flex min-h-full items-center @@ -15,7 +15,7 @@ @apply fixed inset-0 - z-50; + z-[100]; } .CMS_Modal_content { @@ -28,6 +28,6 @@ align-middle shadow-xl transition-all - z-[51] + z-[101] outline-none; } diff --git a/packages/core/src/constants/configSchema.tsx b/packages/core/src/constants/configSchema.tsx index 8fbab0a7b..1c2677c55 100644 --- a/packages/core/src/constants/configSchema.tsx +++ b/packages/core/src/constants/configSchema.tsx @@ -535,7 +535,7 @@ function getConfigSchema() { frame: { type: 'boolean' }, }, }, - search: { type: 'string' }, + search: { type: 'boolean' }, theme: { type: 'object', properties: { diff --git a/packages/core/src/lib/formatters.ts b/packages/core/src/lib/formatters.ts index 1187303b6..040c54a2d 100644 --- a/packages/core/src/lib/formatters.ts +++ b/packages/core/src/lib/formatters.ts @@ -210,8 +210,6 @@ export function folderFormatter( const collectionFields = getFields(collection, entry.slug) as Field[]; - const slug = slugFormatter(collection, entry.data, slugConfig, collectionFields); - const dateFieldName = selectInferredField(collection, 'date'); const dateField = getField(collectionFields, dateFieldName); const date = parseDateFromEntry(entry, dateFieldName, dateField) || null; @@ -221,7 +219,7 @@ export function folderFormatter( const mediaFolder = compileStringTemplate( folderTemplate, date, - slug, + entry.slug, fields, collectionFields, processSegment, diff --git a/packages/core/src/lib/util/__tests__/media.util.spec.ts b/packages/core/src/lib/util/__tests__/media.util.spec.ts index 110df832f..44197264d 100644 --- a/packages/core/src/lib/util/__tests__/media.util.spec.ts +++ b/packages/core/src/lib/util/__tests__/media.util.spec.ts @@ -26,6 +26,50 @@ describe('media.util', () => { }, }); + it('does not transform path if it does not start with media_folder', () => { + const mockConfig = createMockConfig({ + collections: [ + createMockCollection({ + folder: 'base/folder', + slug: '{{fields.title}}-{{fields.name}}', + fields: [ + { + name: 'title', + widget: 'string', + }, + { + name: 'name', + widget: 'string', + }, + mockBaseImageField, + ], + }), + ], + media_folder: '/path/to/media/folder/{{slug}}', + public_folder: '/path/to/public/folder/{{slug}}', + }); + + const mockCollection = mockConfig.collections[0]; + const mockImageField = (mockConfig.collections[0] as FolderCollection) + .fields[3] as FileOrImageField; + + const mockEntry = createMockEntry({ + path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', + data: { title: 'i am a title', name: 'fish' }, + }); + + expect( + selectMediaFilePublicPath( + mockConfig, + mockCollection, + '/some/other/path/image.png', + mockEntry, + mockImageField, + ), + ).toBe('/some/other/path/image.png'); + }); + describe('top level', () => { it('should default to top level config media_folder', () => { const mockConfig = createMockConfig({ @@ -138,6 +182,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', data: { title: 'i am a title', name: 'fish' }, }); @@ -174,6 +219,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', data: { title: 'i am a title', name: 'fish' }, }); @@ -211,6 +257,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: '', data: {}, newRecord: true, }); @@ -305,6 +352,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', data: { title: 'i am a title', name: 'fish' }, }); @@ -341,6 +389,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', data: { title: 'i am a title', name: 'fish' }, }); @@ -378,6 +427,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: '', data: {}, newRecord: true, }); @@ -420,7 +470,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, undefined, - 'image.png', + 'path/to/media/folder/image.png', undefined, undefined, undefined, @@ -438,7 +488,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, undefined, - 'image.png', + 'path/to/media/folder/image.png', undefined, undefined, undefined, @@ -463,7 +513,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + 'path/to/media/folder/image.png', mockBaseEntry, mockImageField, ), @@ -484,7 +534,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + 'path/to/media/folder/image.png', mockBaseEntry, mockImageField, ), @@ -518,7 +568,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + 'path/to/collection/media/folder/image.png', mockBaseEntry, mockImageField, ), @@ -550,7 +600,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + 'path/to/collection/media/folder/image.png', mockBaseEntry, mockImageField, ), @@ -583,7 +633,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + 'path/to/some/other/media/i-am-a-title/image.png', mockBaseEntry, mockImageField, ), @@ -619,6 +669,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', data: { title: 'i am a title', name: 'fish' }, }); @@ -626,7 +677,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + 'path/to/some/other/media/i-am-a-title-fish/image.png', mockEntry, mockImageField, ), @@ -661,6 +712,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', data: { title: 'i am a title', name: 'fish' }, }); @@ -668,7 +720,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + '/path/to/media/folder/i-am-a-title-fish/image.png', mockEntry, mockImageField, ), @@ -704,6 +756,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', data: { title: 'i am a title', name: 'fish' }, }); @@ -711,7 +764,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + 'path/to/media/folder/i-am-a-title-fish/image.png', mockEntry, mockImageField, ), @@ -748,6 +801,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: '', data: {}, newRecord: true, }); @@ -756,7 +810,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + 'path/to/collection/media/folder/image.png', mockEntry, mockImageField, ), @@ -792,7 +846,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + 'path/to/collection/media/folder/image.png', mockBaseEntry, mockImageField, ), @@ -824,7 +878,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + '/path/to/collection/media/folder/image.png', mockBaseEntry, mockImageField, ), @@ -857,7 +911,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + '/path/to/some/other/media/i-am-a-title/image.png', mockBaseEntry, mockImageField, ), @@ -893,6 +947,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', data: { title: 'i am a title', name: 'fish' }, }); @@ -900,7 +955,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + '/path/to/some/other/media/i-am-a-title-fish/image.png', mockEntry, mockImageField, ), @@ -935,6 +990,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', data: { title: 'i am a title', name: 'fish' }, }); @@ -942,7 +998,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + '/path/to/media/folder/i-am-a-title-fish/image.png', mockEntry, mockImageField, ), @@ -978,6 +1034,7 @@ describe('media.util', () => { const mockEntry = createMockEntry({ path: 'path/to/entry/index.md', + slug: 'i-am-a-title-fish', data: { title: 'i am a title', name: 'fish' }, }); @@ -985,7 +1042,7 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + '/path/to/media/folder/i-am-a-title-fish/image.png', mockEntry, mockImageField, ), @@ -1021,7 +1078,8 @@ describe('media.util', () => { .fields[3] as FileOrImageField; const mockEntry = createMockEntry({ - path: 'path/to/entry/index.md', + path: 'path/to/entry/DRAFT_MEDIA_FILES/index.md', + slug: '', data: {}, newRecord: true, }); @@ -1030,11 +1088,11 @@ describe('media.util', () => { selectMediaFilePublicPath( mockConfig, mockCollection, - 'image.png', + '/path/to/collection/media/folder/DRAFT_MEDIA_FILES/image.png', mockEntry, mockImageField, ), - ).toBe('/path/to/collection/public/folder/image.png'); + ).toBe('/path/to/collection/public/folder/DRAFT_MEDIA_FILES/image.png'); }); }); }); diff --git a/packages/core/src/lib/util/media.util.ts b/packages/core/src/lib/util/media.util.ts index 13d78dfa0..0c5bfa87a 100644 --- a/packages/core/src/lib/util/media.util.ts +++ b/packages/core/src/lib/util/media.util.ts @@ -283,29 +283,43 @@ export function selectMediaFilePublicPath( config.slug, ); + let mediaFolder = folderFormatter( + config.media_folder ?? '', + entryMap, + collection as Collection, + config.media_folder ?? '', + 'media_folder', + config.slug, + ); + let selectedPublicFolder = publicFolder; + let selectedMediaFolder = mediaFolder; const customPublicFolder = hasCustomFolder('public_folder', collection, entryMap?.slug, field); + const customMediaFolder = hasCustomFolder('media_folder', collection, entryMap?.slug, field); if (customPublicFolder) { publicFolder = evaluateFolder('public_folder', config, collection!, entryMap, field); selectedPublicFolder = publicFolder; } + if (customMediaFolder) { + mediaFolder = evaluateFolder('media_folder', config, collection!, entryMap, field); + selectedMediaFolder = mediaFolder; + } + if (currentFolder) { - const customMediaFolder = hasCustomFolder('media_folder', collection, entryMap?.slug, field); const mediaFolder = customMediaFolder ? evaluateFolder('media_folder', config, collection!, entryMap, field) : config['media_folder']; selectedPublicFolder = trim(currentFolder, '/').replace(trim(mediaFolder!, '/'), publicFolder); } - const finalPublicPath = joinUrlPath(selectedPublicFolder, basename(mediaPath)); - if (selectedPublicFolder.startsWith('/')) { - return `/${finalPublicPath}`; + if (mediaPath.startsWith(selectedMediaFolder)) { + return mediaPath.replace(selectedMediaFolder, selectedPublicFolder); } - return finalPublicPath; + return mediaPath; } export function selectMediaFilePath( diff --git a/packages/docs/content/docs/add-to-your-site-cdn.mdx b/packages/docs/content/docs/add-to-your-site-cdn.mdx index 5deaeec51..f2e34953e 100644 --- a/packages/docs/content/docs/add-to-your-site-cdn.mdx +++ b/packages/docs/content/docs/add-to-your-site-cdn.mdx @@ -45,12 +45,12 @@ In this example, we pull the `admin/index.html` file from a public CDN. - + Content Manager - + diff --git a/packages/docs/content/docs/decap-migration-guide.mdx b/packages/docs/content/docs/decap-migration-guide.mdx index 478aec5f8..171f88ef4 100644 --- a/packages/docs/content/docs/decap-migration-guide.mdx +++ b/packages/docs/content/docs/decap-migration-guide.mdx @@ -27,7 +27,7 @@ Decap (_remove_): Netlify (_remove_): ```html - + ``` Static CMS (_add_): @@ -84,7 +84,7 @@ Static CMS bundles its styles separately from the main javascript file, so you w **CDN**: ```html - + ``` **Bundling**: