fix: only add public folder if path matches media folder (#991)
This commit is contained in:
parent
dfb088740c
commit
dd80bfa2d3
@ -2,6 +2,7 @@ backend:
|
|||||||
name: test-repo
|
name: test-repo
|
||||||
site_url: 'https://example.com'
|
site_url: 'https://example.com'
|
||||||
media_folder: assets/uploads
|
media_folder: assets/uploads
|
||||||
|
public_folder: /assets/uploads
|
||||||
media_library:
|
media_library:
|
||||||
folder_support: true
|
folder_support: true
|
||||||
locale: en
|
locale: en
|
||||||
|
@ -172,13 +172,9 @@ export function folderFormatter<EF extends BaseField>(
|
|||||||
'folder' in collection ? collection.folder : '',
|
'folder' in collection ? collection.folder : '',
|
||||||
);
|
);
|
||||||
|
|
||||||
const slug = slugFormatter(collection, entry.data, slugConfig);
|
|
||||||
|
|
||||||
const date = parseDateFromEntry(entry, selectInferredField(collection, 'date')) || null;
|
const date = parseDateFromEntry(entry, selectInferredField(collection, 'date')) || null;
|
||||||
|
|
||||||
const processSegment = getProcessSegment(slugConfig, [defaultFolder, fields?.dirname as string]);
|
const processSegment = getProcessSegment(slugConfig, [defaultFolder, fields?.dirname as string]);
|
||||||
|
|
||||||
const mediaFolder = compileStringTemplate(folderTemplate, date, slug, fields, processSegment);
|
return compileStringTemplate(folderTemplate, date, entry.slug, fields, processSegment);
|
||||||
|
|
||||||
return mediaFolder;
|
|
||||||
}
|
}
|
||||||
|
@ -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<UnknownField>({
|
||||||
|
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', () => {
|
describe('top level', () => {
|
||||||
it('should default to top level config media_folder', () => {
|
it('should default to top level config media_folder', () => {
|
||||||
const mockConfig = createMockConfig({
|
const mockConfig = createMockConfig({
|
||||||
@ -138,6 +182,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: 'i-am-a-title-fish',
|
||||||
data: { title: 'i am a title', name: 'fish' },
|
data: { title: 'i am a title', name: 'fish' },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -174,6 +219,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: 'i-am-a-title-fish',
|
||||||
data: { title: 'i am a title', name: 'fish' },
|
data: { title: 'i am a title', name: 'fish' },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -211,6 +257,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: '',
|
||||||
data: {},
|
data: {},
|
||||||
newRecord: true,
|
newRecord: true,
|
||||||
});
|
});
|
||||||
@ -305,6 +352,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: 'i-am-a-title-fish',
|
||||||
data: { title: 'i am a title', name: 'fish' },
|
data: { title: 'i am a title', name: 'fish' },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -341,6 +389,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: 'i-am-a-title-fish',
|
||||||
data: { title: 'i am a title', name: 'fish' },
|
data: { title: 'i am a title', name: 'fish' },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -378,6 +427,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: '',
|
||||||
data: {},
|
data: {},
|
||||||
newRecord: true,
|
newRecord: true,
|
||||||
});
|
});
|
||||||
@ -420,7 +470,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
undefined,
|
undefined,
|
||||||
'image.png',
|
'path/to/media/folder/image.png',
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
@ -438,7 +488,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
undefined,
|
undefined,
|
||||||
'image.png',
|
'path/to/media/folder/image.png',
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
@ -463,7 +513,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'path/to/media/folder/image.png',
|
||||||
mockBaseEntry,
|
mockBaseEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -484,7 +534,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'path/to/media/folder/image.png',
|
||||||
mockBaseEntry,
|
mockBaseEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -518,7 +568,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'path/to/collection/media/folder/image.png',
|
||||||
mockBaseEntry,
|
mockBaseEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -550,7 +600,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'path/to/collection/media/folder/image.png',
|
||||||
mockBaseEntry,
|
mockBaseEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -583,7 +633,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'path/to/some/other/media/i-am-a-title/image.png',
|
||||||
mockBaseEntry,
|
mockBaseEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -619,6 +669,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: 'i-am-a-title-fish',
|
||||||
data: { title: 'i am a title', name: 'fish' },
|
data: { title: 'i am a title', name: 'fish' },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -626,7 +677,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'path/to/some/other/media/i-am-a-title-fish/image.png',
|
||||||
mockEntry,
|
mockEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -661,6 +712,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: 'i-am-a-title-fish',
|
||||||
data: { title: 'i am a title', name: 'fish' },
|
data: { title: 'i am a title', name: 'fish' },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -668,7 +720,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'/path/to/media/folder/i-am-a-title-fish/image.png',
|
||||||
mockEntry,
|
mockEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -704,6 +756,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: 'i-am-a-title-fish',
|
||||||
data: { title: 'i am a title', name: 'fish' },
|
data: { title: 'i am a title', name: 'fish' },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -711,7 +764,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'path/to/media/folder/i-am-a-title-fish/image.png',
|
||||||
mockEntry,
|
mockEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -748,6 +801,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: '',
|
||||||
data: {},
|
data: {},
|
||||||
newRecord: true,
|
newRecord: true,
|
||||||
});
|
});
|
||||||
@ -756,7 +810,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'path/to/collection/media/folder/image.png',
|
||||||
mockEntry,
|
mockEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -792,7 +846,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'path/to/collection/media/folder/image.png',
|
||||||
mockBaseEntry,
|
mockBaseEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -824,7 +878,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'/path/to/collection/media/folder/image.png',
|
||||||
mockBaseEntry,
|
mockBaseEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -857,7 +911,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'/path/to/some/other/media/i-am-a-title/image.png',
|
||||||
mockBaseEntry,
|
mockBaseEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -893,6 +947,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: 'i-am-a-title-fish',
|
||||||
data: { title: 'i am a title', name: 'fish' },
|
data: { title: 'i am a title', name: 'fish' },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -900,7 +955,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'/path/to/some/other/media/i-am-a-title-fish/image.png',
|
||||||
mockEntry,
|
mockEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -935,6 +990,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: 'i-am-a-title-fish',
|
||||||
data: { title: 'i am a title', name: 'fish' },
|
data: { title: 'i am a title', name: 'fish' },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -942,7 +998,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'/path/to/media/folder/i-am-a-title-fish/image.png',
|
||||||
mockEntry,
|
mockEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -978,6 +1034,7 @@ describe('media.util', () => {
|
|||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/index.md',
|
||||||
|
slug: 'i-am-a-title-fish',
|
||||||
data: { title: 'i am a title', name: 'fish' },
|
data: { title: 'i am a title', name: 'fish' },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -985,7 +1042,7 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'/path/to/media/folder/i-am-a-title-fish/image.png',
|
||||||
mockEntry,
|
mockEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
@ -1021,7 +1078,8 @@ describe('media.util', () => {
|
|||||||
.fields[3] as FileOrImageField;
|
.fields[3] as FileOrImageField;
|
||||||
|
|
||||||
const mockEntry = createMockEntry({
|
const mockEntry = createMockEntry({
|
||||||
path: 'path/to/entry/index.md',
|
path: 'path/to/entry/DRAFT_MEDIA_FILES/index.md',
|
||||||
|
slug: '',
|
||||||
data: {},
|
data: {},
|
||||||
newRecord: true,
|
newRecord: true,
|
||||||
});
|
});
|
||||||
@ -1030,11 +1088,11 @@ describe('media.util', () => {
|
|||||||
selectMediaFilePublicPath(
|
selectMediaFilePublicPath(
|
||||||
mockConfig,
|
mockConfig,
|
||||||
mockCollection,
|
mockCollection,
|
||||||
'image.png',
|
'/path/to/collection/media/folder/DRAFT_MEDIA_FILES/image.png',
|
||||||
mockEntry,
|
mockEntry,
|
||||||
mockImageField,
|
mockImageField,
|
||||||
),
|
),
|
||||||
).toBe('/path/to/collection/public/folder/image.png');
|
).toBe('/path/to/collection/public/folder/DRAFT_MEDIA_FILES/image.png');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -283,29 +283,43 @@ export function selectMediaFilePublicPath<EF extends BaseField>(
|
|||||||
config.slug,
|
config.slug,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mediaFolder = folderFormatter(
|
||||||
|
config.media_folder ?? '',
|
||||||
|
entryMap,
|
||||||
|
collection as Collection,
|
||||||
|
config.media_folder ?? '',
|
||||||
|
'media_folder',
|
||||||
|
config.slug,
|
||||||
|
);
|
||||||
|
|
||||||
let selectedPublicFolder = publicFolder;
|
let selectedPublicFolder = publicFolder;
|
||||||
|
let selectedMediaFolder = mediaFolder;
|
||||||
|
|
||||||
const customPublicFolder = hasCustomFolder('public_folder', collection, entryMap?.slug, field);
|
const customPublicFolder = hasCustomFolder('public_folder', collection, entryMap?.slug, field);
|
||||||
|
const customMediaFolder = hasCustomFolder('media_folder', collection, entryMap?.slug, field);
|
||||||
|
|
||||||
if (customPublicFolder) {
|
if (customPublicFolder) {
|
||||||
publicFolder = evaluateFolder('public_folder', config, collection!, entryMap, field);
|
publicFolder = evaluateFolder('public_folder', config, collection!, entryMap, field);
|
||||||
selectedPublicFolder = publicFolder;
|
selectedPublicFolder = publicFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (customMediaFolder) {
|
||||||
|
mediaFolder = evaluateFolder('media_folder', config, collection!, entryMap, field);
|
||||||
|
selectedMediaFolder = mediaFolder;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentFolder) {
|
if (currentFolder) {
|
||||||
const customMediaFolder = hasCustomFolder('media_folder', collection, entryMap?.slug, field);
|
|
||||||
const mediaFolder = customMediaFolder
|
const mediaFolder = customMediaFolder
|
||||||
? evaluateFolder('media_folder', config, collection!, entryMap, field)
|
? evaluateFolder('media_folder', config, collection!, entryMap, field)
|
||||||
: config['media_folder'];
|
: config['media_folder'];
|
||||||
selectedPublicFolder = trim(currentFolder, '/').replace(trim(mediaFolder!, '/'), publicFolder);
|
selectedPublicFolder = trim(currentFolder, '/').replace(trim(mediaFolder!, '/'), publicFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
const finalPublicPath = joinUrlPath(selectedPublicFolder, basename(mediaPath));
|
if (mediaPath.startsWith(selectedMediaFolder)) {
|
||||||
if (selectedPublicFolder.startsWith('/')) {
|
return mediaPath.replace(selectedMediaFolder, selectedPublicFolder);
|
||||||
return `/${finalPublicPath}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalPublicPath;
|
return mediaPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function selectMediaFilePath(
|
export function selectMediaFilePath(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user